Skip to contentSkip to conversation

Makedumpfile: Add 5-level paging support

PATCH In review Baoquan He 3 participants 16 messages Mar 2, 2018 – May 7, 2018

Subsystems (2)
lore
Share & tools
lore

Baoquan He

author
#0 lore raw

cover Makedumpfile: Add 5-level paging support

Kernel has 5-level paging support and now can support boot-time switching between 4/5-level paging mode. This patchset is used to add 5-level paging support in makedumpfile.

A kernel fix is posted to export 'pgtable_l5_enabled' to tell if the corrupted kernel is in 5-level paging mode.
https://patchwork.kernel.org/patch/10253399/

Patch 0001 and 0004 were made by Dou Liyang. While it doesn't work on the latest 5-level code. So add patch 0002 to introduce 'pgtable_l5_enabled'. Change and take out the function check_5level_paging() from dou's old patch and add it into patch 0003. Except of these, don't touch other part of dou's patches.

Thanks, dou, for the effort!

Baoquan He (2):
Makedumpfile: Add pgtable_l5_enabled to number_table
Makedumpfile: Add a new function check_5level_paging()

Dou Liyang (2):
arch/x86_64: Cleanup the address translation of the 4-level page
tables
arch/x86_64: Add 5-level paging support

 arch/x86_64.c  | 130 +++++++++++++++++++++++++++++++++++++++++----------------
 makedumpfile.c |   3 ++
 makedumpfile.h |  39 +++++++++++------
 3 files changed, 123 insertions(+), 49 deletions(-)
Signature · 7 lines
2.13.6


_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
author
#1 lore raw

PATCH 1/4 arch/x86_64: Cleanup the address translation of the 4-level page tables

From: Dou Liyang <[email protected]>

Due to the changing of 4-level page tables implementation in kernel, makedumpfile left behind some of the redundant macros. this make the translation not clear and hard to expand the code to support 5-level page tables.

Remove the PML4* and PGDIR_* and unify the macro to get the index of PGD.

---
 arch/x86_64.c  | 59 +++++++++++++++++++++++++++++++++++-----------------------
 makedumpfile.h | 21 +++++++++------------
 2 files changed, 45 insertions(+), 35 deletions(-)
