On Tue, May 31, 2016 at 03:30:44PM -0400, Dave Anderson wrote: > > This patch looks good -- if it wasn't layered on top of the KASLR patch, > I would check it into github. This patch is almost independent from KASLR support, except that adding new flags, VM_L4_4K and NEW_VMEMMAP, is conflicting. When you merge it, please make a change. -Takahiro AKASHI > Thanks, > Dave > > > ----- Original Message ----- > > From: AKASHI Takahiro <akax.hiro@xxxxxxxxx> > > > > Signed-off-by: AKASHI Takahiro <takahiro.akashi@xxxxxxxxxx> > > --- > > arm64.c | 120 > > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- > > defs.h | 25 +++++++++++++- > > 2 files changed, 137 insertions(+), 8 deletions(-) > > > > diff --git a/arm64.c b/arm64.c > > index c16ea67..b6bfbf3 100644 > > --- a/arm64.c > > +++ b/arm64.c > > @@ -36,6 +36,7 @@ static int arm64_uvtop(struct task_context *, ulong, > > physaddr_t *, int); > > static int arm64_vtop_2level_64k(ulong, ulong, physaddr_t *, int); > > static int arm64_vtop_3level_64k(ulong, ulong, physaddr_t *, int); > > static int arm64_vtop_3level_4k(ulong, ulong, physaddr_t *, int); > > +static int arm64_vtop_4level_4k(ulong, ulong, physaddr_t *, int); > > static ulong arm64_get_task_pgd(ulong); > > static void arm64_irq_stack_init(void); > > static void arm64_stackframe_init(void); > > @@ -233,18 +234,26 @@ arm64_init(int when) > > switch (machdep->pagesize) > > { > > case 4096: > > - machdep->flags |= VM_L3_4K; > > machdep->ptrs_per_pgd = PTRS_PER_PGD_L3_4K; > > if ((machdep->pgd = > > (char *)malloc(PTRS_PER_PGD_L3_4K * 8)) == NULL) > > error(FATAL, "cannot malloc pgd space."); > > + if (machdep->machspec->VA_BITS > PGDIR_SHIFT_L4_4K) { > > + machdep->flags |= VM_L4_4K; > > + if ((machdep->pud = > > + (char *)malloc(PTRS_PER_PUD_L4_4K * 8)) > > + == NULL) > > + error(FATAL, "cannot malloc pud space."); > > + } else { > > + machdep->flags |= VM_L3_4K; > > + machdep->pud = NULL; /* not used */ > > + } > > if ((machdep->pmd = > > (char *)malloc(PTRS_PER_PMD_L3_4K * 8)) == NULL) > > error(FATAL, "cannot malloc pmd space."); > > if ((machdep->ptbl = > > (char *)malloc(PTRS_PER_PTE_L3_4K * 8)) == NULL) > > error(FATAL, "cannot malloc ptbl space."); > > - machdep->pud = NULL; /* not used */ > > break; > > > > case 65536: > > @@ -282,8 +291,8 @@ arm64_init(int when) > > error(FATAL, "cannot determine page size\n"); > > } > > > > - machdep->last_pud_read = 0; /* not used */ > > machdep->last_pgd_read = 0; > > + machdep->last_pud_read = 0; > > machdep->last_pmd_read = 0; > > machdep->last_ptbl_read = 0; > > machdep->clear_machdep_cache = arm64_clear_machdep_cache; > > @@ -462,6 +471,8 @@ arm64_dump_machdep_table(ulong arg) > > fprintf(fp, "%sVM_L3_64K", others++ ? "|" : ""); > > if (machdep->flags & VM_L3_4K) > > fprintf(fp, "%sVM_L3_4K", others++ ? "|" : ""); > > + if (machdep->flags & VM_L4_4K) > > + fprintf(fp, "%sVM_L4_4K", others++ ? "|" : ""); > > if (machdep->flags & VMEMMAP) > > fprintf(fp, "%sVMEMMAP", others++ ? "|" : ""); > > if (machdep->flags & KDUMP_ENABLED) > > @@ -494,11 +505,15 @@ arm64_dump_machdep_table(ulong arg) > > fprintf(fp, " uvtop: arm64_uvtop()->%s()\n", > > machdep->flags & VM_L3_4K ? > > "arm64_vtop_3level_4k" : > > + machdep->flags & VM_L4_4K ? > > + "arm64_vtop_4level_4k" : > > machdep->flags & VM_L3_64K ? > > "arm64_vtop_3level_64k" : "arm64_vtop_2level_64k"); > > fprintf(fp, " kvtop: arm64_kvtop()->%s()\n", > > machdep->flags & VM_L3_4K ? > > "arm64_vtop_3level_4k" : > > + machdep->flags & VM_L4_4K ? > > + "arm64_vtop_4level_4k" : > > machdep->flags & VM_L3_64K ? > > "arm64_vtop_3level_64k" : "arm64_vtop_2level_64k"); > > fprintf(fp, " get_task_pgd: arm64_get_task_pgd()\n"); > > @@ -531,8 +546,13 @@ arm64_dump_machdep_table(ulong arg) > > fprintf(fp, " xendump_panic_task: (n/a)\n"); > > fprintf(fp, " get_xendump_regs: (n/a)\n"); > > fprintf(fp, " line_number_hooks: (not used)\n"); > > - fprintf(fp, " last_pud_read: (not used)\n"); > > fprintf(fp, " last_pgd_read: %lx\n", machdep->last_pgd_read); > > + fprintf(fp, " last_pud_read: "); > > + if ((PAGESIZE() == 65536) || > > + ((PAGESIZE() == 4096) && !(machdep->flags & VM_L4_4K))) > > + fprintf(fp, "(not used)\n"); > > + else > > + fprintf(fp, "%lx\n", machdep->last_pud_read); > > fprintf(fp, " last_pmd_read: "); > > if (PAGESIZE() == 65536) > > fprintf(fp, "(not used)\n"); > > @@ -541,6 +561,7 @@ arm64_dump_machdep_table(ulong arg) > > fprintf(fp, " last_ptbl_read: %lx\n", machdep->last_ptbl_read); > > fprintf(fp, " clear_machdep_cache: arm64_clear_machdep_cache()\n"); > > fprintf(fp, " pgd: %lx\n", (ulong)machdep->pgd); > > + fprintf(fp, " pud: %lx\n", (ulong)machdep->pud); > > fprintf(fp, " pmd: %lx\n", (ulong)machdep->pmd); > > fprintf(fp, " ptbl: %lx\n", (ulong)machdep->ptbl); > > fprintf(fp, " ptrs_per_pgd: %d\n", machdep->ptrs_per_pgd); > > @@ -843,7 +864,7 @@ arm64_kvtop(struct task_context *tc, ulong kvaddr, > > physaddr_t *paddr, int verbos > > kernel_pgd = vt->kernel_pgd[0]; > > *paddr = 0; > > > > - switch (machdep->flags & (VM_L2_64K|VM_L3_64K|VM_L3_4K)) > > + switch (machdep->flags & (VM_L2_64K|VM_L3_64K|VM_L3_4K|VM_L4_4K)) > > { > > case VM_L2_64K: > > return arm64_vtop_2level_64k(kernel_pgd, kvaddr, paddr, verbose); > > @@ -851,6 +872,8 @@ arm64_kvtop(struct task_context *tc, ulong kvaddr, > > physaddr_t *paddr, int verbos > > return arm64_vtop_3level_64k(kernel_pgd, kvaddr, paddr, verbose); > > case VM_L3_4K: > > return arm64_vtop_3level_4k(kernel_pgd, kvaddr, paddr, verbose); > > + case VM_L4_4K: > > + return arm64_vtop_4level_4k(kernel_pgd, kvaddr, paddr, verbose); > > default: > > return FALSE; > > } > > @@ -866,7 +889,7 @@ arm64_uvtop(struct task_context *tc, ulong uvaddr, > > physaddr_t *paddr, int verbos > > > > *paddr = 0; > > > > - switch (machdep->flags & (VM_L2_64K|VM_L3_64K|VM_L3_4K)) > > + switch (machdep->flags & (VM_L2_64K|VM_L3_64K|VM_L3_4K|VM_L4_4K)) > > { > > case VM_L2_64K: > > return arm64_vtop_2level_64k(user_pgd, uvaddr, paddr, verbose); > > @@ -874,6 +897,8 @@ arm64_uvtop(struct task_context *tc, ulong uvaddr, > > physaddr_t *paddr, int verbos > > return arm64_vtop_3level_64k(user_pgd, uvaddr, paddr, verbose); > > case VM_L3_4K: > > return arm64_vtop_3level_4k(user_pgd, uvaddr, paddr, verbose); > > + case VM_L4_4K: > > + return arm64_vtop_4level_4k(user_pgd, uvaddr, paddr, verbose); > > default: > > return FALSE; > > } > > @@ -1092,6 +1117,85 @@ no_page: > > return FALSE; > > } > > > > +static int > > +arm64_vtop_4level_4k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose) > > +{ > > + ulong *pgd_base, *pgd_ptr, pgd_val; > > + ulong *pud_base, *pud_ptr, pud_val; > > + ulong *pmd_base, *pmd_ptr, pmd_val; > > + ulong *pte_base, *pte_ptr, pte_val; > > + > > + if (verbose) > > + fprintf(fp, "PAGE DIRECTORY: %lx\n", pgd); > > + > > + pgd_base = (ulong *)pgd; > > + FILL_PGD(pgd_base, KVADDR, PTRS_PER_PGD_L4_4K * sizeof(ulong)); > > + pgd_ptr = pgd_base + (((vaddr) >> PGDIR_SHIFT_L4_4K) & (PTRS_PER_PGD_L4_4K > > - 1)); > > + pgd_val = ULONG(machdep->pgd + PGDIR_OFFSET(pgd_ptr)); > > + if (verbose) > > + fprintf(fp, " PGD: %lx => %lx\n", (ulong)pgd_ptr, > > pgd_val); > > + if (!pgd_val) > > + goto no_page; > > + > > + pud_base = (ulong *)PTOV(pgd_val & PHYS_MASK & PGDIR_MASK); > > + > > + FILL_PUD(pud_base, KVADDR, PTRS_PER_PUD_L4_4K * sizeof(ulong)); > > + pud_ptr = pud_base + (((vaddr) >> PUD_SHIFT_L4_4K) & (PTRS_PER_PUD_L4_4K - > > 1)); > > + pud_val = ULONG(machdep->pud + PAGEOFFSET(pud_ptr)); > > + if (verbose) > > + fprintf(fp, " PUD: %lx => %lx\n", (ulong)pud_ptr, > > pud_val); > > + if (!pud_val) > > + goto no_page; > > + > > + pmd_base = (ulong *)PTOV(pud_val & PHYS_MASK & (s32)machdep->pagemask); > > + FILL_PMD(pmd_base, KVADDR, PTRS_PER_PMD_L4_4K * sizeof(ulong)); > > + pmd_ptr = pmd_base + (((vaddr) >> PMD_SHIFT_L4_4K) & (PTRS_PER_PMD_L4_4K - > > 1)); > > + pmd_val = ULONG(machdep->pmd + PAGEOFFSET(pmd_ptr)); > > + if (verbose) > > + fprintf(fp, " PMD: %lx => %lx\n", (ulong)pmd_ptr, > > pmd_val); > > + if (!pmd_val) > > + goto no_page; > > + > > + 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); > > + arm64_translate_pte(pmd_val, 0, 0); > > + } > > + *paddr = sectionbase + (vaddr & ~SECTION_PAGE_MASK_2MB); > > + return TRUE; > > + } > > + > > + pte_base = (ulong *)PTOV(pmd_val & PHYS_MASK & (s32)machdep->pagemask); > > + FILL_PTBL(pte_base, KVADDR, PTRS_PER_PTE_L4_4K * sizeof(ulong)); > > + pte_ptr = pte_base + (((vaddr) >> machdep->pageshift) & (PTRS_PER_PTE_L4_4K > > - 1)); > > + pte_val = ULONG(machdep->ptbl + PAGEOFFSET(pte_ptr)); > > + if (verbose) > > + fprintf(fp, " PTE: %lx => %lx\n", (ulong)pte_ptr, > > pte_val); > > + if (!pte_val) > > + goto no_page; > > + > > + if (pte_val & PTE_VALID) { > > + *paddr = (PAGEBASE(pte_val) & PHYS_MASK) + PAGEOFFSET(vaddr); > > + if (verbose) { > > + fprintf(fp, " PAGE: %lx\n\n", PAGEBASE(*paddr)); > > + arm64_translate_pte(pte_val, 0, 0); > > + } > > + } else { > > + if (IS_UVADDR(vaddr, NULL)) > > + *paddr = pte_val; > > + if (verbose) { > > + fprintf(fp, "\n"); > > + arm64_translate_pte(pte_val, 0, 0); > > + } > > + goto no_page; > > + } > > + > > + return TRUE; > > +no_page: > > + return FALSE; > > +} > > + > > static ulong > > arm64_get_task_pgd(ulong task) > > { > > @@ -2556,7 +2660,7 @@ arm64_calc_virtual_memory_ranges(void) > > > > STRUCT_SIZE_INIT(page, "page"); > > > > - switch (machdep->flags & (VM_L2_64K|VM_L3_64K|VM_L3_4K)) > > + switch (machdep->flags & (VM_L2_64K|VM_L3_64K|VM_L3_4K|VM_L4_4K)) > > { > > case VM_L2_64K: > > case VM_L3_64K: > > @@ -2564,6 +2668,8 @@ arm64_calc_virtual_memory_ranges(void) > > break; > > case VM_L3_4K: > > PUD_SIZE = PGDIR_SIZE_L3_4K; > > + case VM_L4_4K: > > + PUD_SIZE = PUD_SIZE_L4_4K; > > break; > > } > > > > diff --git a/defs.h b/defs.h > > index 406a865..17a4fbd 100644 > > --- a/defs.h > > +++ b/defs.h > > @@ -1054,7 +1054,7 @@ extern struct machdep_table *machdep; > > readmem((ulonglong)((ulong)(PGD)), TYPE, machdep->pgd, > > \ > > SIZE, "pgd page", FAULT_ON_ERROR); > > \ > > machdep->last_pgd_read = (ulong)(PGD); > > \ > > - } > > + } > > > > #define FILL_PUD(PUD, TYPE, SIZE) \ > > if (!IS_LAST_PUD_READ(PUD)) { > > \ > > @@ -2884,6 +2884,28 @@ typedef signed int s32; > > #define PMD_MASK_L3_4K (~(PMD_SIZE_L3_4K-1)) > > > > /* > > + * 4-levels / 4K pages > > + * 48-bit VA > > + */ > > +#define PTRS_PER_PGD_L4_4K ((1UL) << (48 - 39)) > > +#define PTRS_PER_PUD_L4_4K (512) > > +#define PTRS_PER_PMD_L4_4K (512) > > +#define PTRS_PER_PTE_L4_4K (512) > > +#define PGDIR_SHIFT_L4_4K (39) > > +#define PGDIR_SIZE_L4_4K ((1UL) << PGDIR_SHIFT_L4_4K) > > +#define PGDIR_MASK_L4_4K (~(PGDIR_SIZE_L4_4K-1)) > > +#define PUD_SHIFT_L4_4K (30) > > +#define PUD_SIZE_L4_4K ((1UL) << PUD_SHIFT_L4_4K) > > +#define PUD_MASK_L4_4K (~(PUD_SIZE_L4_4K-1)) > > +#define PMD_SHIFT_L4_4K (21) > > +#define PMD_SIZE_L4_4K (1UL << PMD_SHIFT_L4_4K) > > +#define PMD_MASK_L4_4K (~(PMD_SIZE_L4_4K-1)) > > + > > +#define PGDIR_SIZE (1UL << ((48 - 39) + 3)) > > +#define PGDIR_MASK (~(PGDIR_SIZE - 1)) > > +#define PGDIR_OFFSET(X) (((ulong)(X)) & (PGDIR_SIZE - 1)) > > + > > +/* > > * 3-levels / 64K pages > > */ > > #define PTRS_PER_PGD_L3_64K (64) > > @@ -2941,6 +2963,7 @@ typedef signed int s32; > > #define KDUMP_ENABLED (0x20) > > #define IRQ_STACKS (0x40) > > #define NEW_VMEMMAP (0x80) > > +#define VM_L4_4K (0x100) > > > > /* > > * sources: Documentation/arm64/memory.txt > > -- > > 2.8.1 > > > > -- > > Crash-utility mailing list > > Crash-utility@xxxxxxxxxx > > https://www.redhat.com/mailman/listinfo/crash-utility > > > > -- > Crash-utility mailing list > Crash-utility@xxxxxxxxxx > https://www.redhat.com/mailman/listinfo/crash-utility -- Thanks, -Takahiro AKASHI -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility