[PATCH RFC] arm64: show zero pfn information when using vtop

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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)

      PTE        PHYSICAL   FLAGS
160000836e71fc3  836e71000  (VALID|USER|RDONLY|SHARED|AF|NG|PXN|UXN|SPECIAL)

      VMA           START       END     FLAGS FILE
ffff000844f51860 ffff8917c000 ffff8957d000 100073

      PAGE         PHYSICAL      MAPPING       INDEX CNT FLAGS
fffffe001fbb9c40  836e71000                0        0  1 2ffffc000001000 reserved

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)

     PTE        PHYSICAL   FLAGS
60000910c00fc1  910c00000  (VALID|USER|RDONLY|SHARED|AF|NG|PXN|UXN)

      VMA           START       END     FLAGS FILE
ffff0000caa711e0 ffff956a9000 ffff95aaa000 100073

      PAGE         PHYSICAL      MAPPING       INDEX CNT FLAGS
fffffe0023230000  910c00000                0        0  1 6ffffc000010000 head

That seems be sensible with this patch.

Signed-off-by: Rongwei Wang <rongwei.wang@xxxxxxxxxxxxxxxxx>
---
 arm64.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++------
 defs.h  |  5 ++++
 2 files changed, 88 insertions(+), 9 deletions(-)

diff --git a/arm64.c b/arm64.c
index 56fb841..264572d 100644
--- a/arm64.c
+++ b/arm64.c
@@ -419,7 +419,25 @@ arm64_init(int when)
 		/* use machdep parameters */
 		arm64_calc_phys_offset();
 		arm64_calc_physvirt_offset();
-	
+
+		if (kernel_symbol_exists("zero_pfn")) {
+				ulong zero_pfn = 0;
+
+				if (readmem(symbol_value("zero_pfn"), KVADDR,
+					      &zero_pfn, sizeof(zero_pfn),
+					      "read zero_pfn", QUIET|RETURN_ON_ERROR))
+					machdep->zero_pfn = zero_pfn;
+		}
+
+		if (kernel_symbol_exists("huge_zero_pfn")) {
+				ulong huge_zero_pfn = 0;
+
+				if (readmem(symbol_value("huge_zero_pfn"), KVADDR,
+					      &huge_zero_pfn, sizeof(huge_zero_pfn),
+					      "read huge_zero_pfn", QUIET|RETURN_ON_ERROR))
+					machdep->huge_zero_pfn = huge_zero_pfn;
+		}
+
 		if (CRASHDEBUG(1)) {
 			if (machdep->flags & NEW_VMEMMAP)
 				fprintf(fp, "kimage_voffset: %lx\n", 
@@ -1787,7 +1805,14 @@ 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);
+			if (kernel_symbol_exists("huge_zero_pfn")) {
+				if (sectionbase == (HUGE_ZEROPFN() << PAGESHIFT()))
+					fprintf(fp, "  PAGE: %lx  (512MB, ZERO PAGE)\n\n",
+						HUGE_ZEROPFN() << PAGESHIFT());
+				else
+					fprintf(fp, "  PAGE: %lx  (512MB)\n\n", sectionbase);
+			} else
+				fprintf(fp, "  PAGE: %lx  (512MB)\n\n", sectionbase);
 			arm64_translate_pte(pgd_val, 0, 0);
 		}
 		*paddr = sectionbase + (vaddr & ~SECTION_PAGE_MASK_512MB);
@@ -1806,7 +1831,14 @@ 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));
+			if (kernel_symbol_exists("zero_pfn")) {
+				if (PAGEBASE(*paddr) == (ZEROPFN() << PAGESHIFT()))
+					fprintf(fp, "  PAGE: %lx  (ZERO PAGE)\n\n",
+						ZEROPFN() << PAGESHIFT());
+				else
+					fprintf(fp, "  PAGE: %lx\n\n", PAGEBASE(*paddr));
+			} else
+				fprintf(fp, "  PAGE: %lx\n\n", PAGEBASE(*paddr));
 			arm64_translate_pte(pte_val, 0, 0);
 		}
 	} else {
@@ -1859,7 +1891,14 @@ 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);
+			if (kernel_symbol_exists("huge_zero_pfn")) {
+				if (sectionbase == (HUGE_ZEROPFN() << PAGESHIFT()))
+					fprintf(fp, "  PAGE: %lx  (512MB, ZERO PAGE)\n\n",
+						HUGE_ZEROPFN() << PAGESHIFT());
+				else
+					fprintf(fp, "  PAGE: %lx  (512MB)\n\n", sectionbase);
+			} else
+				fprintf(fp, "  PAGE: %lx  (512MB)\n\n", sectionbase);
 			arm64_translate_pte(pmd_val, 0, 0);
 		}
 		*paddr = sectionbase + (vaddr & ~SECTION_PAGE_MASK_512MB);