arch/x86_64.c +36 -23
index 1f24415..cbe45c2 100644
@@ -257,7 +257,7 @@ get_versiondep_info_x86_64(void)
 unsigned long long
 __vtop4_x86_64(unsigned long vaddr, unsigned long pagetable)
 {
-	unsigned long page_dir, pml4, pgd_paddr, pgd_pte, pmd_paddr, pmd_pte;
+	unsigned long page_dir, pgd, pud_paddr, pud_pte, pmd_paddr, pmd_pte;
 	unsigned long pte_paddr, pte;
 
 	/*
@@ -269,43 +269,43 @@ __vtop4_x86_64(unsigned long vaddr, unsigned long pagetable)
 		if (page_dir == NOT_PADDR)
 			return NOT_PADDR;
 	}
-	page_dir += pml4_index(vaddr) * sizeof(unsigned long);
-	if (!readmem(PADDR, page_dir, &pml4, sizeof pml4)) {
-		ERRMSG("Can't get pml4 (page_dir:%lx).\n", page_dir);
+	page_dir += pgd_index(vaddr) * sizeof(unsigned long);
+	if (!readmem(PADDR, page_dir, &pgd, sizeof pgd)) {
+		ERRMSG("Can't get pgd (page_dir:%lx).\n", page_dir);
 		return NOT_PADDR;
 	}
 	if (info->vaddr_for_vtop == vaddr)
-		MSG("  PGD : %16lx => %16lx\n", page_dir, pml4);
+		MSG("  PGD : %16lx => %16lx\n", page_dir, pgd);
 
-	if (!(pml4 & _PAGE_PRESENT)) {
-		ERRMSG("Can't get a valid pml4.\n");
+	if (!(pgd & _PAGE_PRESENT)) {
+		ERRMSG("Can't get a valid pgd.\n");
 		return NOT_PADDR;
 	}
 
 	/*
 	 * Get PUD.
 	 */
-	pgd_paddr  = pml4 & ENTRY_MASK;
-	pgd_paddr += pgd_index(vaddr) * sizeof(unsigned long);
-	if (!readmem(PADDR, pgd_paddr, &pgd_pte, sizeof pgd_pte)) {
-		ERRMSG("Can't get pgd_pte (pgd_paddr:%lx).\n", pgd_paddr);
+	pud_paddr  = pgd & ENTRY_MASK;
+	pud_paddr += pud_index(vaddr) * sizeof(unsigned long);
+	if (!readmem(PADDR, pud_paddr, &pud_pte, sizeof pud_pte)) {
+		ERRMSG("Can't get pud_pte (pud_paddr:%lx).\n", pud_paddr);
 		return NOT_PADDR;
 	}
 	if (info->vaddr_for_vtop == vaddr)
-		MSG("  PUD : %16lx => %16lx\n", pgd_paddr, pgd_pte);
+		MSG("  PUD : %16lx => %16lx\n", pud_paddr, pud_pte);
 
-	if (!(pgd_pte & _PAGE_PRESENT)) {
-		ERRMSG("Can't get a valid pgd_pte.\n");
+	if (!(pud_pte & _PAGE_PRESENT)) {
+		ERRMSG("Can't get a valid pud_pte.\n");
 		return NOT_PADDR;
 	}
-	if (pgd_pte & _PAGE_PSE)	/* 1GB pages */
-		return (pgd_pte & ENTRY_MASK & PGDIR_MASK) +
-			(vaddr & ~PGDIR_MASK);
+	if (pud_pte & _PAGE_PSE)	/* 1GB pages */
+		return (pud_pte & ENTRY_MASK & PUD_MASK) +
+			(vaddr & ~PUD_MASK);
 
 	/*
 	 * Get PMD.
 	 */
-	pmd_paddr  = pgd_pte & ENTRY_MASK;
+	pmd_paddr  = pud_pte & ENTRY_MASK;
 	pmd_paddr += pmd_index(vaddr) * sizeof(unsigned long);
 	if (!readmem(PADDR, pmd_paddr, &pmd_pte, sizeof pmd_pte)) {
 		ERRMSG("Can't get pmd_pte (pmd_paddr:%lx).\n", pmd_paddr);
@@ -391,15 +391,22 @@ kvtop_xen_x86_64(unsigned long kvaddr)
 
 	if ((dirp = kvtop_xen_x86_64(SYMBOL(pgd_l4))) == NOT_PADDR)
 		return NOT_PADDR;
-	dirp += pml4_index(kvaddr) * sizeof(unsigned long long);
+
+	/*
+	 * Get PGD.
+	 */
+	dirp += pgd_index(kvaddr) * sizeof(unsigned long long);
 	if (!readmem(PADDR, dirp, &entry, sizeof(entry)))
 		return NOT_PADDR;
 
 	if (!(entry & _PAGE_PRESENT))
 		return NOT_PADDR;
 
+	/*
+	 * Get PUD.
+	 */
 	dirp = entry & ENTRY_MASK;
-	dirp += pgd_index(kvaddr) * sizeof(unsigned long long);
+	dirp += pud_index(kvaddr) * sizeof(unsigned long long);
 	if (!readmem(PADDR, dirp, &entry, sizeof(entry)))
 		return NOT_PADDR;
 
@@ -407,9 +414,12 @@ kvtop_xen_x86_64(unsigned long kvaddr)
 		return NOT_PADDR;
 
 	if (entry & _PAGE_PSE)		/* 1GB pages */
-		return (entry & ENTRY_MASK & PGDIR_MASK) +
-			(kvaddr & ~PGDIR_MASK);
+		return (entry & ENTRY_MASK & PUD_MASK) +
+			(kvaddr & ~PUD_MASK);
 
+	/*
+	 * Get PMD.
+	 */
 	dirp = entry & ENTRY_MASK;
 	dirp += pmd_index(kvaddr) * sizeof(unsigned long long);
 	if (!readmem(PADDR, dirp, &entry, sizeof(entry)))
@@ -422,6 +432,9 @@ kvtop_xen_x86_64(unsigned long kvaddr)
 		return (entry & ENTRY_MASK & PMD_MASK) +
 			(kvaddr & ~PMD_MASK);
 
+	/*
+	 * Get PTE.
+	 */
 	dirp = entry & ENTRY_MASK;
 	dirp += pte_index(kvaddr) * sizeof(unsigned long long);
 	if (!readmem(PADDR, dirp, &entry, sizeof(entry)))
@@ -596,7 +609,7 @@ find_vmemmap_x86_64()
 	 * for max_paddr >> 12 page structures
 	 */
 	high_pfn = max_paddr >> 12;
-	pgd_index = pgd4_index(vaddr_base);
+	pgd_index = pgd_index(vaddr_base);
 	pgd_addr = vaddr_to_paddr(init_level4_pgt); /* address of pgd */
 	pgd_addr += pgd_index * sizeof(unsigned long);
 	page_structs_per_pud = (PTRS_PER_PUD * PTRS_PER_PMD * info->page_size) /
makedumpfile.h +9 -12
index 01eece2..088dfc3 100644
@@ -602,25 +602,22 @@ unsigned long get_kvbase_arm64(void);
 /*
  * 4 Levels paging
  */
-#define PML4_SHIFT		(39)
-#define PTRS_PER_PML4		(512)
-#define PGDIR_SHIFT		(30)
-#define PGDIR_SIZE		(1UL << PGDIR_SHIFT)
-#define PGDIR_MASK		(~(PGDIR_SIZE - 1))
-#define PTRS_PER_PGD		(512)
 #define PGD_SHIFT		(39)
 #define PUD_SHIFT		(30)
 #define PMD_SHIFT		(21)
-#define PMD_SIZE		(1UL << PMD_SHIFT)
-#define PMD_MASK		(~(PMD_SIZE - 1))
+#define PTE_SHIFT		(12)
+
+#define PTRS_PER_PGD		(512)
 #define PTRS_PER_PUD		(512)
 #define PTRS_PER_PMD		(512)
 #define PTRS_PER_PTE		(512)
-#define PTE_SHIFT		(12)
 
-#define pml4_index(address) (((address) >> PML4_SHIFT) & (PTRS_PER_PML4 - 1))
-#define pgd_index(address)  (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
-#define pgd4_index(address) (((address) >> PGD_SHIFT) & (PTRS_PER_PGD - 1))
+#define PUD_SIZE		(1UL << PUD_SHIFT)
+#define PUD_MASK		(~(PUD_SHIFT - 1))
+#define PMD_SIZE		(1UL << PMD_SHIFT)
+#define PMD_MASK		(~(PMD_SIZE - 1))
+
+#define pgd_index(address)  (((address) >> PGD_SHIFT) & (PTRS_PER_PGD - 1))
 #define pud_index(address)  (((address) >> PUD_SHIFT) & (PTRS_PER_PUD - 1))
 #define pmd_index(address)  (((address) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))
 #define pte_index(address)  (((address) >> PTE_SHIFT) & (PTRS_PER_PTE - 1))
Signature · 7 lines
2.13.6


_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
#2 lore raw

RE: [PATCH 1/4] arch/x86_64: Cleanup the address translation of the 4-level page tables

Hi Baoquan,

Sorry for the late reply.

makedumpfile.h unsigned long get_kvbase_arm64(void); · line 616

Quoted 2 lines
makedumpfile.h +2 -0
+#define PUD_SIZE		(1UL << PUD_SHIFT)
+#define PUD_MASK		(~(PUD_SHIFT - 1))
                        Is this (~(PUD_SIZE - 1)) ?

If so, I will correct this.

makedumpfile.h unsigned long get_kvbase_arm64(void); · line 618

Quoted 2 lines
makedumpfile.h +2 -0
+#define PMD_SIZE		(1UL << PMD_SHIFT)
+#define PMD_MASK		(~(PMD_SIZE - 1))

Thanks
Tachibana

Quoted 198 lines

-----Original Message-----
From: kexec [mailto:[email protected]] On Behalf Of Baoquan He
Sent: Friday, March 02, 2018 2:49 PM
To: [email protected]
Cc: [email protected]; [email protected]; Hayashi Masahiko() <[email protected]>; Tachibana Masaki() <[email protected]>
Subject: [PATCH 1/4] arch/x86_64: Cleanup the address translation of the 4-level page tables

From: Dou Liyang <[email protected]>

Due to the changing of 4-level page tables implementation in kernel, makedumpfile left behind some of the redundant macros. this make the translation not clear and hard to expand the code to support 5-level page tables.

Remove the PML4* and PGDIR_* and unify the macro to get the index of PGD.

---
 arch/x86_64.c  | 59 +++++++++++++++++++++++++++++++++++-----------------------
 makedumpfile.h | 21 +++++++++------------
 2 files changed, 45 insertions(+), 35 deletions(-)
arch/x86_64.c +36 -23
index 1f24415..cbe45c2 100644
@@ -257,7 +257,7 @@ get_versiondep_info_x86_64(void)
 unsigned long long
 __vtop4_x86_64(unsigned long vaddr, unsigned long pagetable)
 {
-	unsigned long page_dir, pml4, pgd_paddr, pgd_pte, pmd_paddr, pmd_pte;
+	unsigned long page_dir, pgd, pud_paddr, pud_pte, pmd_paddr, pmd_pte;
 	unsigned long pte_paddr, pte;
 
 	/*
@@ -269,43 +269,43 @@ __vtop4_x86_64(unsigned long vaddr, unsigned long pagetable)
 		if (page_dir == NOT_PADDR)
 			return NOT_PADDR;
 	}
-	page_dir += pml4_index(vaddr) * sizeof(unsigned long);
-	if (!readmem(PADDR, page_dir, &pml4, sizeof pml4)) {
-		ERRMSG("Can't get pml4 (page_dir:%lx).\n", page_dir);
+	page_dir += pgd_index(vaddr) * sizeof(unsigned long);
+	if (!readmem(PADDR, page_dir, &pgd, sizeof pgd)) {
+		ERRMSG("Can't get pgd (page_dir:%lx).\n", page_dir);
 		return NOT_PADDR;
 	}
 	if (info->vaddr_for_vtop == vaddr)
-		MSG("  PGD : %16lx => %16lx\n", page_dir, pml4);
+		MSG("  PGD : %16lx => %16lx\n", page_dir, pgd);
 
-	if (!(pml4 & _PAGE_PRESENT)) {
-		ERRMSG("Can't get a valid pml4.\n");
+	if (!(pgd & _PAGE_PRESENT)) {
+		ERRMSG("Can't get a valid pgd.\n");
 		return NOT_PADDR;
 	}
 
 	/*
 	 * Get PUD.
 	 */
-	pgd_paddr  = pml4 & ENTRY_MASK;
-	pgd_paddr += pgd_index(vaddr) * sizeof(unsigned long);
-	if (!readmem(PADDR, pgd_paddr, &pgd_pte, sizeof pgd_pte)) {
-		ERRMSG("Can't get pgd_pte (pgd_paddr:%lx).\n", pgd_paddr);
+	pud_paddr  = pgd & ENTRY_MASK;
+	pud_paddr += pud_index(vaddr) * sizeof(unsigned long);
+	if (!readmem(PADDR, pud_paddr, &pud_pte, sizeof pud_pte)) {
+		ERRMSG("Can't get pud_pte (pud_paddr:%lx).\n", pud_paddr);
 		return NOT_PADDR;
 	}
 	if (info->vaddr_for_vtop == vaddr)
-		MSG("  PUD : %16lx => %16lx\n", pgd_paddr, pgd_pte);
+		MSG("  PUD : %16lx => %16lx\n", pud_paddr, pud_pte);
 
-	if (!(pgd_pte & _PAGE_PRESENT)) {
-		ERRMSG("Can't get a valid pgd_pte.\n");
+	if (!(pud_pte & _PAGE_PRESENT)) {
+		ERRMSG("Can't get a valid pud_pte.\n");
 		return NOT_PADDR;
 	}
-	if (pgd_pte & _PAGE_PSE)	/* 1GB pages */
-		return (pgd_pte & ENTRY_MASK & PGDIR_MASK) +
-			(vaddr & ~PGDIR_MASK);
+	if (pud_pte & _PAGE_PSE)	/* 1GB pages */
+		return (pud_pte & ENTRY_MASK & PUD_MASK) +
+			(vaddr & ~PUD_MASK);
 
 	/*
 	 * Get PMD.
 	 */
-	pmd_paddr  = pgd_pte & ENTRY_MASK;
+	pmd_paddr  = pud_pte & ENTRY_MASK;
 	pmd_paddr += pmd_index(vaddr) * sizeof(unsigned long);
 	if (!readmem(PADDR, pmd_paddr, &pmd_pte, sizeof pmd_pte)) {
 		ERRMSG("Can't get pmd_pte (pmd_paddr:%lx).\n", pmd_paddr);
@@ -391,15 +391,22 @@ kvtop_xen_x86_64(unsigned long kvaddr)
 
 	if ((dirp = kvtop_xen_x86_64(SYMBOL(pgd_l4))) == NOT_PADDR)
 		return NOT_PADDR;
-	dirp += pml4_index(kvaddr) * sizeof(unsigned long long);
+
+	/*
+	 * Get PGD.
+	 */
+	dirp += pgd_index(kvaddr) * sizeof(unsigned long long);
 	if (!readmem(PADDR, dirp, &entry, sizeof(entry)))
 		return NOT_PADDR;
 
 	if (!(entry & _PAGE_PRESENT))
 		return NOT_PADDR;
 
+	/*
+	 * Get PUD.
+	 */
 	dirp = entry & ENTRY_MASK;
-	dirp += pgd_index(kvaddr) * sizeof(unsigned long long);
+	dirp += pud_index(kvaddr) * sizeof(unsigned long long);
 	if (!readmem(PADDR, dirp, &entry, sizeof(entry)))
 		return NOT_PADDR;
 
@@ -407,9 +414,12 @@ kvtop_xen_x86_64(unsigned long kvaddr)
 		return NOT_PADDR;
 
 	if (entry & _PAGE_PSE)		/* 1GB pages */
-		return (entry & ENTRY_MASK & PGDIR_MASK) +
-			(kvaddr & ~PGDIR_MASK);
+		return (entry & ENTRY_MASK & PUD_MASK) +
+			(kvaddr & ~PUD_MASK);
 
+	/*
+	 * Get PMD.
+	 */
 	dirp = entry & ENTRY_MASK;
 	dirp += pmd_index(kvaddr) * sizeof(unsigned long long);
 	if (!readmem(PADDR, dirp, &entry, sizeof(entry)))
@@ -422,6 +432,9 @@ kvtop_xen_x86_64(unsigned long kvaddr)
 		return (entry & ENTRY_MASK & PMD_MASK) +
 			(kvaddr & ~PMD_MASK);
 
+	/*
+	 * Get PTE.
+	 */
 	dirp = entry & ENTRY_MASK;
 	dirp += pte_index(kvaddr) * sizeof(unsigned long long);
 	if (!readmem(PADDR, dirp, &entry, sizeof(entry)))
@@ -596,7 +609,7 @@ find_vmemmap_x86_64()
 	 * for max_paddr >> 12 page structures
 	 */
 	high_pfn = max_paddr >> 12;
-	pgd_index = pgd4_index(vaddr_base);
+	pgd_index = pgd_index(vaddr_base);
 	pgd_addr = vaddr_to_paddr(init_level4_pgt); /* address of pgd */
 	pgd_addr += pgd_index * sizeof(unsigned long);
 	page_structs_per_pud = (PTRS_PER_PUD * PTRS_PER_PMD * info->page_size) /
makedumpfile.h +9 -13
index 01eece2..088dfc3 100644
@@ -602,25 +602,22 @@ unsigned long get_kvbase_arm64(void);
 /*
  * 4 Levels paging
  */
-#define PML4_SHIFT		(39)
-#define PTRS_PER_PML4		(512)
-#define PGDIR_SHIFT		(30)
-#define PGDIR_SIZE		(1UL << PGDIR_SHIFT)
-#define PGDIR_MASK		(~(PGDIR_SIZE - 1))
-#define PTRS_PER_PGD		(512)
 #define PGD_SHIFT		(39)
 #define PUD_SHIFT		(30)
 #define PMD_SHIFT		(21)
-#define PMD_SIZE		(1UL << PMD_SHIFT)
-#define PMD_MASK		(~(PMD_SIZE - 1))
+#define PTE_SHIFT		(12)
+
+#define PTRS_PER_PGD		(512)
 #define PTRS_PER_PUD		(512)
 #define PTRS_PER_PMD		(512)
 #define PTRS_PER_PTE		(512)
-#define PTE_SHIFT		(12)
 
-#define pml4_index(address) (((address) >> PML4_SHIFT) & (PTRS_PER_PML4 - 1))
-#define pgd_index(address)  (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
-#define pgd4_index(address) (((address) >> PGD_SHIFT) & (PTRS_PER_PGD - 1))
+#define PUD_SIZE		(1UL << PUD_SHIFT)
+#define PUD_MASK		(~(PUD_SHIFT - 1))
+#define PMD_SIZE		(1UL << PMD_SHIFT)
+#define PMD_MASK		(~(PMD_SIZE - 1))
+
+#define pgd_index(address)  (((address) >> PGD_SHIFT) & (PTRS_PER_PGD - 1))
 #define pud_index(address)  (((address) >> PUD_SHIFT) & (PTRS_PER_PUD - 1))
 #define pmd_index(address)  (((address) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))
 #define pte_index(address)  (((address) >> PTE_SHIFT) & (PTRS_PER_PTE - 1))
--

2.13.6

Quoted 4 lines

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#3 lore raw

Re: [PATCH 1/4] arch/x86_64: Cleanup the address translation of the 4-level page tables

Hi Masaki-san,

Quoted 10 lines · Masaki Tachibana

Hi Baoquan,

Sorry for the late reply.

makedumpfile.h unsigned long get_kvbase_arm64(void); · line 616

Quoted 2 lines
makedumpfile.h +2 -0
+#define PUD_SIZE		(1UL << PUD_SHIFT)
+#define PUD_MASK		(~(PUD_SHIFT - 1))
                         Is this (~(PUD_SIZE - 1)) ?

If so, I will correct this.

Oops! my mistake, go ahead!

Thanks,
dou

Quoted 206 lines

makedumpfile.h unsigned long get_kvbase_arm64(void); · line 618

Quoted 2 lines
makedumpfile.h +2 -0
+#define PMD_SIZE		(1UL << PMD_SHIFT)
+#define PMD_MASK		(~(PMD_SIZE - 1))

Thanks
Tachibana

Quoted 198 lines

-----Original Message-----
From: kexec [mailto:[email protected]] On Behalf Of Baoquan He
Sent: Friday, March 02, 2018 2:49 PM
To: [email protected]
Cc: [email protected]; [email protected]; Hayashi Masahiko() <[email protected]>; Tachibana Masaki() <[email protected]>
Subject: [PATCH 1/4] arch/x86_64: Cleanup the address translation of the 4-level page tables

From: Dou Liyang <[email protected]>

Due to the changing of 4-level page tables implementation in kernel, makedumpfile left behind some of the redundant macros. this make the translation not clear and hard to expand the code to support 5-level page tables.

Remove the PML4* and PGDIR_* and unify the macro to get the index of PGD.

---
  arch/x86_64.c  | 59 +++++++++++++++++++++++++++++++++++-----------------------
  makedumpfile.h | 21 +++++++++------------
  2 files changed, 45 insertions(+), 35 deletions(-)
arch/x86_64.c +36 -23
index 1f24415..cbe45c2 100644
@@ -257,7 +257,7 @@ get_versiondep_info_x86_64(void)
  unsigned long long
  __vtop4_x86_64(unsigned long vaddr, unsigned long pagetable)
  {
-	unsigned long page_dir, pml4, pgd_paddr, pgd_pte, pmd_paddr, pmd_pte;
+	unsigned long page_dir, pgd, pud_paddr, pud_pte, pmd_paddr, pmd_pte;
  	unsigned long pte_paddr, pte;
 
  	/*
@@ -269,43 +269,43 @@ __vtop4_x86_64(unsigned long vaddr, unsigned long pagetable)
  		if (page_dir == NOT_PADDR)
  			return NOT_PADDR;
  	}
-	page_dir += pml4_index(vaddr) * sizeof(unsigned long);
-	if (!readmem(PADDR, page_dir, &pml4, sizeof pml4)) {
-		ERRMSG("Can't get pml4 (page_dir:%lx).\n", page_dir);
+	page_dir += pgd_index(vaddr) * sizeof(unsigned long);
+	if (!readmem(PADDR, page_dir, &pgd, sizeof pgd)) {
+		ERRMSG("Can't get pgd (page_dir:%lx).\n", page_dir);
  		return NOT_PADDR;
  	}
  	if (info->vaddr_for_vtop == vaddr)
-		MSG("  PGD : %16lx => %16lx\n", page_dir, pml4);
+		MSG("  PGD : %16lx => %16lx\n", page_dir, pgd);
 
-	if (!(pml4 & _PAGE_PRESENT)) {
-		ERRMSG("Can't get a valid pml4.\n");
+	if (!(pgd & _PAGE_PRESENT)) {
+		ERRMSG("Can't get a valid pgd.\n");
  		return NOT_PADDR;
  	}
 
  	/*
  	 * Get PUD.
  	 */
-	pgd_paddr  = pml4 & ENTRY_MASK;
-	pgd_paddr += pgd_index(vaddr) * sizeof(unsigned long);
-	if (!readmem(PADDR, pgd_paddr, &pgd_pte, sizeof pgd_pte)) {
-		ERRMSG("Can't get pgd_pte (pgd_paddr:%lx).\n", pgd_paddr);
+	pud_paddr  = pgd & ENTRY_MASK;
+	pud_paddr += pud_index(vaddr) * sizeof(unsigned long);
+	if (!readmem(PADDR, pud_paddr, &pud_pte, sizeof pud_pte)) {
+		ERRMSG("Can't get pud_pte (pud_paddr:%lx).\n", pud_paddr);
  		return NOT_PADDR;
  	}
  	if (info->vaddr_for_vtop == vaddr)
-		MSG("  PUD : %16lx => %16lx\n", pgd_paddr, pgd_pte);
+		MSG("  PUD : %16lx => %16lx\n", pud_paddr, pud_pte);
 
-	if (!(pgd_pte & _PAGE_PRESENT)) {
-		ERRMSG("Can't get a valid pgd_pte.\n");
+	if (!(pud_pte & _PAGE_PRESENT)) {
+		ERRMSG("Can't get a valid pud_pte.\n");
  		return NOT_PADDR;
  	}
-	if (pgd_pte & _PAGE_PSE)	/* 1GB pages */
-		return (pgd_pte & ENTRY_MASK & PGDIR_MASK) +
-			(vaddr & ~PGDIR_MASK);
+	if (pud_pte & _PAGE_PSE)	/* 1GB pages */
+		return (pud_pte & ENTRY_MASK & PUD_MASK) +
+			(vaddr & ~PUD_MASK);
 
  	/*
  	 * Get PMD.
  	 */
-	pmd_paddr  = pgd_pte & ENTRY_MASK;
+	pmd_paddr  = pud_pte & ENTRY_MASK;
  	pmd_paddr += pmd_index(vaddr) * sizeof(unsigned long);
  	if (!readmem(PADDR, pmd_paddr, &pmd_pte, sizeof pmd_pte)) {
  		ERRMSG("Can't get pmd_pte (pmd_paddr:%lx).\n", pmd_paddr);
@@ -391,15 +391,22 @@ kvtop_xen_x86_64(unsigned long kvaddr)
 
  	if ((dirp = kvtop_xen_x86_64(SYMBOL(pgd_l4))) == NOT_PADDR)
  		return NOT_PADDR;
-	dirp += pml4_index(kvaddr) * sizeof(unsigned long long);
+
+	/*
+	 * Get PGD.
+	 */
+	dirp += pgd_index(kvaddr) * sizeof(unsigned long long);
  	if (!readmem(PADDR, dirp, &entry, sizeof(entry)))
  		return NOT_PADDR;
 
  	if (!(entry & _PAGE_PRESENT))
  		return NOT_PADDR;
 
+	/*
+	 * Get PUD.
+	 */
  	dirp = entry & ENTRY_MASK;
-	dirp += pgd_index(kvaddr) * sizeof(unsigned long long);
+	dirp += pud_index(kvaddr) * sizeof(unsigned long long);
  	if (!readmem(PADDR, dirp, &entry, sizeof(entry)))
  		return NOT_PADDR;
 
@@ -407,9 +414,12 @@ kvtop_xen_x86_64(unsigned long kvaddr)
  		return NOT_PADDR;
 
  	if (entry & _PAGE_PSE)		/* 1GB pages */
-		return (entry & ENTRY_MASK & PGDIR_MASK) +
-			(kvaddr & ~PGDIR_MASK);
+		return (entry & ENTRY_MASK & PUD_MASK) +
+			(kvaddr & ~PUD_MASK);
 
+	/*
+	 * Get PMD.
+	 */
  	dirp = entry & ENTRY_MASK;
  	dirp += pmd_index(kvaddr) * sizeof(unsigned long long);
  	if (!readmem(PADDR, dirp, &entry, sizeof(entry)))
@@ -422,6 +432,9 @@ kvtop_xen_x86_64(unsigned long kvaddr)
  		return (entry & ENTRY_MASK & PMD_MASK) +
  			(kvaddr & ~PMD_MASK);
 
+	/*
+	 * Get PTE.
+	 */
  	dirp = entry & ENTRY_MASK;
  	dirp += pte_index(kvaddr) * sizeof(unsigned long long);
  	if (!readmem(PADDR, dirp, &entry, sizeof(entry)))
@@ -596,7 +609,7 @@ find_vmemmap_x86_64()
  	 * for max_paddr >> 12 page structures
  	 */
  	high_pfn = max_paddr >> 12;
-	pgd_index = pgd4_index(vaddr_base);
+	pgd_index = pgd_index(vaddr_base);
  	pgd_addr = vaddr_to_paddr(init_level4_pgt); /* address of pgd */
  	pgd_addr += pgd_index * sizeof(unsigned long);
  	page_structs_per_pud = (PTRS_PER_PUD * PTRS_PER_PMD * info->page_size) /
makedumpfile.h +9 -13
index 01eece2..088dfc3 100644
@@ -602,25 +602,22 @@ unsigned long get_kvbase_arm64(void);
  /*
   * 4 Levels paging
   */
-#define PML4_SHIFT		(39)
-#define PTRS_PER_PML4		(512)
-#define PGDIR_SHIFT		(30)
-#define PGDIR_SIZE		(1UL << PGDIR_SHIFT)
-#define PGDIR_MASK		(~(PGDIR_SIZE - 1))
-#define PTRS_PER_PGD		(512)
  #define PGD_SHIFT		(39)
  #define PUD_SHIFT		(30)
  #define PMD_SHIFT		(21)
-#define PMD_SIZE		(1UL << PMD_SHIFT)
-#define PMD_MASK		(~(PMD_SIZE - 1))
+#define PTE_SHIFT		(12)
+
+#define PTRS_PER_PGD		(512)
  #define PTRS_PER_PUD		(512)
  #define PTRS_PER_PMD		(512)
  #define PTRS_PER_PTE		(512)
-#define PTE_SHIFT		(12)
 
-#define pml4_index(address) (((address) >> PML4_SHIFT) & (PTRS_PER_PML4 - 1))
-#define pgd_index(address)  (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
-#define pgd4_index(address) (((address) >> PGD_SHIFT) & (PTRS_PER_PGD - 1))
+#define PUD_SIZE		(1UL << PUD_SHIFT)
+#define PUD_MASK		(~(PUD_SHIFT - 1))
+#define PMD_SIZE		(1UL << PMD_SHIFT)
+#define PMD_MASK		(~(PMD_SIZE - 1))
+
+#define pgd_index(address)  (((address) >> PGD_SHIFT) & (PTRS_PER_PGD - 1))
  #define pud_index(address)  (((address) >> PUD_SHIFT) & (PTRS_PER_PUD - 1))
  #define pmd_index(address)  (((address) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))
  #define pte_index(address)  (((address) >> PTE_SHIFT) & (PTRS_PER_PTE - 1))
--

2.13.6

Quoted 9 lines
Quoted 4 lines

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

author
#4 lore raw

Re: [PATCH 1/4] arch/x86_64: Cleanup the address translation of the 4-level page tables

In reply to Masaki Tachibana
Quoted 9 lines · Masaki Tachibana

Hi Baoquan,

Sorry for the late reply.

makedumpfile.h unsigned long get_kvbase_arm64(void); · line 616

Quoted 2 lines
makedumpfile.h +2 -0
+#define PUD_SIZE		(1UL << PUD_SHIFT)
+#define PUD_MASK		(~(PUD_SHIFT - 1))
                        Is this (~(PUD_SIZE - 1)) ?

If so, I will correct this.

This patch is from Dou, while I think you are right. Please help change it directly.

Quoted 207 lines

makedumpfile.h unsigned long get_kvbase_arm64(void); · line 618

Quoted 3 lines
makedumpfile.h +2 -0
+#define PMD_SIZE		(1UL << PMD_SHIFT)
+#define PMD_MASK		(~(PMD_SIZE - 1))

Thanks
Tachibana

Quoted 198 lines

-----Original Message-----
From: kexec [mailto:[email protected]] On Behalf Of Baoquan He
Sent: Friday, March 02, 2018 2:49 PM
To: [email protected]
Cc: [email protected]; [email protected]; Hayashi Masahiko() <[email protected]>; Tachibana Masaki() <[email protected]>
Subject: [PATCH 1/4] arch/x86_64: Cleanup the address translation of the 4-level page tables

From: Dou Liyang <[email protected]>

Due to the changing of 4-level page tables implementation in kernel, makedumpfile left behind some of the redundant macros. this make the translation not clear and hard to expand the code to support 5-level page tables.

Remove the PML4* and PGDIR_* and unify the macro to get the index of PGD.

---
 arch/x86_64.c  | 59 +++++++++++++++++++++++++++++++++++-----------------------
 makedumpfile.h | 21 +++++++++------------
 2 files changed, 45 insertions(+), 35 deletions(-)
arch/x86_64.c +36 -23
index 1f24415..cbe45c2 100644
@@ -257,7 +257,7 @@ get_versiondep_info_x86_64(void)
 unsigned long long
 __vtop4_x86_64(unsigned long vaddr, unsigned long pagetable)
 {
-	unsigned long page_dir, pml4, pgd_paddr, pgd_pte, pmd_paddr, pmd_pte;
+	unsigned long page_dir, pgd, pud_paddr, pud_pte, pmd_paddr, pmd_pte;
 	unsigned long pte_paddr, pte;
 
 	/*
@@ -269,43 +269,43 @@ __vtop4_x86_64(unsigned long vaddr, unsigned long pagetable)
 		if (page_dir == NOT_PADDR)
 			return NOT_PADDR;
 	}
-	page_dir += pml4_index(vaddr) * sizeof(unsigned long);
-	if (!readmem(PADDR, page_dir, &pml4, sizeof pml4)) {
-		ERRMSG("Can't get pml4 (page_dir:%lx).\n", page_dir);
+	page_dir += pgd_index(vaddr) * sizeof(unsigned long);
+	if (!readmem(PADDR, page_dir, &pgd, sizeof pgd)) {
+		ERRMSG("Can't get pgd (page_dir:%lx).\n", page_dir);
 		return NOT_PADDR;
 	}
 	if (info->vaddr_for_vtop == vaddr)
-		MSG("  PGD : %16lx => %16lx\n", page_dir, pml4);
+		MSG("  PGD : %16lx => %16lx\n", page_dir, pgd);
 
-	if (!(pml4 & _PAGE_PRESENT)) {
-		ERRMSG("Can't get a valid pml4.\n");
+	if (!(pgd & _PAGE_PRESENT)) {
+		ERRMSG("Can't get a valid pgd.\n");
 		return NOT_PADDR;
 	}
 
 	/*
 	 * Get PUD.
 	 */
-	pgd_paddr  = pml4 & ENTRY_MASK;
-	pgd_paddr += pgd_index(vaddr) * sizeof(unsigned long);
-	if (!readmem(PADDR, pgd_paddr, &pgd_pte, sizeof pgd_pte)) {
-		ERRMSG("Can't get pgd_pte (pgd_paddr:%lx).\n", pgd_paddr);
+	pud_paddr  = pgd & ENTRY_MASK;
+	pud_paddr += pud_index(vaddr) * sizeof(unsigned long);
+	if (!readmem(PADDR, pud_paddr, &pud_pte, sizeof pud_pte)) {
+		ERRMSG("Can't get pud_pte (pud_paddr:%lx).\n", pud_paddr);
 		return NOT_PADDR;
 	}
 	if (info->vaddr_for_vtop == vaddr)
-		MSG("  PUD : %16lx => %16lx\n", pgd_paddr, pgd_pte);
+		MSG("  PUD : %16lx => %16lx\n", pud_paddr, pud_pte);
 
-	if (!(pgd_pte & _PAGE_PRESENT)) {
-		ERRMSG("Can't get a valid pgd_pte.\n");
+	if (!(pud_pte & _PAGE_PRESENT)) {
+		ERRMSG("Can't get a valid pud_pte.\n");
 		return NOT_PADDR;
 	}
-	if (pgd_pte & _PAGE_PSE)	/* 1GB pages */
-		return (pgd_pte & ENTRY_MASK & PGDIR_MASK) +
-			(vaddr & ~PGDIR_MASK);
+	if (pud_pte & _PAGE_PSE)	/* 1GB pages */
+		return (pud_pte & ENTRY_MASK & PUD_MASK) +
+			(vaddr & ~PUD_MASK);
 
 	/*
 	 * Get PMD.
 	 */
-	pmd_paddr  = pgd_pte & ENTRY_MASK;
+	pmd_paddr  = pud_pte & ENTRY_MASK;
 	pmd_paddr += pmd_index(vaddr) * sizeof(unsigned long);
 	if (!readmem(PADDR, pmd_paddr, &pmd_pte, sizeof pmd_pte)) {
 		ERRMSG("Can't get pmd_pte (pmd_paddr:%lx).\n", pmd_paddr);
@@ -391,15 +391,22 @@ kvtop_xen_x86_64(unsigned long kvaddr)
 
 	if ((dirp = kvtop_xen_x86_64(SYMBOL(pgd_l4))) == NOT_PADDR)
 		return NOT_PADDR;
-	dirp += pml4_index(kvaddr) * sizeof(unsigned long long);
+
+	/*
+	 * Get PGD.
+	 */
+	dirp += pgd_index(kvaddr) * sizeof(unsigned long long);
 	if (!readmem(PADDR, dirp, &entry, sizeof(entry)))
 		return NOT_PADDR;
 
 	if (!(entry & _PAGE_PRESENT))
 		return NOT_PADDR;
 
+	/*
+	 * Get PUD.
+	 */
 	dirp = entry & ENTRY_MASK;
-	dirp += pgd_index(kvaddr) * sizeof(unsigned long long);
+	dirp += pud_index(kvaddr) * sizeof(unsigned long long);
 	if (!readmem(PADDR, dirp, &entry, sizeof(entry)))
 		return NOT_PADDR;
 
@@ -407,9 +414,12 @@ kvtop_xen_x86_64(unsigned long kvaddr)
 		return NOT_PADDR;
 
 	if (entry & _PAGE_PSE)		/* 1GB pages */
-		return (entry & ENTRY_MASK & PGDIR_MASK) +
-			(kvaddr & ~PGDIR_MASK);
+		return (entry & ENTRY_MASK & PUD_MASK) +
+			(kvaddr & ~PUD_MASK);
 
+	/*
+	 * Get PMD.
+	 */
 	dirp = entry & ENTRY_MASK;
 	dirp += pmd_index(kvaddr) * sizeof(unsigned long long);
 	if (!readmem(PADDR, dirp, &entry, sizeof(entry)))
@@ -422,6 +432,9 @@ kvtop_xen_x86_64(unsigned long kvaddr)
 		return (entry & ENTRY_MASK & PMD_MASK) +
 			(kvaddr & ~PMD_MASK);
 
+	/*
+	 * Get PTE.
+	 */
 	dirp = entry & ENTRY_MASK;
 	dirp += pte_index(kvaddr) * sizeof(unsigned long long);
 	if (!readmem(PADDR, dirp, &entry, sizeof(entry)))
@@ -596,7 +609,7 @@ find_vmemmap_x86_64()
 	 * for max_paddr >> 12 page structures
 	 */
 	high_pfn = max_paddr >> 12;
-	pgd_index = pgd4_index(vaddr_base);
+	pgd_index = pgd_index(vaddr_base);
 	pgd_addr = vaddr_to_paddr(init_level4_pgt); /* address of pgd */
 	pgd_addr += pgd_index * sizeof(unsigned long);
 	page_structs_per_pud = (PTRS_PER_PUD * PTRS_PER_PMD * info->page_size) /
makedumpfile.h +9 -13
index 01eece2..088dfc3 100644
@@ -602,25 +602,22 @@ unsigned long get_kvbase_arm64(void);
 /*
  * 4 Levels paging
  */
-#define PML4_SHIFT		(39)
-#define PTRS_PER_PML4		(512)
-#define PGDIR_SHIFT		(30)
-#define PGDIR_SIZE		(1UL << PGDIR_SHIFT)
-#define PGDIR_MASK		(~(PGDIR_SIZE - 1))
-#define PTRS_PER_PGD		(512)
 #define PGD_SHIFT		(39)
 #define PUD_SHIFT		(30)
 #define PMD_SHIFT		(21)
-#define PMD_SIZE		(1UL << PMD_SHIFT)
-#define PMD_MASK		(~(PMD_SIZE - 1))
+#define PTE_SHIFT		(12)
+
+#define PTRS_PER_PGD		(512)
 #define PTRS_PER_PUD		(512)
 #define PTRS_PER_PMD		(512)
 #define PTRS_PER_PTE		(512)
-#define PTE_SHIFT		(12)
 
-#define pml4_index(address) (((address) >> PML4_SHIFT) & (PTRS_PER_PML4 - 1))
-#define pgd_index(address)  (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
-#define pgd4_index(address) (((address) >> PGD_SHIFT) & (PTRS_PER_PGD - 1))
+#define PUD_SIZE		(1UL << PUD_SHIFT)
+#define PUD_MASK		(~(PUD_SHIFT - 1))
+#define PMD_SIZE		(1UL << PMD_SHIFT)
+#define PMD_MASK		(~(PMD_SIZE - 1))
+
+#define pgd_index(address)  (((address) >> PGD_SHIFT) & (PTRS_PER_PGD - 1))
 #define pud_index(address)  (((address) >> PUD_SHIFT) & (PTRS_PER_PUD - 1))
 #define pmd_index(address)  (((address) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))
 #define pte_index(address)  (((address) >> PTE_SHIFT) & (PTRS_PER_PTE - 1))
--

2.13.6

Quoted 11 lines
Quoted 4 lines

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

author
#5 lore raw

PATCH 2/4 Makedumpfile: Add pgtable_l5_enabled to number_table

In reply to Baoquan He

This is in preparation for later 5-level supporting.

---
 makedumpfile.c | 3 +++
 makedumpfile.h | 1 +
 2 files changed, 4 insertions(+)
makedumpfile.c +3 -0
index ed138d3..c1e893a 100644
@@ -1723,6 +1723,7 @@ get_structure_info(void)
 
 	ENUM_NUMBER_INIT(NR_FREE_PAGES, "NR_FREE_PAGES");
 	ENUM_NUMBER_INIT(N_ONLINE, "N_ONLINE");
+	ENUM_NUMBER_INIT(N_ONLINE, "pgtable_l5_enabled");
 
 	ENUM_NUMBER_INIT(PG_lru, "PG_lru");
 	ENUM_NUMBER_INIT(PG_private, "PG_private");
@@ -2251,6 +2252,7 @@ write_vmcoreinfo_data(void)
 
 	WRITE_NUMBER("NR_FREE_PAGES", NR_FREE_PAGES);
 	WRITE_NUMBER("N_ONLINE", N_ONLINE);
+	WRITE_NUMBER("N_ONLINE", pgtable_l5_enabled);
 
 	WRITE_NUMBER("PG_lru", PG_lru);
 	WRITE_NUMBER("PG_private", PG_private);
@@ -2645,6 +2647,7 @@ read_vmcoreinfo(void)
 
 	READ_NUMBER("NR_FREE_PAGES", NR_FREE_PAGES);
 	READ_NUMBER("N_ONLINE", N_ONLINE);
+	READ_NUMBER("pgtable_l5_enabled", pgtable_l5_enabled);
 
 	READ_NUMBER("PG_lru", PG_lru);
 	READ_NUMBER("PG_private", PG_private);
makedumpfile.h +1 -0
index 088dfc3..a0d1c13 100644
@@ -1856,6 +1856,7 @@ struct array_table {
 struct number_table {
 	long	NR_FREE_PAGES;
 	long	N_ONLINE;
+	long	pgtable_l5_enabled;
 
 	/*
  	* Page flags
Signature · 7 lines
2.13.6


_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
#6 lore raw

RE: [PATCH 2/4] Makedumpfile: Add pgtable_l5_enabled to number_table

Hi Baoquan,

Sorry for the late reply.

makedumpfile.c get_structure_info(void) · line 1726

Quoted 1 line
makedumpfile.c +1 -0
+	ENUM_NUMBER_INIT(N_ONLINE, "pgtable_l5_enabled");

Is this ENUM_NUMBER_INIT(pgtable_l5_enabled, "pgtable_l5_enabled"); ?

makedumpfile.c write_vmcoreinfo_data(void) · line 2255

Quoted 1 line
makedumpfile.c +1 -0
+	WRITE_NUMBER("N_ONLINE", pgtable_l5_enabled);

Is this WRITE_NUMBER("pgtable_l5_enabled", pgtable_l5_enabled); ?

If so, I will correct these.

Thanks
Tachibana

Quoted 60 lines

-----Original Message-----
From: kexec [mailto:[email protected]] On Behalf Of Baoquan He
Sent: Friday, March 02, 2018 2:49 PM
To: [email protected]
Cc: [email protected]; [email protected]; Hayashi Masahiko() <[email protected]>; Baoquan He <[email protected]>; Tachibana Masaki() <[email protected]>
Subject: [PATCH 2/4] Makedumpfile: Add pgtable_l5_enabled to number_table

This is in preparation for later 5-level supporting.

---
 makedumpfile.c | 3 +++
 makedumpfile.h | 1 +
 2 files changed, 4 insertions(+)
makedumpfile.c +3 -0
index ed138d3..c1e893a 100644
@@ -1723,6 +1723,7 @@ get_structure_info(void)
 
 	ENUM_NUMBER_INIT(NR_FREE_PAGES, "NR_FREE_PAGES");
 	ENUM_NUMBER_INIT(N_ONLINE, "N_ONLINE");
+	ENUM_NUMBER_INIT(N_ONLINE, "pgtable_l5_enabled");
 
 	ENUM_NUMBER_INIT(PG_lru, "PG_lru");
 	ENUM_NUMBER_INIT(PG_private, "PG_private");
@@ -2251,6 +2252,7 @@ write_vmcoreinfo_data(void)
 
 	WRITE_NUMBER("NR_FREE_PAGES", NR_FREE_PAGES);
 	WRITE_NUMBER("N_ONLINE", N_ONLINE);
+	WRITE_NUMBER("N_ONLINE", pgtable_l5_enabled);
 
 	WRITE_NUMBER("PG_lru", PG_lru);
 	WRITE_NUMBER("PG_private", PG_private);
@@ -2645,6 +2647,7 @@ read_vmcoreinfo(void)
 
 	READ_NUMBER("NR_FREE_PAGES", NR_FREE_PAGES);
 	READ_NUMBER("N_ONLINE", N_ONLINE);
+	READ_NUMBER("pgtable_l5_enabled", pgtable_l5_enabled);
 
 	READ_NUMBER("PG_lru", PG_lru);
 	READ_NUMBER("PG_private", PG_private);
makedumpfile.h +1 -1
index 088dfc3..a0d1c13 100644
@@ -1856,6 +1856,7 @@ struct array_table {
 struct number_table {
 	long	NR_FREE_PAGES;
 	long	N_ONLINE;
+	long	pgtable_l5_enabled;
 
 	/*
  	* Page flags
--

2.13.6

Quoted 4 lines

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#7 lore raw

Re: [PATCH 2/4] Makedumpfile: Add pgtable_l5_enabled to number_table

Hi Tachibana,

Quoted 4 lines · Masaki Tachibana

Hi Baoquan,

Sorry for the late reply.

Quoted 9 lines

makedumpfile.c get_structure_info(void) · line 1726

Quoted 1 line
makedumpfile.c +1 -0
+	ENUM_NUMBER_INIT(N_ONLINE, "pgtable_l5_enabled");

Is this ENUM_NUMBER_INIT(pgtable_l5_enabled, "pgtable_l5_enabled"); ?

makedumpfile.c write_vmcoreinfo_data(void) · line 2255

Quoted 1 line
makedumpfile.c +1 -0
+	WRITE_NUMBER("N_ONLINE", pgtable_l5_enabled);

Is this WRITE_NUMBER("pgtable_l5_enabled", pgtable_l5_enabled); ?

If so, I will correct these.

Yes, I agree with you.

Thanks,
dou.

Quoted 64 lines

Thanks
Tachibana

Quoted 60 lines

-----Original Message-----
From: kexec [mailto:[email protected]] On Behalf Of Baoquan He
Sent: Friday, March 02, 2018 2:49 PM
To: [email protected]
Cc: [email protected]; [email protected]; Hayashi Masahiko() <[email protected]>; Baoquan He <[email protected]>; Tachibana Masaki() <[email protected]>
Subject: [PATCH 2/4] Makedumpfile: Add pgtable_l5_enabled to number_table

This is in preparation for later 5-level supporting.

---
  makedumpfile.c | 3 +++
  makedumpfile.h | 1 +
  2 files changed, 4 insertions(+)
makedumpfile.c +3 -0
index ed138d3..c1e893a 100644
@@ -1723,6 +1723,7 @@ get_structure_info(void)
 
  	ENUM_NUMBER_INIT(NR_FREE_PAGES, "NR_FREE_PAGES");
  	ENUM_NUMBER_INIT(N_ONLINE, "N_ONLINE");
+	ENUM_NUMBER_INIT(N_ONLINE, "pgtable_l5_enabled");
 
  	ENUM_NUMBER_INIT(PG_lru, "PG_lru");
  	ENUM_NUMBER_INIT(PG_private, "PG_private");
@@ -2251,6 +2252,7 @@ write_vmcoreinfo_data(void)
 
  	WRITE_NUMBER("NR_FREE_PAGES", NR_FREE_PAGES);
  	WRITE_NUMBER("N_ONLINE", N_ONLINE);
+	WRITE_NUMBER("N_ONLINE", pgtable_l5_enabled);
 
  	WRITE_NUMBER("PG_lru", PG_lru);
  	WRITE_NUMBER("PG_private", PG_private);
@@ -2645,6 +2647,7 @@ read_vmcoreinfo(void)
 
  	READ_NUMBER("NR_FREE_PAGES", NR_FREE_PAGES);
  	READ_NUMBER("N_ONLINE", N_ONLINE);
+	READ_NUMBER("pgtable_l5_enabled", pgtable_l5_enabled);
 
  	READ_NUMBER("PG_lru", PG_lru);
  	READ_NUMBER("PG_private", PG_private);
makedumpfile.h +1 -1
index 088dfc3..a0d1c13 100644
@@ -1856,6 +1856,7 @@ struct array_table {
  struct number_table {
  	long	NR_FREE_PAGES;
  	long	N_ONLINE;
+	long	pgtable_l5_enabled;
 
  	/*
   	* Page flags
--

2.13.6

Quoted 9 lines
Quoted 4 lines

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

author
#8 lore raw

PATCH 3/4 Makedumpfile: Add a new function check_5level_paging()

In reply to Baoquan He

Use it to check if the corrupted kernel is in 5-level paging.

---
 arch/x86_64.c | 9 +++++++++
 1 file changed, 9 insertions(+)
arch/x86_64.c +9 -0
index cbe45c2..e88ee0b 100644
@@ -33,6 +33,15 @@ get_xen_p2m_mfn(void)
 	return NOT_FOUND_LONG_VALUE;
 }
 
+static int
+check_5level_paging(void)
+{
+	if (NUMBER(pgtable_l5_enabled) != 0)
+		return TRUE;
+	else
+		return FALSE;
+}
+
 unsigned long
 get_kaslr_offset_x86_64(unsigned long vaddr)
 {
Signature · 7 lines
2.13.6


_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
#9 lore raw

RE: [PATCH 3/4] Makedumpfile: Add a new function check_5level_paging()

Hi Baoquan,

Sorry for the late reply.

arch/x86_64.c get_xen_p2m_mfn(void) · line 39

Quoted 3 lines
arch/x86_64.c +3 -0
+check_5level_paging(void)
+{
+	if (NUMBER(pgtable_l5_enabled) != 0)

Is this if (NUMBER(pgtable_l5_enabled) != NOT_FOUND_NUMBER && NUMBER(pgtable_l5_enabled) != 0) ? If so, I will correct this.

arch/x86_64.c get_xen_p2m_mfn(void) · line 40

Quoted 1 line
arch/x86_64.c +1 -0
+		return TRUE;

Thanks
Tachibana

Quoted 39 lines

-----Original Message-----
From: kexec [mailto:[email protected]] On Behalf Of Baoquan He
Sent: Friday, March 02, 2018 2:49 PM
To: [email protected]
Cc: [email protected]; [email protected]; Hayashi Masahiko() <[email protected]>; Baoquan He <[email protected]>; Tachibana Masaki() <[email protected]>
Subject: [PATCH 3/4] Makedumpfile: Add a new function check_5level_paging()

Use it to check if the corrupted kernel is in 5-level paging.

---
 arch/x86_64.c | 9 +++++++++
 1 file changed, 9 insertions(+)
arch/x86_64.c +9 -1
index cbe45c2..e88ee0b 100644
@@ -33,6 +33,15 @@ get_xen_p2m_mfn(void)
 	return NOT_FOUND_LONG_VALUE;
 }
 
+static int
+check_5level_paging(void)
+{
+	if (NUMBER(pgtable_l5_enabled) != 0)
+		return TRUE;
+	else
+		return FALSE;
+}
+
 unsigned long
 get_kaslr_offset_x86_64(unsigned long vaddr)
 {
--

2.13.6

Quoted 4 lines

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

author
#10 lore raw

Re: [PATCH 3/4] Makedumpfile: Add a new function check_5level_paging()

Quoted 9 lines · Masaki Tachibana

Hi Baoquan,

Sorry for the late reply.

arch/x86_64.c get_xen_p2m_mfn(void) · line 39

Quoted 3 lines
arch/x86_64.c +3 -0
+check_5level_paging(void)
+{
+	if (NUMBER(pgtable_l5_enabled) != 0)

Is this if (NUMBER(pgtable_l5_enabled) != NOT_FOUND_NUMBER && NUMBER(pgtable_l5_enabled) != 0) ? If so, I will correct this.

Yes, you are right. For kernel which includes 5-level code, it export pgtable_l5_enabled as 0 or 1, however for kernel w/o 5-level code, should be NOT_FOUND_NUMBER. Please help correct it.

Thanks
Baoquan

Quoted 40 lines
Quoted 40 lines

-----Original Message-----
From: kexec [mailto:[email protected]] On Behalf Of Baoquan He
Sent: Friday, March 02, 2018 2:49 PM
To: [email protected]
Cc: [email protected]; [email protected]; Hayashi Masahiko() <[email protected]>; Baoquan He <[email protected]>; Tachibana Masaki() <[email protected]>
Subject: [PATCH 3/4] Makedumpfile: Add a new function check_5level_paging()

Use it to check if the corrupted kernel is in 5-level paging.

---
 arch/x86_64.c | 9 +++++++++
 1 file changed, 9 insertions(+)
arch/x86_64.c +9 -1
index cbe45c2..e88ee0b 100644
@@ -33,6 +33,15 @@ get_xen_p2m_mfn(void)
 	return NOT_FOUND_LONG_VALUE;
 }
 
+static int
+check_5level_paging(void)
+{
+	if (NUMBER(pgtable_l5_enabled) != 0)
+		return TRUE;
+	else
+		return FALSE;
+}
+
 unsigned long
 get_kaslr_offset_x86_64(unsigned long vaddr)
 {
--

2.13.6

Quoted 11 lines
Quoted 4 lines

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

author
#11 lore raw

PATCH 4/4 arch/x86_64: Add 5-level paging support

In reply to Baoquan He

From: Dou Liyang <[email protected]>

Now, kernel can use 5-level page tables in x86_64 system.

Add the 5-level paging support for makedumpfile.

---
 arch/x86_64.c  | 76 ++++++++++++++++++++++++++++++++++++++++++----------------
 makedumpfile.h | 17 +++++++++++++
 2 files changed, 72 insertions(+), 21 deletions(-)
arch/x86_64.c +55 -21
index e88ee0b..b242f36 100644
@@ -112,6 +112,8 @@ get_page_offset_x86_64(void)
 
 	if (info->kernel_version < KERNEL_VERSION(2, 6, 27)) {
 		info->page_offset = __PAGE_OFFSET_ORIG;
+	} else if(check_5level_paging()) {
+		info->page_offset = __PAGE_OFFSET_5LEVEL;
 	} else {
 		info->page_offset = __PAGE_OFFSET_2_6_27;
 	}
@@ -243,6 +245,8 @@ get_versiondep_info_x86_64(void)
 		info->max_physmem_bits  = _MAX_PHYSMEM_BITS_ORIG;
 	else if (info->kernel_version < KERNEL_VERSION(2, 6, 31))
 		info->max_physmem_bits  = _MAX_PHYSMEM_BITS_2_6_26;
+	else if(check_5level_paging())
+		info->max_physmem_bits  = _MAX_PHYSMEM_BITS_5LEVEL;
 	else
 		info->max_physmem_bits  = _MAX_PHYSMEM_BITS_2_6_31;
 
@@ -252,6 +256,9 @@ get_versiondep_info_x86_64(void)
 	if (info->kernel_version < KERNEL_VERSION(2, 6, 31)) {
 		info->vmemmap_start = VMEMMAP_START_ORIG;
 		info->vmemmap_end   = VMEMMAP_END_ORIG;
+	} else if(check_5level_paging()) {
+		info->vmemmap_start = VMEMMAP_START_5LEVEL;
+		info->vmemmap_end   = VMEMMAP_END_5LEVEL;
 	} else {
 		info->vmemmap_start = VMEMMAP_START_2_6_31;
 		info->vmemmap_end   = VMEMMAP_END_2_6_31;
@@ -268,6 +275,7 @@ __vtop4_x86_64(unsigned long vaddr, unsigned long pagetable)
 {
 	unsigned long page_dir, pgd, pud_paddr, pud_pte, pmd_paddr, pmd_pte;
 	unsigned long pte_paddr, pte;
+	unsigned long p4d_paddr, p4d_pte;
 
 	/*
 	 * Get PGD.
@@ -278,23 +286,56 @@ __vtop4_x86_64(unsigned long vaddr, unsigned long pagetable)
 		if (page_dir == NOT_PADDR)
 			return NOT_PADDR;
 	}
-	page_dir += pgd_index(vaddr) * sizeof(unsigned long);
-	if (!readmem(PADDR, page_dir, &pgd, sizeof pgd)) {
-		ERRMSG("Can't get pgd (page_dir:%lx).\n", page_dir);
-		return NOT_PADDR;
-	}
-	if (info->vaddr_for_vtop == vaddr)
-		MSG("  PGD : %16lx => %16lx\n", page_dir, pgd);
 
-	if (!(pgd & _PAGE_PRESENT)) {
-		ERRMSG("Can't get a valid pgd.\n");
-		return NOT_PADDR;
+	if (check_5level_paging()) {
+		page_dir += pgd5_index(vaddr) * sizeof(unsigned long);
+		if (!readmem(PADDR, page_dir, &pgd, sizeof pgd)) {
+			ERRMSG("Can't get pgd (page_dir:%lx).\n", page_dir);
+			return NOT_PADDR;
+		}
+		if (info->vaddr_for_vtop == vaddr)
+			MSG("  PGD : %16lx => %16lx\n", page_dir, pgd);
+
+		if (!(pgd & _PAGE_PRESENT)) {
+			ERRMSG("Can't get a valid pgd.\n");
+			return NOT_PADDR;
+		}
+		/*
+		 * Get P4D.
+		 */
+		p4d_paddr  = pgd & ENTRY_MASK;
+		p4d_paddr += p4d_index(vaddr) * sizeof(unsigned long);
+		if (!readmem(PADDR, p4d_paddr, &p4d_pte, sizeof p4d_pte)) {
+			ERRMSG("Can't get p4d_pte (p4d_paddr:%lx).\n", p4d_paddr);
+			return NOT_PADDR;
+		}
+		if (info->vaddr_for_vtop == vaddr)
+			MSG("  P4D : %16lx => %16lx\n", p4d_paddr, p4d_pte);
+
+		if (!(p4d_pte & _PAGE_PRESENT)) {
+			ERRMSG("Can't get a valid p4d_pte.\n");
+			return NOT_PADDR;
+		}
+		pud_paddr  = p4d_pte & ENTRY_MASK;
+	}else {
+		page_dir += pgd_index(vaddr) * sizeof(unsigned long);
+		if (!readmem(PADDR, page_dir, &pgd, sizeof pgd)) {
+			ERRMSG("Can't get pgd (page_dir:%lx).\n", page_dir);
+			return NOT_PADDR;
+		}
+		if (info->vaddr_for_vtop == vaddr)
+			MSG("  PGD : %16lx => %16lx\n", page_dir, pgd);
+
+		if (!(pgd & _PAGE_PRESENT)) {
+			ERRMSG("Can't get a valid pgd.\n");
+			return NOT_PADDR;
+		}
+		pud_paddr  = pgd & ENTRY_MASK;
 	}
 
 	/*
 	 * Get PUD.
 	 */
-	pud_paddr  = pgd & ENTRY_MASK;
 	pud_paddr += pud_index(vaddr) * sizeof(unsigned long);
 	if (!readmem(PADDR, pud_paddr, &pud_pte, sizeof pud_pte)) {
 		ERRMSG("Can't get pud_pte (pud_paddr:%lx).\n", pud_paddr);
@@ -361,12 +402,7 @@ vtop4_x86_64(unsigned long vaddr)
 	else if (SYMBOL(init_top_pgt) != NOT_FOUND_SYMBOL)
 		init_level4_pgt = SYMBOL(init_top_pgt);
 	else {
-		ERRMSG("Can't get the symbol of init_level4_pgt.\n");
-		return NOT_PADDR;
-	}
-
-	if (SYMBOL(level4_kernel_pgt) != NOT_FOUND_SYMBOL) {
-		ERRMSG("Kernel is built with 5-level page tables\n");
+		ERRMSG("Can't get the symbol of init_level4_pgt/init_top_pgt.\n");
 		return NOT_PADDR;
 	}
 
@@ -605,10 +641,6 @@ find_vmemmap_x86_64()
 		return FAILED;
 	}
 
-	if (SYMBOL(level4_kernel_pgt) != NOT_FOUND_SYMBOL) {
-		ERRMSG("kernel is configured for 5-level page tables\n");
-		return FAILED;
-	}
 	pagestructsize = size_table.page;
 	hugepagesize = PTRS_PER_PMD * info->page_size;
 	vaddr_base = info->vmemmap_start;
@@ -630,12 +662,14 @@ find_vmemmap_x86_64()
 	/* outer loop is for pud entries in the pgd */
 	for (pgdindex = 0, pgdp = (unsigned long *)pgd_addr; pgdindex < num_puds;
 								pgdindex++, pgdp++) {
+
 		/* read the pgd one word at a time, into pud_addr */
 		if (!readmem(PADDR, (unsigned long long)pgdp, (void *)&pud_addr,
 								sizeof(unsigned long))) {
 			ERRMSG("Can't get pgd entry for slot %d.\n", pgd_index);
 			return FAILED;
 		}
+
 		/* mask the pgd entry for the address of the pud page */
 		pud_addr &= PMASK;
 		if (pud_addr == 0)
makedumpfile.h +17 -0
index a0d1c13..d26c30b 100644
@@ -581,16 +581,21 @@ unsigned long get_kvbase_arm64(void);
 #ifdef __x86_64__
 #define __PAGE_OFFSET_ORIG	(0xffff810000000000) /* 2.6.26, or former */
 #define __PAGE_OFFSET_2_6_27	(0xffff880000000000) /* 2.6.27, or later  */
+#define __PAGE_OFFSET_5LEVEL	(0xff10000000000000) /* 5-level page table */
 
 #define VMALLOC_START_ORIG	(0xffffc20000000000) /* 2.6.30, or former */
 #define VMALLOC_START_2_6_31	(0xffffc90000000000) /* 2.6.31, or later  */
+#define VMALLOC_START_5LEVEL	(0xffa0000000000000) /* 5-level page table */
 #define VMALLOC_END_ORIG	(0xffffe1ffffffffff) /* 2.6.30, or former */
 #define VMALLOC_END_2_6_31	(0xffffe8ffffffffff) /* 2.6.31, or later  */
+#define VMALLOC_END_5LEVEL	(0xffd1ffffffffffff) /* 5-level page table */
 
 #define VMEMMAP_START_ORIG	(0xffffe20000000000) /* 2.6.30, or former */
 #define VMEMMAP_START_2_6_31	(0xffffea0000000000) /* 2.6.31, or later  */
+#define VMEMMAP_START_5LEVEL	(0xffd4000000000000) /* 5-level page table */
 #define VMEMMAP_END_ORIG	(0xffffe2ffffffffff) /* 2.6.30, or former */
 #define VMEMMAP_END_2_6_31	(0xffffeaffffffffff) /* 2.6.31, or later  */
+#define VMEMMAP_END_5LEVEL	(0xffd5ffffffffffff) /* 5-level page table */
 
 #define __START_KERNEL_map	(0xffffffff80000000)
 #define KVBASE			PAGE_OFFSET
@@ -598,6 +603,7 @@ unsigned long get_kvbase_arm64(void);
 #define _MAX_PHYSMEM_BITS_ORIG		(40)
 #define _MAX_PHYSMEM_BITS_2_6_26	(44)
 #define _MAX_PHYSMEM_BITS_2_6_31	(46)
+#define _MAX_PHYSMEM_BITS_5LEVEL	(52)
 
 /*
  * 4 Levels paging
@@ -617,7 +623,18 @@ unsigned long get_kvbase_arm64(void);
 #define PMD_SIZE		(1UL << PMD_SHIFT)
 #define PMD_MASK		(~(PMD_SIZE - 1))
 
+/*
+ * 5 Levels paging
+ */
+#define PGD_SHIFT_5LEVEL	(48)
+#define P4D_SHIFT		(39)
+
+#define PTRS_PER_PGD_5LEVEL	(512)
+#define PTRS_PER_P4D		(512)
+
+#define pgd5_index(address)  (((address) >> PGD_SHIFT_5LEVEL) & (PTRS_PER_PGD_5LEVEL - 1))
 #define pgd_index(address)  (((address) >> PGD_SHIFT) & (PTRS_PER_PGD - 1))
+#define p4d_index(address)  (((address) >> P4D_SHIFT) & (PTRS_PER_P4D - 1))
 #define pud_index(address)  (((address) >> PUD_SHIFT) & (PTRS_PER_PUD - 1))
 #define pmd_index(address)  (((address) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))
 #define pte_index(address)  (((address) >> PTE_SHIFT) & (PTRS_PER_PTE - 1))
Signature · 7 lines
2.13.6


_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
#12 lore raw

RE: [PATCH 4/4] arch/x86_64: Add 5-level paging support

Hi Baoquan,

Sorry for the late reply.

The patch looks good.

Thanks
Tachibana

Quoted 225 lines

-----Original Message-----
From: kexec [mailto:[email protected]] On Behalf Of Baoquan He
Sent: Friday, March 02, 2018 2:49 PM
To: [email protected]
Cc: [email protected]; [email protected]; Hayashi Masahiko() <[email protected]>; Tachibana Masaki() <[email protected]>
Subject: [PATCH 4/4] arch/x86_64: Add 5-level paging support

From: Dou Liyang <[email protected]>

Now, kernel can use 5-level page tables in x86_64 system.

Add the 5-level paging support for makedumpfile.

---
 arch/x86_64.c  | 76 ++++++++++++++++++++++++++++++++++++++++++----------------
 makedumpfile.h | 17 +++++++++++++
 2 files changed, 72 insertions(+), 21 deletions(-)
arch/x86_64.c +55 -21
index e88ee0b..b242f36 100644
@@ -112,6 +112,8 @@ get_page_offset_x86_64(void)
 
 	if (info->kernel_version < KERNEL_VERSION(2, 6, 27)) {
 		info->page_offset = __PAGE_OFFSET_ORIG;
+	} else if(check_5level_paging()) {
+		info->page_offset = __PAGE_OFFSET_5LEVEL;
 	} else {
 		info->page_offset = __PAGE_OFFSET_2_6_27;
 	}
@@ -243,6 +245,8 @@ get_versiondep_info_x86_64(void)
 		info->max_physmem_bits  = _MAX_PHYSMEM_BITS_ORIG;
 	else if (info->kernel_version < KERNEL_VERSION(2, 6, 31))
 		info->max_physmem_bits  = _MAX_PHYSMEM_BITS_2_6_26;
+	else if(check_5level_paging())
+		info->max_physmem_bits  = _MAX_PHYSMEM_BITS_5LEVEL;
 	else
 		info->max_physmem_bits  = _MAX_PHYSMEM_BITS_2_6_31;
 
@@ -252,6 +256,9 @@ get_versiondep_info_x86_64(void)
 	if (info->kernel_version < KERNEL_VERSION(2, 6, 31)) {
 		info->vmemmap_start = VMEMMAP_START_ORIG;
 		info->vmemmap_end   = VMEMMAP_END_ORIG;
+	} else if(check_5level_paging()) {
+		info->vmemmap_start = VMEMMAP_START_5LEVEL;
+		info->vmemmap_end   = VMEMMAP_END_5LEVEL;
 	} else {
 		info->vmemmap_start = VMEMMAP_START_2_6_31;
 		info->vmemmap_end   = VMEMMAP_END_2_6_31;
@@ -268,6 +275,7 @@ __vtop4_x86_64(unsigned long vaddr, unsigned long pagetable)
 {
 	unsigned long page_dir, pgd, pud_paddr, pud_pte, pmd_paddr, pmd_pte;
 	unsigned long pte_paddr, pte;
+	unsigned long p4d_paddr, p4d_pte;
 
 	/*
 	 * Get PGD.
@@ -278,23 +286,56 @@ __vtop4_x86_64(unsigned long vaddr, unsigned long pagetable)
 		if (page_dir == NOT_PADDR)
 			return NOT_PADDR;
 	}
-	page_dir += pgd_index(vaddr) * sizeof(unsigned long);
-	if (!readmem(PADDR, page_dir, &pgd, sizeof pgd)) {
-		ERRMSG("Can't get pgd (page_dir:%lx).\n", page_dir);
-		return NOT_PADDR;
-	}
-	if (info->vaddr_for_vtop == vaddr)
-		MSG("  PGD : %16lx => %16lx\n", page_dir, pgd);
 
-	if (!(pgd & _PAGE_PRESENT)) {
-		ERRMSG("Can't get a valid pgd.\n");
-		return NOT_PADDR;
+	if (check_5level_paging()) {
+		page_dir += pgd5_index(vaddr) * sizeof(unsigned long);
+		if (!readmem(PADDR, page_dir, &pgd, sizeof pgd)) {
+			ERRMSG("Can't get pgd (page_dir:%lx).\n", page_dir);
+			return NOT_PADDR;
+		}
+		if (info->vaddr_for_vtop == vaddr)
+			MSG("  PGD : %16lx => %16lx\n", page_dir, pgd);
+
+		if (!(pgd & _PAGE_PRESENT)) {
+			ERRMSG("Can't get a valid pgd.\n");
+			return NOT_PADDR;
+		}
+		/*
+		 * Get P4D.
+		 */
+		p4d_paddr  = pgd & ENTRY_MASK;
+		p4d_paddr += p4d_index(vaddr) * sizeof(unsigned long);
+		if (!readmem(PADDR, p4d_paddr, &p4d_pte, sizeof p4d_pte)) {
+			ERRMSG("Can't get p4d_pte (p4d_paddr:%lx).\n", p4d_paddr);
+			return NOT_PADDR;
+		}
+		if (info->vaddr_for_vtop == vaddr)
+			MSG("  P4D : %16lx => %16lx\n", p4d_paddr, p4d_pte);
+
+		if (!(p4d_pte & _PAGE_PRESENT)) {
+			ERRMSG("Can't get a valid p4d_pte.\n");
+			return NOT_PADDR;
+		}
+		pud_paddr  = p4d_pte & ENTRY_MASK;
+	}else {
+		page_dir += pgd_index(vaddr) * sizeof(unsigned long);
+		if (!readmem(PADDR, page_dir, &pgd, sizeof pgd)) {
+			ERRMSG("Can't get pgd (page_dir:%lx).\n", page_dir);
+			return NOT_PADDR;
+		}
+		if (info->vaddr_for_vtop == vaddr)
+			MSG("  PGD : %16lx => %16lx\n", page_dir, pgd);
+
+		if (!(pgd & _PAGE_PRESENT)) {
+			ERRMSG("Can't get a valid pgd.\n");
+			return NOT_PADDR;
+		}
+		pud_paddr  = pgd & ENTRY_MASK;
 	}
 
 	/*
 	 * Get PUD.
 	 */
-	pud_paddr  = pgd & ENTRY_MASK;
 	pud_paddr += pud_index(vaddr) * sizeof(unsigned long);
 	if (!readmem(PADDR, pud_paddr, &pud_pte, sizeof pud_pte)) {
 		ERRMSG("Can't get pud_pte (pud_paddr:%lx).\n", pud_paddr);
@@ -361,12 +402,7 @@ vtop4_x86_64(unsigned long vaddr)
 	else if (SYMBOL(init_top_pgt) != NOT_FOUND_SYMBOL)
 		init_level4_pgt = SYMBOL(init_top_pgt);
 	else {
-		ERRMSG("Can't get the symbol of init_level4_pgt.\n");
-		return NOT_PADDR;
-	}
-
-	if (SYMBOL(level4_kernel_pgt) != NOT_FOUND_SYMBOL) {
-		ERRMSG("Kernel is built with 5-level page tables\n");
+		ERRMSG("Can't get the symbol of init_level4_pgt/init_top_pgt.\n");
 		return NOT_PADDR;
 	}
 
@@ -605,10 +641,6 @@ find_vmemmap_x86_64()
 		return FAILED;
 	}
 
-	if (SYMBOL(level4_kernel_pgt) != NOT_FOUND_SYMBOL) {
-		ERRMSG("kernel is configured for 5-level page tables\n");
-		return FAILED;
-	}
 	pagestructsize = size_table.page;
 	hugepagesize = PTRS_PER_PMD * info->page_size;
 	vaddr_base = info->vmemmap_start;
@@ -630,12 +662,14 @@ find_vmemmap_x86_64()
 	/* outer loop is for pud entries in the pgd */
 	for (pgdindex = 0, pgdp = (unsigned long *)pgd_addr; pgdindex < num_puds;
 								pgdindex++, pgdp++) {
+
 		/* read the pgd one word at a time, into pud_addr */
 		if (!readmem(PADDR, (unsigned long long)pgdp, (void *)&pud_addr,
 								sizeof(unsigned long))) {
 			ERRMSG("Can't get pgd entry for slot %d.\n", pgd_index);
 			return FAILED;
 		}
+
 		/* mask the pgd entry for the address of the pud page */
 		pud_addr &= PMASK;
 		if (pud_addr == 0)
makedumpfile.h +17 -1
index a0d1c13..d26c30b 100644
@@ -581,16 +581,21 @@ unsigned long get_kvbase_arm64(void);
 #ifdef __x86_64__
 #define __PAGE_OFFSET_ORIG	(0xffff810000000000) /* 2.6.26, or former */
 #define __PAGE_OFFSET_2_6_27	(0xffff880000000000) /* 2.6.27, or later  */
+#define __PAGE_OFFSET_5LEVEL	(0xff10000000000000) /* 5-level page table */
 
 #define VMALLOC_START_ORIG	(0xffffc20000000000) /* 2.6.30, or former */
 #define VMALLOC_START_2_6_31	(0xffffc90000000000) /* 2.6.31, or later  */
+#define VMALLOC_START_5LEVEL	(0xffa0000000000000) /* 5-level page table */
 #define VMALLOC_END_ORIG	(0xffffe1ffffffffff) /* 2.6.30, or former */
 #define VMALLOC_END_2_6_31	(0xffffe8ffffffffff) /* 2.6.31, or later  */
+#define VMALLOC_END_5LEVEL	(0xffd1ffffffffffff) /* 5-level page table */
 
 #define VMEMMAP_START_ORIG	(0xffffe20000000000) /* 2.6.30, or former */
 #define VMEMMAP_START_2_6_31	(0xffffea0000000000) /* 2.6.31, or later  */
+#define VMEMMAP_START_5LEVEL	(0xffd4000000000000) /* 5-level page table */
 #define VMEMMAP_END_ORIG	(0xffffe2ffffffffff) /* 2.6.30, or former */
 #define VMEMMAP_END_2_6_31	(0xffffeaffffffffff) /* 2.6.31, or later  */
+#define VMEMMAP_END_5LEVEL	(0xffd5ffffffffffff) /* 5-level page table */
 
 #define __START_KERNEL_map	(0xffffffff80000000)
 #define KVBASE			PAGE_OFFSET
@@ -598,6 +603,7 @@ unsigned long get_kvbase_arm64(void);
 #define _MAX_PHYSMEM_BITS_ORIG		(40)
 #define _MAX_PHYSMEM_BITS_2_6_26	(44)
 #define _MAX_PHYSMEM_BITS_2_6_31	(46)
+#define _MAX_PHYSMEM_BITS_5LEVEL	(52)
 
 /*
  * 4 Levels paging
@@ -617,7 +623,18 @@ unsigned long get_kvbase_arm64(void);
 #define PMD_SIZE		(1UL << PMD_SHIFT)
 #define PMD_MASK		(~(PMD_SIZE - 1))
 
+/*
+ * 5 Levels paging
+ */
+#define PGD_SHIFT_5LEVEL	(48)
+#define P4D_SHIFT		(39)
+
+#define PTRS_PER_PGD_5LEVEL	(512)
+#define PTRS_PER_P4D		(512)
+
+#define pgd5_index(address)  (((address) >> PGD_SHIFT_5LEVEL) & (PTRS_PER_PGD_5LEVEL - 1))
 #define pgd_index(address)  (((address) >> PGD_SHIFT) & (PTRS_PER_PGD - 1))
+#define p4d_index(address)  (((address) >> P4D_SHIFT) & (PTRS_PER_P4D - 1))
 #define pud_index(address)  (((address) >> PUD_SHIFT) & (PTRS_PER_PUD - 1))
 #define pmd_index(address)  (((address) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))
 #define pte_index(address)  (((address) >> PTE_SHIFT) & (PTRS_PER_PTE - 1))
--

2.13.6

Quoted 4 lines

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

author
#13 lore raw
In reply to Baoquan He

Hi Tachibana, Nakayama,

Ping!

Now 5-level suport on x86 64 has been merged into 4.16, do we have plan to merge this patchset? Or defer to a certain phase?

Thanks
Baoquan

Quoted 25 lines · Baoquan He

Kernel has 5-level paging support and now can support boot-time switching between 4/5-level paging mode. This patchset is used to add 5-level paging support in makedumpfile.

A kernel fix is posted to export 'pgtable_l5_enabled' to tell if the corrupted kernel is in 5-level paging mode.
https://patchwork.kernel.org/patch/10253399/

Patch 0001 and 0004 were made by Dou Liyang. While it doesn't work on the latest 5-level code. So add patch 0002 to introduce 'pgtable_l5_enabled'. Change and take out the function check_5level_paging() from dou's old patch and add it into patch 0003. Except of these, don't touch other part of dou's patches.

Thanks, dou, for the effort!

Baoquan He (2):
Makedumpfile: Add pgtable_l5_enabled to number_table
Makedumpfile: Add a new function check_5level_paging()

Dou Liyang (2):
arch/x86_64: Cleanup the address translation of the 4-level page
tables
arch/x86_64: Add 5-level paging support

Quoted 8 lines
 arch/x86_64.c  | 130 +++++++++++++++++++++++++++++++++++++++++----------------
 makedumpfile.c |   3 ++
 makedumpfile.h |  39 +++++++++++------
 3 files changed, 123 insertions(+), 49 deletions(-)
Signature · 1 line
2.13.6

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#14 lore raw

Hi Baoquan,

Sorry for the late reply.
I'll merge the patches into V1.6.4. However, I need time to acknowledge formally. Please wait some weeks.

Thanks
Tachibana

Quoted 12 lines

-----Original Message-----
From: Baoquan He [mailto:[email protected]]
Sent: Thursday, April 12, 2018 11:45 AM
To: Tachibana Masaki() <[email protected]>; Hayashi Masahiko() <[email protected]>; Nakayama Takuya() <[email protected]>
Cc: [email protected]; [email protected]; [email protected]
Subject: Re: [PATCH 0/4] Makedumpfile: Add 5-level paging support

Hi Tachibana, Nakayama,

Ping!

Quoted 40 lines

Now 5-level suport on x86 64 has been merged into 4.16, do we have plan to merge this patchset? Or defer to a certain phase?

Thanks
Baoquan

Quoted 33 lines · Baoquan He

Kernel has 5-level paging support and now can support boot-time switching between 4/5-level paging mode. This patchset is used to add 5-level paging support in makedumpfile.

A kernel fix is posted to export 'pgtable_l5_enabled' to tell if the corrupted kernel is in 5-level paging mode.
https://patchwork.kernel.org/patch/10253399/

Patch 0001 and 0004 were made by Dou Liyang. While it doesn't work on the latest 5-level code. So add patch 0002 to introduce 'pgtable_l5_enabled'. Change and take out the function check_5level_paging() from dou's old patch and add it into patch 0003. Except of these, don't touch other part of dou's patches.

Thanks, dou, for the effort!

Baoquan He (2):
Makedumpfile: Add pgtable_l5_enabled to number_table
Makedumpfile: Add a new function check_5level_paging()

Dou Liyang (2):
arch/x86_64: Cleanup the address translation of the 4-level page
tables
arch/x86_64: Add 5-level paging support

 arch/x86_64.c  | 130 +++++++++++++++++++++++++++++++++++++++++----------------
 makedumpfile.c |   3 ++
 makedumpfile.h |  39 +++++++++++------
 3 files changed, 123 insertions(+), 49 deletions(-)

--
2.13.6

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

author
#15 lore raw
Quoted 4 lines · Masaki Tachibana

Hi Baoquan,

Sorry for the late reply.
I'll merge the patches into V1.6.4.

That's great, thanks.

Quoted 2 lines

However, I need time to acknowledge formally.
Please wait some weeks.

Sure, it's not very urgent.

Thanks
Baoquan

Quoted 45 lines
Quoted 45 lines

-----Original Message-----
From: Baoquan He [mailto:[email protected]]
Sent: Thursday, April 12, 2018 11:45 AM
To: Tachibana Masaki() <[email protected]>; Hayashi Masahiko() <[email protected]>; Nakayama Takuya() <[email protected]>
Cc: [email protected]; [email protected]; [email protected]
Subject: Re: [PATCH 0/4] Makedumpfile: Add 5-level paging support

Hi Tachibana, Nakayama,

Ping!

Now 5-level suport on x86 64 has been merged into 4.16, do we have plan to merge this patchset? Or defer to a certain phase?

Thanks
Baoquan

Quoted 25 lines · Baoquan He

Kernel has 5-level paging support and now can support boot-time switching between 4/5-level paging mode. This patchset is used to add 5-level paging support in makedumpfile.

A kernel fix is posted to export 'pgtable_l5_enabled' to tell if the corrupted kernel is in 5-level paging mode.
https://patchwork.kernel.org/patch/10253399/

Patch 0001 and 0004 were made by Dou Liyang. While it doesn't work on the latest 5-level code. So add patch 0002 to introduce 'pgtable_l5_enabled'. Change and take out the function check_5level_paging() from dou's old patch and add it into patch 0003. Except of these, don't touch other part of dou's patches.

Thanks, dou, for the effort!

Baoquan He (2):
Makedumpfile: Add pgtable_l5_enabled to number_table
Makedumpfile: Add a new function check_5level_paging()

Dou Liyang (2):
arch/x86_64: Cleanup the address translation of the 4-level page
tables
arch/x86_64: Add 5-level paging support

Quoted 10 lines
Quoted 8 lines
Quoted 8 lines
 arch/x86_64.c  | 130 +++++++++++++++++++++++++++++++++++++++++----------------
 makedumpfile.c |   3 ++
 makedumpfile.h |  39 +++++++++++------
 3 files changed, 123 insertions(+), 49 deletions(-)

--
2.13.6

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec