[Crash-utility] [PATCH] [PPC32] Fix vmalloc address translation for BookE

Suzuki K. Poulose suzuki at in.ibm.com
Mon Jan 16 05:15:02 UTC 2012


This patch fixes the vmalloc address translation for BookE.This
patch is based on the PPC44x definitions and may not work fine for
other systems.

crash> mod
mod: cannot access vmalloc'd module memory
crash>


After the patch :

crash> mod
 MODULE   NAME        SIZE  OBJECT FILE
d1018fd8  mbcache     6023  (not loaded)  [CONFIG_KALLSYMS]
d1077190  jbd        58360  (not loaded)  [CONFIG_KALLSYMS]
d107ca98  llc         4525  (not loaded)  [CONFIG_KALLSYMS]
d1130de4  ext3      203186  (not loaded)  [CONFIG_KALLSYMS]
d114bbac  squashfs   26129  (not loaded)  [CONFIG_KALLSYMS]


On ppc44x, the virtual-address is split as below :

Bits   |0      10|11      19|20         31|
	-----------------------------------
       |   PGD   |    PMD   | PAGE_OFFSET  |
        -----------------------------------

The PAGE_BASE_ADDR is a 64bit value(of type phys_addr_t).

Note : I am not sure how do we distinguish the different values (PGDIR_SHIFT etc)
for different PPC32 systems. Since there are a lot of different platforms
under PPC32, we need some mechanism to dynamically determine the PGDIR, PTE
shift values. One option is to put the information in the VMCOREINFO.

Or we should hard code these values for each platform and
compile a crash for a particular platform.

Thoughts ?

Signed-off-by: Suzuki K. Poulose <suzuki at in.ibm.com>
---

 defs.h |    4 ++--
 ppc.c  |   20 ++++++++++++--------
 2 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/defs.h b/defs.h
index 82d51e5..844f369 100755
--- a/defs.h
+++ b/defs.h
@@ -2603,8 +2603,8 @@ struct load_module {
 #define VTOP(X)            ((unsigned long)(X)-(machdep->kvbase))
 #define IS_VMALLOC_ADDR(X) (vt->vmalloc_start && (ulong)(X) >= vt->vmalloc_start)
 
-#define PGDIR_SHIFT   (22)
-#define PTRS_PER_PTE  (1024)
+#define PGDIR_SHIFT   (21)
+#define PTRS_PER_PTE  (512)
 #define PTRS_PER_PGD  (1024)
 
 #define _PAGE_PRESENT   0x001   /* software: pte contains a translation */
diff --git a/ppc.c b/ppc.c
index 2a10fac..6a1db2a 100755
--- a/ppc.c
+++ b/ppc.c
@@ -381,8 +381,8 @@ ppc_kvtop(struct task_context *tc, ulong kvaddr, physaddr_t *paddr, int verbose)
 	ulong *page_dir;
 	ulong *page_middle;
 	ulong *page_table;
-        ulong pgd_pte;
-        ulong pte;
+	ulong pgd_pte;
+	unsigned long long pte;	/* PTE is 64 bit */
 
 	if (!IS_KVADDR(kvaddr))
 		return FALSE;
@@ -404,9 +404,13 @@ ppc_kvtop(struct task_context *tc, ulong kvaddr, physaddr_t *paddr, int verbose)
 		fprintf(fp, "PAGE DIRECTORY: %lx\n", (ulong)pgd);
 
 	page_dir = pgd + (kvaddr >> PGDIR_SHIFT);
-
-        FILL_PGD(PAGEBASE(pgd), KVADDR, PAGESIZE());
-        pgd_pte = ULONG(machdep->pgd + PAGEOFFSET(page_dir));
+	/*
+	 * The (kvaddr >> PGDIR_SHIFT) may exceed PAGESIZE().
+	 * Use PAGEBASE(page_dir) to read the page containing the
+	 * translation.
+	 */
+        FILL_PGD(PAGEBASE(page_dir), KVADDR, PAGESIZE());
+        pgd_pte = ULONG((unsigned long)machdep->pgd + PAGEOFFSET(page_dir));
 
 	if (verbose)
 		fprintf(fp, "  PGD: %lx => %lx\n", (ulong)page_dir, pgd_pte);
@@ -417,7 +421,7 @@ ppc_kvtop(struct task_context *tc, ulong kvaddr, physaddr_t *paddr, int verbose)
 	page_middle = (ulong *)pgd_pte;
 
 	if (machdep->flags & CPU_BOOKE)
-		page_table = page_middle + (BTOP(kvaddr) & (PTRS_PER_PTE - 1));
+		page_table = (unsigned long long *)page_middle + (BTOP(kvaddr) & (PTRS_PER_PTE - 1));
 	else {
 		page_table = (ulong *)((pgd_pte & (ulong)machdep->pagemask) + machdep->kvbase);
 		page_table += ((ulong)BTOP(kvaddr) & (PTRS_PER_PTE-1));
@@ -428,10 +432,10 @@ ppc_kvtop(struct task_context *tc, ulong kvaddr, physaddr_t *paddr, int verbose)
 			(ulong)page_table);
 
         FILL_PTBL(PAGEBASE(page_table), KVADDR, PAGESIZE());
-        pte = ULONG(machdep->ptbl + PAGEOFFSET(page_table));
+        pte = ULONGLONG((unsigned long)machdep->ptbl + PAGEOFFSET(page_table));
 
 	if (verbose) 
-		fprintf(fp, "  PTE: %lx => %lx\n", (ulong)page_table, pte);
+		fprintf(fp, "  PTE: %lx => %llx\n", (ulong)page_table, pte);
 
 	if (!(pte & _PAGE_PRESENT)) { 
 		if (pte && verbose) {




More information about the Crash-utility mailing list