@@ -1878,7 +1917,14 @@ 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));
+			if (kernel_symbol_exists("zero_pfn")) {
+				if (PAGEBASE(*paddr) == (ZEROPFN() << PAGESHIFT()))
+					fprintf(fp, "  PAGE: %lx  (ZERO PAGE)\n\n",
+						ZEROPFN() << PAGESHIFT());
+				else
+					fprintf(fp, "  PAGE: %lx\n\n", PAGEBASE(*paddr));
+			} else
+				fprintf(fp, "  PAGE: %lx\n\n", PAGEBASE(*paddr));
 			arm64_translate_pte(pte_val, 0, 0);
 		}
 	} else {
@@ -1940,7 +1986,14 @@ 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);
+			if (kernel_symbol_exists("huge_zero_pfn")) {
+				if (sectionbase == (HUGE_ZEROPFN() << PAGESHIFT()))
+					fprintf(fp, "  PAGE: %lx  (2MB, ZERO PAGE)\n\n",
+						HUGE_ZEROPFN() << PAGESHIFT());
+				else
+					fprintf(fp, "  PAGE: %lx  (2MB)\n\n", sectionbase);
+			} else
+				fprintf(fp, "  PAGE: %lx  (2MB)\n\n", sectionbase);
 			arm64_translate_pte(pmd_val, 0, 0);
 		}
 		*paddr = sectionbase + (vaddr & ~SECTION_PAGE_MASK_2MB);
@@ -1959,7 +2012,14 @@ 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));
+			if (kernel_symbol_exists("zero_pfn")) {
+				if (PAGEBASE(*paddr) == (ZEROPFN() << PAGESHIFT()))
+					fprintf(fp, "  PAGE: %lx  (ZERO PAGE)\n\n",
+						ZEROPFN() << PAGESHIFT());
+				else
+					fprintf(fp, "  PAGE: %lx\n\n", PAGEBASE(*paddr));
+			} else
+				fprintf(fp, "  PAGE: %lx\n\n", PAGEBASE(*paddr));
 			arm64_translate_pte(pte_val, 0, 0);
 		}
 	} else {
@@ -2029,7 +2089,14 @@ 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);
+			if (kernel_symbol_exists("huge_zero_pfn")) {
+				if (sectionbase == (HUGE_ZEROPFN() << PAGESHIFT()))
+					fprintf(fp, "  PAGE: %lx  (2MB, ZERO PAGE)\n\n",
+						HUGE_ZEROPFN() << PAGESHIFT());
+				else
+					fprintf(fp, "  PAGE: %lx  (2MB)\n\n", sectionbase);
+			} else
+				fprintf(fp, "  PAGE: %lx  (2MB)\n\n", sectionbase);
 			arm64_translate_pte(pmd_val, 0, 0);
 		}
 		*paddr = sectionbase + (vaddr & ~SECTION_PAGE_MASK_2MB);
@@ -2048,7 +2115,14 @@ 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));
+			if (kernel_symbol_exists("zero_pfn")) {
+				if (PAGEBASE(*paddr) == (ZEROPFN() << PAGESHIFT()))
+					fprintf(fp, "  PAGE: %lx  (ZERO PAGE)\n\n",
+						ZEROPFN() << PAGESHIFT());
+				else
+					fprintf(fp, "  PAGE: %lx\n\n", PAGEBASE(*paddr));
+			} else
+				fprintf(fp, "  PAGE: %lx\n\n", PAGEBASE(*paddr));
 			arm64_translate_pte(pte_val, 0, 0);
 		}
 	} else {
diff --git a/defs.h b/defs.h
index 12ad6aa..4ed2d0a 100644
--- a/defs.h
+++ b/defs.h
@@ -1071,6 +1071,8 @@ struct machdep_table {
         void (*show_interrupts)(int, ulong *);
 	int (*is_page_ptr)(ulong, physaddr_t *);
 	int (*get_cpu_reg)(int, int, const char *, int, void *);
+	ulong zero_pfn;
+	ulong huge_zero_pfn;
 };
 
 /*
@@ -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 ZEROPFN()    (machdep->zero_pfn)
+#define HUGE_ZEROPFN()   (machdep->huge_zero_pfn)
+
 /* 
  * Sparse memory stuff
  *  These must follow the definitions in the kernel mmzone.h
-- 
2.27.0

--
Crash-utility mailing list
Crash-utility@xxxxxxxxxx
https://listman.redhat.com/mailman/listinfo/crash-utility
Contribution Guidelines: https://github.com/crash-utility/crash/wiki




[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux