On Fri, Aug 16, 2024 at 4:41 PM Tao Liu <ltao@redhat.com> wrote:
Hi Lijiang & Kuan ying,

On Fri, Aug 16, 2024 at 8:34 PM lijiang <lijiang@redhat.com> wrote:
>
> On Fri, Aug 16, 2024 at 11:33 AM <devel-request@lists.crash-utility.osci.io> wrote:
>>
>> Date: Fri, 16 Aug 2024 11:30:20 +0800
>> From: Kuan-Ying Lee <kuan-ying.lee@canonical.com>
>> Subject: [Crash-utility] [PATCH v2 1/3] arm64: Introduction of support
>>         for 16K page with 2-level table support
>> To: kuan-ying.lee@canonical.com,
>>         devel@lists.crash-utility.osci.io
>> Message-ID: <20240816033030.82655-2-kuan-ying.lee@canonical.com>
>>
>> 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@canonical.com>
>> ---
>>  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.


Applied:
[1] https://github.com/crash-utility/crash/commit/bcdf0f798d01dcc9c92be3c1e027e35629463b13
[2] https://github.com/crash-utility/crash/commit/f93d870f8b6ad79cb84694d8e3226cb8c3f54c3e
[3] https://github.com/crash-utility/crash/commit/af3d266aeb8c18c5e41d0a72694f4dce88754396

Thanks
Lianbo
 
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