Blame SOURCES/0016-arm64-use-TCR_EL1_T1SZ-to-get-the-correct-info-if-va.patch

3ce5e9
From 28a41ec7a471474094d8ab39f3a69b44d0f9ebcf Mon Sep 17 00:00:00 2001
3ce5e9
From: Huang Shijie <shijie@os.amperecomputing.com>
3ce5e9
Date: Mon, 22 Aug 2022 09:29:32 +0000
3ce5e9
Subject: [PATCH 16/28] arm64: use TCR_EL1_T1SZ to get the correct info if
3ce5e9
 vabits_actual is missing
3ce5e9
3ce5e9
After kernel commit 0d9b1ffefabe ("arm64: mm: make vabits_actual a build
3ce5e9
time constant if possible"), the vabits_actual is not compiled to kernel
3ce5e9
symbols when "VA_BITS > 48" is false.
3ce5e9
3ce5e9
So the crash will not find the vabits_actual symbol, and it will fail
3ce5e9
in the end like this:
3ce5e9
3ce5e9
  # ./crash
3ce5e9
  ...
3ce5e9
  WARNING: VA_BITS: calculated: 46  vmcoreinfo: 48
3ce5e9
  crash: invalid kernel virtual address: ffff88177ffff000  type: "pud page"
3ce5e9
3ce5e9
This patch introduces the arm64_set_va_bits_by_tcr(), and if crash cannot
3ce5e9
find vabits_actual symbol, it will use the TCR_EL1_T1SZ register to get
3ce5e9
the correct VA_BITS_ACTUAL/VA_BITS/VA_START.
3ce5e9
3ce5e9
Tested this patch with:
3ce5e9
  1.) the live mode with /proc/kcore
3ce5e9
  2.) the kdump file with /proc/vmcore.
3ce5e9
3ce5e9
Signed-off-by: Huang Shijie <shijie@os.amperecomputing.com>
3ce5e9
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
3ce5e9
---
3ce5e9
 arm64.c | 51 ++++++++++++++++++++++++++++++++++-----------------
3ce5e9
 1 file changed, 34 insertions(+), 17 deletions(-)
3ce5e9
3ce5e9
diff --git a/arm64.c b/arm64.c
3ce5e9
index b6b7aa11f4fe..c3e26a371a61 100644
3ce5e9
--- a/arm64.c
3ce5e9
+++ b/arm64.c
3ce5e9
@@ -4586,6 +4586,36 @@ arm64_IS_VMALLOC_ADDR(ulong vaddr)
3ce5e9
                 (vaddr >= ms->modules_vaddr && vaddr <= ms->modules_end));
3ce5e9
 }
3ce5e9
 
3ce5e9
+/* Return TRUE if we succeed, return FALSE on failure. */
3ce5e9
+static int
3ce5e9
+arm64_set_va_bits_by_tcr(void)
3ce5e9
+{
3ce5e9
+	ulong value;
3ce5e9
+	char *string;
3ce5e9
+
3ce5e9
+	if ((string = pc->read_vmcoreinfo("NUMBER(TCR_EL1_T1SZ)")) ||
3ce5e9
+	    (string = pc->read_vmcoreinfo("NUMBER(tcr_el1_t1sz)"))) {
3ce5e9
+		/* See ARMv8 ARM for the description of
3ce5e9
+		 * TCR_EL1.T1SZ and how it can be used
3ce5e9
+		 * to calculate the vabits_actual
3ce5e9
+		 * supported by underlying kernel.
3ce5e9
+		 *
3ce5e9
+		 * Basically:
3ce5e9
+		 * vabits_actual = 64 - T1SZ;
3ce5e9
+		 */
3ce5e9
+		value = 64 - strtoll(string, NULL, 0);
3ce5e9
+		if (CRASHDEBUG(1))
3ce5e9
+			fprintf(fp,  "vmcoreinfo : vabits_actual: %ld\n", value);
3ce5e9
+		free(string);
3ce5e9
+		machdep->machspec->VA_BITS_ACTUAL = value;
3ce5e9
+		machdep->machspec->VA_BITS = value;
3ce5e9
+		machdep->machspec->VA_START = _VA_START(machdep->machspec->VA_BITS_ACTUAL);
3ce5e9
+		return TRUE;
3ce5e9
+	}
3ce5e9
+
3ce5e9
+	return FALSE;
3ce5e9
+}
3ce5e9
+
3ce5e9
 static void 
3ce5e9
 arm64_calc_VA_BITS(void)
3ce5e9
 {
3ce5e9
@@ -4616,23 +4646,8 @@ arm64_calc_VA_BITS(void)
3ce5e9
 		} else if (ACTIVE())
3ce5e9
 			error(FATAL, "cannot determine VA_BITS_ACTUAL: please use /proc/kcore\n");
3ce5e9
 		else {
3ce5e9
-			if ((string = pc->read_vmcoreinfo("NUMBER(TCR_EL1_T1SZ)")) ||
3ce5e9
-			    (string = pc->read_vmcoreinfo("NUMBER(tcr_el1_t1sz)"))) {
3ce5e9
-				/* See ARMv8 ARM for the description of
3ce5e9
-				 * TCR_EL1.T1SZ and how it can be used
3ce5e9
-				 * to calculate the vabits_actual
3ce5e9
-				 * supported by underlying kernel.
3ce5e9
-				 *
3ce5e9
-				 * Basically:
3ce5e9
-				 * vabits_actual = 64 - T1SZ;
3ce5e9
-				 */
3ce5e9
-				value = 64 - strtoll(string, NULL, 0);
3ce5e9
-				if (CRASHDEBUG(1))
3ce5e9
-					fprintf(fp,  "vmcoreinfo : vabits_actual: %ld\n", value);
3ce5e9
-				free(string);
3ce5e9
-				machdep->machspec->VA_BITS_ACTUAL = value;
3ce5e9
-				machdep->machspec->VA_BITS = value;
3ce5e9
-				machdep->machspec->VA_START = _VA_START(machdep->machspec->VA_BITS_ACTUAL);
3ce5e9
+			if (arm64_set_va_bits_by_tcr()) {
3ce5e9
+				/* nothing */
3ce5e9
 			} else if (machdep->machspec->VA_BITS_ACTUAL) {
3ce5e9
 				machdep->machspec->VA_BITS = machdep->machspec->VA_BITS_ACTUAL;
3ce5e9
 				machdep->machspec->VA_START = _VA_START(machdep->machspec->VA_BITS_ACTUAL);
3ce5e9
@@ -4654,6 +4669,8 @@ arm64_calc_VA_BITS(void)
3ce5e9
 		 */
3ce5e9
 		machdep->flags |= FLIPPED_VM;
3ce5e9
 		return;
3ce5e9
+	} else if (arm64_set_va_bits_by_tcr()) {
3ce5e9
+		return;
3ce5e9
 	}
3ce5e9
 
3ce5e9
 	if (!(sp = symbol_search("swapper_pg_dir")) &&
3ce5e9
-- 
3ce5e9
2.37.1
3ce5e9