After commit ebd9aea1f27e ("arm64: head: drop idmap_ptrs_per_pgd") in Linux kernel-v6.0, kernel removed the idmap_ptrs_per_pgd. This commit cause the following error. crash: invalid kernel virtual address: ffff800083700000 type: "64-bit KVADDR" We cannot use "idmap_ptrs_per_pgd" to know the size of "ptrs_per_pgd". We use VA_BITS to know the size of "ptrs_per_pgd" instead. Signed-off-by: Kuan-Ying Lee <kuan-ying.lee@xxxxxxxxxxxxx> --- arm64.c | 18 ++++++++++++++++-- defs.h | 3 ++- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/arm64.c b/arm64.c index 8812110fb950..d8b030d4b0b0 100644 --- a/arm64.c +++ b/arm64.c @@ -445,6 +445,10 @@ arm64_init(int when) break; case 65536: + /* + * idmap_ptrs_per_pgd has been removed in kernel commit ebd9aea1f27e ("arm64: + * head: drop idmap_ptrs_per_pgd"). This commit is included after Linux-v6.0. + */ if (kernel_symbol_exists("idmap_ptrs_per_pgd") && readmem(symbol_value("idmap_ptrs_per_pgd"), KVADDR, &value, sizeof(ulong), "idmap_ptrs_per_pgd", QUIET|RETURN_ON_ERROR)) @@ -452,8 +456,14 @@ arm64_init(int when) if (machdep->machspec->VA_BITS > PGDIR_SHIFT_L3_64K) { machdep->flags |= VM_L3_64K; - if (!machdep->ptrs_per_pgd) - machdep->ptrs_per_pgd = PTRS_PER_PGD_L3_64K; + if (!machdep->ptrs_per_pgd) { + if (machdep->machspec->VA_BITS == 52) + machdep->ptrs_per_pgd = PTRS_PER_PGD_L3_64K_52; + else if (machdep->machspec->VA_BITS == 48) + machdep->ptrs_per_pgd = PTRS_PER_PGD_L3_64K_48; + else + error(FATAL, "wrong VA_BITS for 64K page."); + } if ((machdep->pgd = (char *)malloc(machdep->ptrs_per_pgd * 8)) == NULL) error(FATAL, "cannot malloc pgd space."); @@ -1974,6 +1984,10 @@ arm64_vtop_3level_64k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose) pgd_base = (ulong *)pgd; FILL_PGD(pgd_base, KVADDR, machdep->ptrs_per_pgd * sizeof(ulong)); + /* + * We need to use machdep->ptrs_per_pgd to mask vaddr instead of using macro, because + * 48-bits and 52-bits have different size of ptrs_per_pgd. + */ pgd_ptr = pgd_base + (((vaddr) >> PGDIR_SHIFT_L3_64K) & (machdep->ptrs_per_pgd - 1)); pgd_val = ULONG(machdep->pgd + PGDIR_OFFSET_L3_64K(pgd_ptr)); if (verbose) diff --git a/defs.h b/defs.h index 2d881344cba6..9f4d676e25f9 100644 --- a/defs.h +++ b/defs.h @@ -3333,7 +3333,8 @@ typedef signed int s32; * 3-levels / 64K pages * 48-bit, 52-bit VA */ -#define PTRS_PER_PGD_L3_64K (64) +#define PTRS_PER_PGD_L3_64K_48 ((1UL) << (48 - 42)) // 48-bit VA +#define PTRS_PER_PGD_L3_64K_52 ((1UL) << (52 - 42)) // 52-bit VA #define PTRS_PER_PMD_L3_64K (8192) #define PTRS_PER_PTE_L3_64K (8192) #define PGDIR_SHIFT_L3_64K (42) -- 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