I have an ARM crash dump where the page tables have been corrupted.
crash segfaults while reading it because of a stack overflow due to recursion
in the page table read core:
readmem: e2efcde0, KVADDR, "module unwind table", 24, (ROE), 8600bc0>
addr: e2efcde0 paddr: 22efcde0 cnt: 24
<readmem: bf006550, KVADDR, "module unwind index table", 8, (ROE),
9ccab28>
<readmem: c0004000, KVADDR, "pgd page", 16384, (FOE), 91c18e8>
addr: c0004000 paddr: 4000 cnt: 4096
addr: c0005000 paddr: 5000 cnt: 4096
addr: c0006000 paddr: 6000 cnt: 4096
addr: c0007000 paddr: 7000 cnt: 4096
<readmem: ed2d3000, KVADDR, "page table", 4096, (FOE), 91c58f0>
<readmem: ed2d3000, KVADDR, "page table", 4096, (FOE), 91c58f0>
<readmem: ed2d3000, KVADDR, "page table", 4096, (FOE), 91c58f0>
<readmem: ed2d3000, KVADDR, "page table", 4096, (FOE), 91c58f0>
<readmem: ed2d3000, KVADDR, "page table", 4096, (FOE), 91c58f0>
<readmem: ed2d3000, KVADDR, "page table", 4096, (FOE), 91c58f0>
etc till segfault
The problem appears to be that the ARM code is attempting to PTOV() the
physical address found in the page table and readmem() it as a KVADDR instead
of just directly reading it as a PHYSADDR.
Patch below.
Rabin
diff --git a/arm.c b/arm.c
index 5eb5649..4ca2fcd 100644
--- a/arm.c
+++ b/arm.c
@@ -979,9 +979,9 @@ arm_vtop(ulong vaddr, ulong *pgd, physaddr_t *paddr, int verbose)
/*
* pte_offset_map(pmd, vaddr)
*/
- page_table = (ulong *)PTOV(pmd_page_addr(pmd_pte)) + PTE_OFFSET(vaddr);
+ page_table = pmd_page_addr(pmd_pte) + PTE_OFFSET(vaddr);
- FILL_PTBL(PAGEBASE(page_table), KVADDR, PAGESIZE());
+ FILL_PTBL(PAGEBASE(page_table), PHYSADDR, PAGESIZE());
pte = ULONG(machdep->ptbl + PAGEOFFSET(page_table));
if (verbose) {