Hi Lijiang & Kuan ying, On Fri, Aug 16, 2024 at 8:34 PM lijiang <lijiang@xxxxxxxxxx> wrote: > > On Fri, Aug 16, 2024 at 11:33 AM <devel-request@xxxxxxxxxxxxxxxxxxxxxxxxxxx> wrote: >> >> Date: Fri, 16 Aug 2024 11:30:20 +0800 >> From: Kuan-Ying Lee <kuan-ying.lee@xxxxxxxxxxxxx> >> Subject: [PATCH v2 1/3] arm64: Introduction of support >> for 16K page with 2-level table support >> To: kuan-ying.lee@xxxxxxxxxxxxx, >> devel@xxxxxxxxxxxxxxxxxxxxxxxxxxx >> Message-ID: <20240816033030.82655-2-kuan-ying.lee@xxxxxxxxxxxxx> >> >> Introduction of ARM64 support for 16K page size with 2-level page >> table and 36 VA bits. >> >> Signed-off-by: Kuan-Ying Lee <kuan-ying.lee@xxxxxxxxxxxxx> >> --- >> arm64.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- >> defs.h | 11 +++++++ >> 2 files changed, 101 insertions(+), 4 deletions(-) >> >> diff --git a/arm64.c b/arm64.c >> index 8ed1aaf919d6..e484d20992c0 100644 >> --- a/arm64.c >> +++ b/arm64.c >> @@ -42,6 +42,7 @@ static int arm64_kvtop(struct task_context *, ulong, physaddr_t *, int); >> 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_2level_16k(ulong, ulong, physaddr_t *, int); >> static int arm64_vtop_3level_16k(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); >> @@ -412,7 +413,7 @@ arm64_init(int when) >> break; >> >> case 16384: >> - if (machdep->machspec->VA_BITS > PGDIR_SHIFT_L3_16K) { >> + if (machdep->machspec->VA_BITS == 47) { >> machdep->flags |= VM_L3_16K; >> if (!machdep->ptrs_per_pgd) >> machdep->ptrs_per_pgd = PTRS_PER_PGD_L3_16K; >> @@ -425,8 +426,19 @@ arm64_init(int when) >> if ((machdep->ptbl = >> (char *)malloc(PTRS_PER_PTE_L3_16K * 8)) == NULL) >> error(FATAL, "cannot malloc ptbl space."); >> + } else if (machdep->machspec->VA_BITS == 36) { >> + machdep->flags |= VM_L2_16K; >> + if (!machdep->ptrs_per_pgd) >> + machdep->ptrs_per_pgd = PTRS_PER_PGD_L2_16K; >> + if ((machdep->pgd = >> + (char *)malloc(machdep->ptrs_per_pgd * 8)) == NULL) >> + error(FATAL, "cannot malloc pgd space."); >> + if ((machdep->ptbl = >> + (char *)malloc(PTRS_PER_PTE_L2_16K * 8)) == NULL) >> + error(FATAL, "cannot malloc ptbl space."); >> + machdep->pmd = NULL; /* not used */ >> } else { >> - error(FATAL, "we only support 47 bits, 3 level for 16K page now."); >> + error(FATAL, "Do not support 48 bits or 52 bits, 4-level for 16K page now."); > > > Thank you for the update, Kuan-Ying. > > I have no other comments, for v2: Ack Me too, for v2, ack. Thanks, Tao Liu > > Lianbo > >> } >> machdep->pud = NULL; /* not used */ >> break; >> @@ -1064,6 +1076,8 @@ arm64_dump_machdep_table(ulong arg) >> fprintf(fp, "%sVM_L2_64K", others++ ? "|" : ""); >> if (machdep->flags & VM_L3_64K) >> fprintf(fp, "%sVM_L3_64K", others++ ? "|" : ""); >> + if (machdep->flags & VM_L2_16K) >> + fprintf(fp, "%sVM_L2_16K", others++ ? "|" : ""); >> if (machdep->flags & VM_L3_16K) >> fprintf(fp, "%sVM_L3_16K", others++ ? "|" : ""); >> if (machdep->flags & VM_L3_4K) >> @@ -1113,6 +1127,8 @@ arm64_dump_machdep_table(ulong arg) >> "arm64_vtop_3level_4k" : >> machdep->flags & VM_L4_4K ? >> "arm64_vtop_4level_4k" : >> + machdep->flags & VM_L2_16K ? >> + "arm64_vtop_2level_16k" : >> machdep->flags & VM_L3_16K ? >> "arm64_vtop_3level_16k" : >> machdep->flags & VM_L3_64K ? >> @@ -1122,6 +1138,8 @@ arm64_dump_machdep_table(ulong arg) >> "arm64_vtop_3level_4k" : >> machdep->flags & VM_L4_4K ? >> "arm64_vtop_4level_4k" : >> + machdep->flags & VM_L2_16K ? >> + "arm64_vtop_2level_16k" : >> machdep->flags & VM_L3_16K ? >> "arm64_vtop_3level_16k" : >> machdep->flags & VM_L3_64K ? >> @@ -1814,7 +1832,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|VM_L4_4K|VM_L3_16K)) >> + switch (machdep->flags & (VM_L2_64K|VM_L3_64K|VM_L3_4K|VM_L4_4K|VM_L2_16K|VM_L3_16K)) >> { >> case VM_L2_64K: >> return arm64_vtop_2level_64k(kernel_pgd, kvaddr, paddr, verbose); >> @@ -1824,6 +1842,8 @@ arm64_kvtop(struct task_context *tc, ulong kvaddr, physaddr_t *paddr, int verbos >> return arm64_vtop_3level_4k(kernel_pgd, kvaddr, paddr, verbose); >> case VM_L4_4K: >> return arm64_vtop_4level_4k(kernel_pgd, kvaddr, paddr, verbose); >> + case VM_L2_16K: >> + return arm64_vtop_2level_16k(kernel_pgd, kvaddr, paddr, verbose); >> case VM_L3_16K: >> return arm64_vtop_3level_16k(kernel_pgd, kvaddr, paddr, verbose); >> default: >> @@ -1841,7 +1861,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|VM_L4_4K|VM_L3_16K)) >> + switch (machdep->flags & (VM_L2_64K|VM_L3_64K|VM_L3_4K|VM_L4_4K|VM_L2_16K|VM_L3_16K)) >> { >> case VM_L2_64K: >> return arm64_vtop_2level_64k(user_pgd, uvaddr, paddr, verbose); >> @@ -1851,6 +1871,8 @@ arm64_uvtop(struct task_context *tc, ulong uvaddr, physaddr_t *paddr, int verbos >> return arm64_vtop_3level_4k(user_pgd, uvaddr, paddr, verbose); >> case VM_L4_4K: >> return arm64_vtop_4level_4k(user_pgd, uvaddr, paddr, verbose); >> + case VM_L2_16K: >> + return arm64_vtop_2level_16k(user_pgd, uvaddr, paddr, verbose); >> case VM_L3_16K: >> return arm64_vtop_3level_16k(user_pgd, uvaddr, paddr, verbose); >> default: >> @@ -2012,6 +2034,70 @@ no_page: >> return FALSE; >> } >> >> +static int >> +arm64_vtop_2level_16k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose) >> +{ >> + ulong *pgd_base, *pgd_ptr, pgd_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, machdep->ptrs_per_pgd * sizeof(ulong)); >> + pgd_ptr = pgd_base + (((vaddr) >> PGDIR_SHIFT_L2_16K) & (machdep->ptrs_per_pgd - 1)); >> + pgd_val = ULONG(machdep->pgd + PAGEOFFSET(pgd_ptr)); >> + if (verbose) >> + fprintf(fp, " PGD: %lx => %lx\n", (ulong)pgd_ptr, pgd_val); >> + if (!pgd_val) >> + goto no_page; >> + >> + /* >> + * #define __PAGETABLE_PUD_FOLDED >> + * #define __PAGETABLE_PMD_FOLDED >> + */ >> + >> + if ((pgd_val & PMD_TYPE_MASK) == PMD_TYPE_SECT) { >> + ulong sectionbase = (pgd_val & SECTION_PAGE_MASK_32MB) & PHYS_MASK; >> + if (verbose) { >> + fprintf(fp, " PAGE: %lx (32MB%s)\n\n", sectionbase, >> + IS_ZEROPAGE(sectionbase) ? ", ZERO PAGE" : ""); >> + arm64_translate_pte(pgd_val, 0, 0); >> + } >> + *paddr = sectionbase + (vaddr & ~SECTION_PAGE_MASK_32MB); >> + return TRUE; >> + } >> + >> + pte_base = (ulong *)PTOV(pgd_val & PHYS_MASK & (s32)machdep->pagemask); >> + FILL_PTBL(pte_base, KVADDR, PTRS_PER_PTE_L2_16K * sizeof(ulong)); >> + pte_ptr = pte_base + (((vaddr) >> machdep->pageshift) & (PTRS_PER_PTE_L2_16K - 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 %s\n\n", PAGEBASE(*paddr), >> + IS_ZEROPAGE(PAGEBASE(*paddr)) ? "(ZERO PAGE)" : ""); >> + 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 int >> arm64_vtop_3level_16k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose) >> { >> diff --git a/defs.h b/defs.h >> index 1b7649d9f05c..dfbd2419f969 100644 >> --- a/defs.h >> +++ b/defs.h >> @@ -3302,6 +3302,16 @@ typedef signed int s32; >> #define PGDIR_MASK_48VA (~(PGDIR_SIZE_48VA - 1)) >> #define PGDIR_OFFSET_48VA(X) (((ulong)(X)) & (PGDIR_SIZE_48VA - 1)) >> >> +/* >> + * 2-levels / 16K pages >> + * 36-bit VA >> + */ >> +#define PTRS_PER_PGD_L2_16K (2048) >> +#define PTRS_PER_PTE_L2_16K (2048) >> +#define PGDIR_SHIFT_L2_16K (25) >> +#define PGDIR_SIZE_L2_16K ((1UL) << PGDIR_SHIFT_L2_16K) >> +#define PGDIR_MASK_L2_16K (~(PGDIR_SIZE_L2_16K-1)) >> + >> /* >> * 3-levels / 16K pages >> * 47-bit VA >> @@ -3383,6 +3393,7 @@ typedef signed int s32; >> #define OVERFLOW_STACKS (0x1000) >> #define ARM64_MTE (0x2000) >> #define VM_L3_16K (0x4000) >> +#define VM_L2_16K (0x8000) >> >> /* >> * Get kimage_voffset from /dev/crash >> -- >> 2.43.0 > > -- > Crash-utility mailing list -- devel@xxxxxxxxxxxxxxxxxxxxxxxxxxx > To unsubscribe send an email to devel-leave@xxxxxxxxxxxxxxxxxxxxxxxxxxx > https://${domain_name}/admin/lists/devel.lists.crash-utility.osci.io/ > Contribution Guidelines: https://github.com/crash-utility/crash/wiki -- Crash-utility mailing list -- devel@xxxxxxxxxxxxxxxxxxxxxxxxxxx To unsubscribe send an email to devel-leave@xxxxxxxxxxxxxxxxxxxxxxxxxxx https://${domain_name}/admin/lists/devel.lists.crash-utility.osci.io/ Contribution Guidelines: https://github.com/crash-utility/crash/wiki