On Fri, Aug 16, 2024 at 4:41 PM Tao Liu <ltao(a)redhat.com> wrote:
Hi Lijiang & Kuan ying,
On Fri, Aug 16, 2024 at 8:34 PM lijiang <lijiang(a)redhat.com> wrote:
>
> On Fri, Aug 16, 2024 at 11:33 AM <
devel-request(a)lists.crash-utility.osci.io> wrote:
>>
>> Date: Fri, 16 Aug 2024 11:30:20 +0800
>> From: Kuan-Ying Lee <kuan-ying.lee(a)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(a)canonical.com,
>> devel(a)lists.crash-utility.osci.io
>> Message-ID: <20240816033030.82655-2-kuan-ying.lee(a)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(a)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/bcdf0f798d01dcc9c92be3c1e02...
[2]
https://github.com/crash-utility/crash/commit/f93d870f8b6ad79cb84694d8e32...
[3]
https://github.com/crash-utility/crash/commit/af3d266aeb8c18c5e41d0a72694...
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