[Crash-utility] [PATCH v3] arm64/x86_64: show zero pfn information when using vtop

Rongwei Wang rongwei.wang at linux.alibaba.com
Tue May 16 11:40:54 UTC 2023


Now vtop can not show us the page is zero pfn
when PTE or PMD has attached ZERO PAGE. This
patch supports show this information directly
when using vtop, likes:

crash> vtop -c 13674 ffff8917e000
VIRTUAL     PHYSICAL
ffff8917e000  836e71000

PAGE DIRECTORY: ffff000802f8d000
   PGD: ffff000802f8dff8 => 884e29003
   PUD: ffff000844e29ff0 => 884e93003
   PMD: ffff000844e93240 => 840413003
   PTE: ffff000800413bf0 => 160000836e71fc3
  PAGE: 836e71000  (ZERO PAGE)
...

If huge page found:

crash> vtop -c 14538 ffff95800000
VIRTUAL     PHYSICAL
ffff95800000  910c00000

PAGE DIRECTORY: ffff000801fa0000
   PGD: ffff000801fa0ff8 => 884f53003
   PUD: ffff000844f53ff0 => 8426cb003
   PMD: ffff0008026cb560 => 60000910c00fc1
  PAGE: 910c00000  (2MB, ZERO PAGE)
...

That seems be sensible with this patch.

Signed-off-by: Rongwei Wang <rongwei.wang at linux.alibaba.com>
---
 arm64.c  | 24 ++++++++++++++++--------
 defs.h   |  5 +++++
 memory.c | 23 +++++++++++++++++++++++
 x86_64.c |  9 +++++----
 4 files changed, 49 insertions(+), 12 deletions(-)

