[Crash-utility] [PATCH 3/4] arm64: fix 64K page and 52-bits VA support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux