Blame SOURCES/kexec-tools-2.0.15-makedumpfile-arm64-Add-support-to-read-symbols-like-_stext-from-p.patch

26a7a5
From d1e780507b6ed4b67e5e0e4e4b7c9796dc537210 Mon Sep 17 00:00:00 2001
26a7a5
From: Bhupesh Sharma <bhsharma@redhat.com>
26a7a5
Date: Tue, 6 Mar 2018 02:13:00 +0900
26a7a5
Subject: [PATCH 2/3] arm64: Add support to read symbols like _stext from
26a7a5
 '/proc/kallsyms'
26a7a5
26a7a5
On ARM64 platforms the VA_BITS supported by a linux kernel being run
26a7a5
can be selected by setting 'ARM64_VA_BITS_*' (see 'arch/arm64/Kconfig'
26a7a5
for details).
26a7a5
26a7a5
Now, to determine the 'info->page_offset' in arm64 makedumpfile
26a7a5
context ('arch/arm64.c') we need to determine the VA_BITS which was
26a7a5
selected by the underlying linux kernel.
26a7a5
26a7a5
There can be several ways to determine the VA_BITS, out of which
26a7a5
reading the '_stext' symbol and calculating the 'va_bits' using the
26a7a5
same is the simplest yet portable method.
26a7a5
26a7a5
For reading the kernel symbols like '_stext', we can read the
26a7a5
'/proc/kallsyms' file which contains these symbols and
26a7a5
works even in case of KASLR enabled arm64 kernels, as in those cases,
26a7a5
the '_stext' symbol will end up being randomized and hence
26a7a5
cannot be correctly read from the 'vmlinux' file.
26a7a5
26a7a5
Signed-off-by: Bhupesh Sharma <bhsharma@redhat.com>
26a7a5
---
26a7a5
 arch/arm64.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
26a7a5
 1 file changed, 73 insertions(+), 4 deletions(-)
26a7a5
26a7a5
diff --git a/makedumpfile-1.6.2/arch/arm64.c b/makedumpfile-1.6.2/arch/arm64.c
26a7a5
index 25d7a1f4db98..c9dab677f2c9 100644
26a7a5
--- a/makedumpfile-1.6.2/arch/arm64.c
26a7a5
+++ b/makedumpfile-1.6.2/arch/arm64.c
26a7a5
@@ -48,6 +48,12 @@ static unsigned long kimage_voffset;
26a7a5
 #define SZ_64K			(64 * 1024)
26a7a5
 #define SZ_128M			(128 * 1024 * 1024)
26a7a5
 
26a7a5
+#define PAGE_OFFSET_36 ((0xffffffffffffffffUL) << 36)
26a7a5
+#define PAGE_OFFSET_39 ((0xffffffffffffffffUL) << 39)
26a7a5
+#define PAGE_OFFSET_42 ((0xffffffffffffffffUL) << 42)
26a7a5
+#define PAGE_OFFSET_47 ((0xffffffffffffffffUL) << 47)
26a7a5
+#define PAGE_OFFSET_48 ((0xffffffffffffffffUL) << 48)
26a7a5
+
26a7a5
 #define pgd_val(x)		((x).pgd)
26a7a5
 #define pud_val(x)		(pgd_val((x).pgd))
26a7a5
 #define pmd_val(x)		(pud_val((x).pud))
26a7a5
@@ -140,8 +146,6 @@ pud_offset(pgd_t *pgda, pgd_t *pgdv, unsigned long vaddr)
26a7a5
 
26a7a5
 static int calculate_plat_config(void)
26a7a5
 {
26a7a5
-	va_bits = NUMBER(VA_BITS);
26a7a5
-
26a7a5
 	/* derive pgtable_level as per arch/arm64/Kconfig */
26a7a5
 	if ((PAGESIZE() == SZ_16K && va_bits == 36) ||
26a7a5
 			(PAGESIZE() == SZ_64K && va_bits == 42)) {
26a7a5
@@ -177,6 +181,44 @@ get_phys_base_arm64(void)
26a7a5
 	return TRUE;
26a7a5
 }
26a7a5
 
26a7a5
+ulong
26a7a5
+get_stext_symbol(void)
26a7a5
+{
26a7a5
+	int found;
26a7a5
+	FILE *fp;
26a7a5
+	char buf[BUFSIZE];
26a7a5
+	char *kallsyms[MAXARGS];
26a7a5
+	ulong kallsym;
26a7a5
+
26a7a5
+	if (!file_exists("/proc/kallsyms")) {
26a7a5
+		ERRMSG("(%s) does not exist, will not be able to read symbols. %s\n",
26a7a5
+		       "/proc/kallsyms", strerror(errno));
26a7a5
+		return FALSE;
26a7a5
+	}
26a7a5
+
26a7a5
+	if ((fp = fopen("/proc/kallsyms", "r")) == NULL) {
26a7a5
+		ERRMSG("Cannot open (%s) to read symbols. %s\n",
26a7a5
+		       "/proc/kallsyms", strerror(errno));
26a7a5
+		return FALSE;
26a7a5
+	}
26a7a5
+
26a7a5
+	found = FALSE;
26a7a5
+	kallsym = 0;
26a7a5
+
26a7a5
+	while (!found && fgets(buf, BUFSIZE, fp) &&
26a7a5
+	      (parse_line(buf, kallsyms) == 3)) {
26a7a5
+		if (hexadecimal(kallsyms[0], 0) &&
26a7a5
+		    STREQ(kallsyms[2], "_stext")) {
26a7a5
+			kallsym = htol(kallsyms[0], 0);
26a7a5
+			found = TRUE;
26a7a5
+			break;
26a7a5
+		}
26a7a5
+	}
26a7a5
+	fclose(fp);
26a7a5
+
26a7a5
+	return(found ? kallsym : FALSE);
26a7a5
+}
26a7a5
+
26a7a5
 int
26a7a5
 get_machdep_info_arm64(void)
26a7a5
 {
26a7a5
@@ -188,12 +230,10 @@ get_machdep_info_arm64(void)
26a7a5
 	kimage_voffset = NUMBER(kimage_voffset);
26a7a5
 	info->max_physmem_bits = PHYS_MASK_SHIFT;
26a7a5
 	info->section_size_bits = SECTIONS_SIZE_BITS;
26a7a5
-	info->page_offset = 0xffffffffffffffffUL << (va_bits - 1);
26a7a5
 
26a7a5
 	DEBUG_MSG("kimage_voffset   : %lx\n", kimage_voffset);
26a7a5
 	DEBUG_MSG("max_physmem_bits : %lx\n", info->max_physmem_bits);
26a7a5
 	DEBUG_MSG("section_size_bits: %lx\n", info->section_size_bits);
26a7a5
-	DEBUG_MSG("page_offset      : %lx\n", info->page_offset);
26a7a5
 
26a7a5
 	return TRUE;
26a7a5
 }
26a7a5
@@ -219,6 +259,35 @@ get_xen_info_arm64(void)
26a7a5
 int
26a7a5
 get_versiondep_info_arm64(void)
26a7a5
 {
26a7a5
+	ulong _stext;
26a7a5
+
26a7a5
+	_stext = get_stext_symbol();
26a7a5
+	if (!_stext) {
26a7a5
+		ERRMSG("Can't get the symbol of _stext.\n");
26a7a5
+		return FALSE;
26a7a5
+	}
26a7a5
+
26a7a5
+	/* Derive va_bits as per arch/arm64/Kconfig */
26a7a5
+	if ((_stext & PAGE_OFFSET_36) == PAGE_OFFSET_36) {
26a7a5
+		va_bits = 36;
26a7a5
+	} else if ((_stext & PAGE_OFFSET_39) == PAGE_OFFSET_39) {
26a7a5
+		va_bits = 39;
26a7a5
+	} else if ((_stext & PAGE_OFFSET_42) == PAGE_OFFSET_42) {
26a7a5
+		va_bits = 42;
26a7a5
+	} else if ((_stext & PAGE_OFFSET_47) == PAGE_OFFSET_47) {
26a7a5
+		va_bits = 47;
26a7a5
+	} else if ((_stext & PAGE_OFFSET_48) == PAGE_OFFSET_48) {
26a7a5
+		va_bits = 48;
26a7a5
+	} else {
26a7a5
+		ERRMSG("Cannot find a proper _stext for calculating VA_BITS\n");
26a7a5
+		return FALSE;
26a7a5
+	}
26a7a5
+
26a7a5
+	info->page_offset = (0xffffffffffffffffUL) << (va_bits - 1);
26a7a5
+
26a7a5
+	DEBUG_MSG("page_offset=%lx, va_bits=%d\n", info->page_offset,
26a7a5
+			va_bits);
26a7a5
+
26a7a5
 	return TRUE;
26a7a5
 }
26a7a5
 
26a7a5
-- 
26a7a5
2.7.4
26a7a5