diff --git a/arm64.c b/arm64.c
index 56fb841..efbdccb 100644
--- a/arm64.c
+++ b/arm64.c
@@ -1787,7 +1787,8 @@ arm64_vtop_2level_64k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose)
 	if ((pgd_val & PMD_TYPE_MASK) == PMD_TYPE_SECT) {
 		ulong sectionbase = (pgd_val & SECTION_PAGE_MASK_512MB) & PHYS_MASK;
 		if (verbose) {
-			fprintf(fp, "  PAGE: %lx  (512MB)\n\n", sectionbase);
+			fprintf(fp, "  PAGE: %lx  (512MB%s)\n\n", sectionbase,
+				IS_ZEROPAGE(sectionbase) ? ", ZERO PAGE" : "");
 			arm64_translate_pte(pgd_val, 0, 0);
 		}
 		*paddr = sectionbase + (vaddr & ~SECTION_PAGE_MASK_512MB);
@@ -1806,7 +1807,8 @@ arm64_vtop_2level_64k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose)
 	if (pte_val & PTE_VALID) {
 		*paddr = (PAGEBASE(pte_val) & PHYS_MASK) + PAGEOFFSET(vaddr);
 		if (verbose) {
-			fprintf(fp, "  PAGE: %lx\n\n", PAGEBASE(*paddr));
+			fprintf(fp, "  PAGE: %lx  %s\n\n", PAGEBASE(*paddr),
+				IS_ZEROPAGE(PAGEBASE(*paddr)) ? "(ZERO PAGE)" : "");
 			arm64_translate_pte(pte_val, 0, 0);
 		}
 	} else {
@@ -1859,7 +1861,8 @@ arm64_vtop_3level_64k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose)
 	if ((pmd_val & PMD_TYPE_MASK) == PMD_TYPE_SECT) {
 		ulong sectionbase = PTE_TO_PHYS(pmd_val) & SECTION_PAGE_MASK_512MB;
 		if (verbose) {
-			fprintf(fp, "  PAGE: %lx  (512MB)\n\n", sectionbase);
+			fprintf(fp, "  PAGE: %lx  (512MB%s)\n\n", sectionbase,
+				IS_ZEROPAGE(sectionbase) ? ", ZERO PAGE" : "");
 			arm64_translate_pte(pmd_val, 0, 0);
 		}
 		*paddr = sectionbase + (vaddr & ~SECTION_PAGE_MASK_512MB);
@@ -1878,7 +1881,8 @@ arm64_vtop_3level_64k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose)
 	if (pte_val & PTE_VALID) {
 		*paddr = PTE_TO_PHYS(pte_val) + PAGEOFFSET(vaddr);
 		if (verbose) {
-			fprintf(fp, "  PAGE: %lx\n\n", PAGEBASE(*paddr));
+			fprintf(fp, "  PAGE: %lx  %s\n\n", PAGEBASE(*paddr),
+				IS_ZEROPAGE(PAGEBASE(*paddr)) ? "(ZERO PAGE)" : "");
 			arm64_translate_pte(pte_val, 0, 0);
 		}
 	} else {
@@ -1940,7 +1944,8 @@ arm64_vtop_3level_4k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose)
 	if ((pmd_val & PMD_TYPE_MASK) == PMD_TYPE_SECT) {
 		ulong sectionbase = (pmd_val & SECTION_PAGE_MASK_2MB) & PHYS_MASK;
 		if (verbose) {
-			fprintf(fp, "  PAGE: %lx  (2MB)\n\n", sectionbase);
+			fprintf(fp, "  PAGE: %lx  (2MB%s)\n\n", sectionbase,
+				IS_ZEROPAGE(sectionbase) ? ", ZERO PAGE" : "");
 			arm64_translate_pte(pmd_val, 0, 0);
 		}
 		*paddr = sectionbase + (vaddr & ~SECTION_PAGE_MASK_2MB);
@@ -1959,7 +1964,8 @@ arm64_vtop_3level_4k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose)
 	if (pte_val & PTE_VALID) {
 		*paddr = (PAGEBASE(pte_val) & PHYS_MASK) + PAGEOFFSET(vaddr);
 		if (verbose) {
-			fprintf(fp, "  PAGE: %lx\n\n", PAGEBASE(*paddr));
+			fprintf(fp, "  PAGE: %lx  %s\n\n", PAGEBASE(*paddr),
+				IS_ZEROPAGE(PAGEBASE(*paddr)) ? "(ZERO PAGE)" : "");
 			arm64_translate_pte(pte_val, 0, 0);
 		}
 	} else {
@@ -2029,7 +2035,8 @@ arm64_vtop_4level_4k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose)
 	if ((pmd_val & PMD_TYPE_MASK) == PMD_TYPE_SECT) {
 		ulong sectionbase = (pmd_val & SECTION_PAGE_MASK_2MB) & PHYS_MASK;
 		if (verbose) {
-			fprintf(fp, "  PAGE: %lx  (2MB)\n\n", sectionbase);
+			fprintf(fp, "  PAGE: %lx  (2MB%s)\n\n", sectionbase,
+				IS_ZEROPAGE(sectionbase) ? ", ZERO PAGE" : "");
 			arm64_translate_pte(pmd_val, 0, 0);
 		}
 		*paddr = sectionbase + (vaddr & ~SECTION_PAGE_MASK_2MB);
@@ -2048,7 +2055,8 @@ arm64_vtop_4level_4k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose)
 	if (pte_val & PTE_VALID) {
 		*paddr = (PAGEBASE(pte_val) & PHYS_MASK) + PAGEOFFSET(vaddr);
 		if (verbose) {
-			fprintf(fp, "  PAGE: %lx\n\n", PAGEBASE(*paddr));
+			fprintf(fp, "  PAGE: %lx  %s\n\n", PAGEBASE(*paddr),
+				IS_ZEROPAGE(PAGEBASE(*paddr)) ? "(ZERO PAGE)" : "");
 			arm64_translate_pte(pte_val, 0, 0);
 		}
 	} else {
diff --git a/defs.h b/defs.h
index 12ad6aa..a6e4ef3 100644
--- a/defs.h
+++ b/defs.h
@@ -2618,6 +2618,8 @@ struct vm_table {                /* kernel VM-related data */
 		char *name;
 	} *pageflags_data;
 	ulong max_mem_section_nr;
+	ulong zero_paddr;
+	ulong huge_zero_paddr;
 };
 
 #define NODES                       (0x1)
@@ -2999,6 +3001,9 @@ struct load_module {
 #define VIRTPAGEBASE(X)  (((ulong)(X)) & (ulong)machdep->pagemask)
 #define PHYSPAGEBASE(X)  (((physaddr_t)(X)) & (physaddr_t)machdep->pagemask)
 
+#define IS_ZEROPAGE(paddr)   ((paddr) == vt->zero_paddr || \
+			      (paddr) == vt->huge_zero_paddr)
+
 /* 
  * Sparse memory stuff
  *  These must follow the definitions in the kernel mmzone.h
diff --git a/memory.c b/memory.c
index 0568f18..d791283 100644
--- a/memory.c
+++ b/memory.c
@@ -1208,6 +1208,27 @@ vm_init(void)
 		machdep->memory_size()));
 	vt->paddr_prlen = strlen(buf);
 
+	vt->zero_paddr = ~0UL;
+	if (kernel_symbol_exists("zero_pfn")) {
+		ulong zero_pfn;
+
+		if (readmem(symbol_value("zero_pfn"), KVADDR,
+			    &zero_pfn, sizeof(zero_pfn),
+			    "read zero_pfn", QUIET|RETURN_ON_ERROR))
+			vt->zero_paddr = zero_pfn << PAGESHIFT();
+	}
+
+	vt->huge_zero_paddr = ~0UL;
+	if (kernel_symbol_exists("huge_zero_pfn")) {
+		ulong huge_zero_pfn;
+
+		if (readmem(symbol_value("huge_zero_pfn"), KVADDR,
+			    &huge_zero_pfn, sizeof(huge_zero_pfn),
+			    "read huge_zero_pfn", QUIET|RETURN_ON_ERROR) &&
+		    huge_zero_pfn != ~0UL)
+			vt->huge_zero_paddr = huge_zero_pfn << PAGESHIFT();
+	}
+
 	if (vt->flags & PERCPU_KMALLOC_V1) 
                 vt->dump_kmem_cache = dump_kmem_cache_percpu_v1;
 	else if (vt->flags & PERCPU_KMALLOC_V2) 
@@ -14063,6 +14084,8 @@ dump_vm_table(int verbose)
 	} else {
 		fprintf(fp, "    node_online_map: (unused)\n");
 	}
+	fprintf(fp, "         zero_paddr: %lx\n", vt->zero_paddr);
+	fprintf(fp, "    huge_zero_paddr: %lx\n", vt->huge_zero_paddr);
 	fprintf(fp, "   nr_vm_stat_items: %d\n", vt->nr_vm_stat_items);
 	fprintf(fp, "      vm_stat_items: %s", (vt->flags & VM_STAT) ?
 		"\n" : "(not used)\n");
diff --git a/x86_64.c b/x86_64.c
index 5019c69..693a08b 100644
--- a/x86_64.c
+++ b/x86_64.c
@@ -2114,8 +2114,9 @@ x86_64_uvtop_level4(struct task_context *tc, ulong uvaddr, physaddr_t *paddr, in
 		goto no_upage;
         if (pmd_pte & _PAGE_PSE) {
 		if (verbose) {
-                        fprintf(fp, "  PAGE: %lx  (2MB)\n\n", 
-				PAGEBASE(pmd_pte) & PHYSICAL_PAGE_MASK);
+			fprintf(fp, "  PAGE: %lx  (2MB%s)\n\n",
+				PAGEBASE(pmd_pte) & PHYSICAL_PAGE_MASK,
+				IS_ZEROPAGE(PAGEBASE(pmd_pte) & PHYSICAL_PAGE_MASK) ? ", ZERO PAGE" : "");
                         x86_64_translate_pte(pmd_pte, 0, 0);
                 }
 
@@ -2143,8 +2144,8 @@ x86_64_uvtop_level4(struct task_context *tc, ulong uvaddr, physaddr_t *paddr, in
 	*paddr = (PAGEBASE(pte) & PHYSICAL_PAGE_MASK) + PAGEOFFSET(uvaddr);
 
 	if (verbose) {
-		fprintf(fp, "  PAGE: %lx\n\n", 
-			PAGEBASE(*paddr) & PHYSICAL_PAGE_MASK);
+		fprintf(fp, "  PAGE: %lx  %s\n\n", PAGEBASE(*paddr) & PHYSICAL_PAGE_MASK,
+			IS_ZEROPAGE(PAGEBASE(*paddr) & PHYSICAL_PAGE_MASK) ? "(ZERO PAGE)" : "");
 		x86_64_translate_pte(pte, 0, 0);
 	}
 
-- 
2.27.0



More information about the Crash-utility mailing list