Isn't the problem actually that we read the section entry wrong?
The following (and attached) is the fix I've been using for this.
Oza: it is not a problem as none of the kernel section level translations goes through
vtop.
if you look at
arm_kvtop(struct task_context *tc, ulong kvaddr, physaddr_t *paddr, int verbose)
{
if (!IS_KVADDR(kvaddr))
return FALSE;
if (!vt->vmalloc_start) {
*paddr = VTOP(kvaddr);
return TRUE;
}
if (!IS_VMALLOC_ADDR(kvaddr)) {
*paddr = VTOP(kvaddr);
if (!verbose)
return TRUE;
}
return arm_vtop(kvaddr, (ulong *)vt->kernel_pgd[0], paddr, verbose);
it just uses VTOP for any kernel address other than vmalloc.
and vmalloc addresses are not falling in sections.
may in kernel_init part it might be called, but it is a problem only if 20th bit set; and
while section translation we mask 20th bit.
Regards,
Oza.
________________________________
From: Rabin Vincent <rabin(a)rab.in>
To: "Discussion list for crash utility usage, maintenance and development"
<crash-utility(a)redhat.com>
Cc: Thomas Fänge <thomas.fange(a)sonymobile.com>
Sent: Thursday, 4 October 2012 2:35 PM
Subject: Re: [Crash-utility] using crash for ARM
2012/10/4 Mika Westerberg <mika.westerberg(a)iki.fi>:
The unity-mapped region is mapped using 1MB pages. However, we
actually have
(when using the Linux ARM 2-level translation scheme):
see arch/arm/include/asm/pgtable-2level.h:
#define PMD_SHIFT 21
#define PGDIR_SHIFT 21
#define PTRS_PER_PGD 2048
So we have 2048 entries in a PGD instead of 4096 making a PGD entry an array
of "two pointers".
Anyway as you and Paawan suggested it looks like a bug - we always use the
first entry instead of the second given that bit 20 is set in the virtual
address.
Isn't the problem actually that we read the section entry wrong?
The following (and attached) is the fix I've been using for this.
Rabin
diff --git a/arm.c b/arm.c
index 5930c02..4e7b6dc 100644
--- a/arm.c
+++ b/arm.c
@@ -957,12 +957,14 @@ arm_vtop(ulong vaddr, ulong *pgd, physaddr_t
*paddr, int verbose)
MKSTR((ulong)page_middle)), pmd_pte);
if ((pmd_pte & PMD_TYPE_MASK) == PMD_TYPE_SECT) {
+ ulong sectionbase = pmd_pte & _SECTION_PAGE_MASK;
+
if (verbose) {
fprintf(fp, " PAGE: %s (1MB)\n\n",
mkstring(buf, VADDR_PRLEN, RJUST | LONG_HEX,
- MKSTR(PAGEBASE(pmd_pte))));
+ MKSTR(sectionbase)));
}
- *paddr = PAGEBASE(pmd_pte) + (vaddr & ~_SECTION_PAGE_MASK);
+ *paddr = sectionbase + (vaddr & ~_SECTION_PAGE_MASK);
return TRUE;
}
--
Crash-utility mailing list
Crash-utility(a)redhat.com
https://www.redhat.com/mailman/listinfo/crash-utility