Blame SOURCES/kexec-tools-2.0.15-makedumpfile-arm64-restore-info-page_offset-and-implement-paddr_t.patch

1c0632
From 91dc4cab62568605a274dd2260e863df2ade0230 Mon Sep 17 00:00:00 2001
1c0632
From: Bhupesh Sharma <bhsharma@redhat.com>
1c0632
Date: Thu, 27 Dec 2018 15:26:16 +0530
1c0632
Subject: makedumpfile/arm64: Fix 'info->page_offset' calculation
1c0632
1c0632
This patch is a partial backport of the makedumpfile commit
1c0632
bc8b3bbf41580723435d5d4c6da17db3c9e5ad6d.
1c0632
1c0632
Since the upstream makedumpfile implementation had intermediate patches
1c0632
applied which eased 'page_offset' calculation for arm64 arch, but these
1c0632
were reverted via bc8b3bbf41580723435d5d4c6da17db3c9e5ad6d.
1c0632
1c0632
So, its not very useful to backport all those intermediate patches.
1c0632
1c0632
Signed-off-by: Bhupesh Sharma <bhsharma@redhat.com>
1c0632
---
1c0632
 arch/arm64.c   | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----
1c0632
 makedumpfile.c |  6 +++++
1c0632
 makedumpfile.h |  7 +++++-
1c0632
 3 files changed, 82 insertions(+), 6 deletions(-)
1c0632
1c0632
diff --git a/makedumpfile-1.6.2/arch/arm64.c b/makedumpfile-1.6.2/arch/arm64.c
1c0632
index fe49d408186e..491010846f8e 100644
1c0632
--- a/makedumpfile-1.6.2/arch/arm64.c
1c0632
+++ b/makedumpfile-1.6.2/arch/arm64.c
1c0632
@@ -168,11 +168,76 @@ get_kvbase_arm64(void)
1c0632
 int
1c0632
 get_phys_base_arm64(void)
1c0632
 {
1c0632
-	info->phys_base = NUMBER(PHYS_OFFSET);
1c0632
+	int i;
1c0632
+	unsigned long long phys_start;
1c0632
+	unsigned long long virt_start;
1c0632
+
1c0632
+	if (NUMBER(PHYS_OFFSET) != NOT_FOUND_NUMBER) {
1c0632
+		info->phys_base = NUMBER(PHYS_OFFSET);
1c0632
+		DEBUG_MSG("phys_base    : %lx (vmcoreinfo)\n",
1c0632
+				info->phys_base);
1c0632
+		return TRUE;
1c0632
+	}
1c0632
1c0632
-	DEBUG_MSG("phys_base    : %lx\n", info->phys_base);
1c0632
+	if (get_num_pt_loads() && PAGE_OFFSET) {
1c0632
+		for (i = 0;
1c0632
+		    get_pt_load(i, &phys_start, NULL, &virt_start, NULL);
1c0632
+		    i++) {
1c0632
+			if (virt_start != NOT_KV_ADDR
1c0632
+			    && virt_start >= PAGE_OFFSET
1c0632
+			    && phys_start != NOT_PADDR) {
1c0632
+				info->phys_base = phys_start -
1c0632
+					(virt_start & ~PAGE_OFFSET);
1c0632
+				DEBUG_MSG("phys_base    : %lx (pt_load)\n",
1c0632
+						info->phys_base);
1c0632
+				return TRUE;
1c0632
+			}
1c0632
+		}
1c0632
+	}
1c0632
1c0632
-	return TRUE;
1c0632
+	ERRMSG("Cannot determine phys_base\n");
1c0632
+	return FALSE;
1c0632
+}
1c0632
+
1c0632
+unsigned long
1c0632
+get_kaslr_offset_arm64(unsigned long vaddr)
1c0632
+{
1c0632
+	unsigned int i;
1c0632
+	char buf[BUFSIZE_FGETS], *endp;
1c0632
+
1c0632
+	if (!info->kaslr_offset && info->file_vmcoreinfo) {
1c0632
+		if (fseek(info->file_vmcoreinfo, 0, SEEK_SET) < 0) {
1c0632
+			ERRMSG("Can't seek the vmcoreinfo file(%s). %s\n",
1c0632
+					info->name_vmcoreinfo, strerror(errno));
1c0632
+			return FALSE;
1c0632
+		}
1c0632
+
1c0632
+		while (fgets(buf, BUFSIZE_FGETS, info->file_vmcoreinfo)) {
1c0632
+			i = strlen(buf);
1c0632
+			if (!i)
1c0632
+				break;
1c0632
+			if (buf[i - 1] == '\n')
1c0632
+				buf[i - 1] = '\0';
1c0632
+			if (strncmp(buf, STR_KERNELOFFSET,
1c0632
+					strlen(STR_KERNELOFFSET)) == 0) {
1c0632
+				info->kaslr_offset =
1c0632
+					strtoul(buf+strlen(STR_KERNELOFFSET),&endp,16);
1c0632
+				DEBUG_MSG("info->kaslr_offset: %lx\n", info->kaslr_offset);
1c0632
+			}
1c0632
+		}
1c0632
+	}
1c0632
+
1c0632
+	if (vaddr >= __START_KERNEL_map &&
1c0632
+			vaddr < __START_KERNEL_map + info->kaslr_offset) {
1c0632
+		DEBUG_MSG("info->kaslr_offset: %lx\n", info->kaslr_offset);
1c0632
+		return info->kaslr_offset;
1c0632
+	} else {
1c0632
+		/*
1c0632
+		 * TODO: we need to check if it is vmalloc/vmmemmap/module
1c0632
+		 * address, we will have different offset
1c0632
+		 */
1c0632
+		return 0;
1c0632
+	}
1c0632
 }
1c0632
1c0632
 ulong
1c0632
@@ -285,8 +350,8 @@ get_versiondep_info_arm64(void)
1c0632
1c0632
	info->page_offset = (0xffffffffffffffffUL) << (va_bits - 1);
1c0632
1c0632
-	DEBUG_MSG("page_offset=%lx, va_bits=%d\n", info->page_offset,
1c0632
-			va_bits);
1c0632
+	DEBUG_MSG("va_bits      : %d\n", va_bits);
1c0632
+	DEBUG_MSG("page_offset  : %lx\n", info->page_offset);
1c0632
1c0632
	return TRUE;
1c0632
 }
1c0632
diff --git a/makedumpfile-1.6.2/makedumpfile.c b/makedumpfile-1.6.2/makedumpfile.c
1c0632
index c9634cd42858..78ebced33e6a 100644
1c0632
--- a/makedumpfile-1.6.2/makedumpfile.c
1c0632
+++ b/makedumpfile-1.6.2/makedumpfile.c
1c0632
@@ -2339,6 +2339,7 @@ read_vmcoreinfo_basic_info(void)
1c0632
			break;
1c0632
		if (buf[i - 1] == '\n')
1c0632
			buf[i - 1] = '\0';
1c0632
+
1c0632
		if (strncmp(buf, STR_OSRELEASE, strlen(STR_OSRELEASE)) == 0) {
1c0632
			get_release = TRUE;
1c0632
			/* if the release have been stored, skip this time. */
1c0632
@@ -2382,6 +2383,7 @@ read_vmcoreinfo_basic_info(void)
1c0632
		    strlen(STR_CONFIG_PGTABLE_4)) == 0)
1c0632
			vt.mem_flags |= MEMORY_PAGETABLE_4L;
1c0632
	}
1c0632
+
1c0632
	if (!get_release || !info->page_size) {
1c0632
		ERRMSG("Invalid format in %s", info->name_vmcoreinfo);
1c0632
		return FALSE;
1c0632
@@ -11084,6 +11086,10 @@ int show_mem_usage(void)
1c0632
	if (!get_page_offset())
1c0632
		return FALSE;
1c0632
1c0632
+	/* paddr_to_vaddr() on arm64 needs phys_base. */
1c0632
+	if (!get_phys_base())
1c0632
+		return FALSE;
1c0632
+
1c0632
	if (!get_sys_kernel_vmcoreinfo(&vmcoreinfo_addr, &vmcoreinfo_len))
1c0632
		return FALSE;
1c0632
1c0632
diff --git a/makedumpfile-1.6.2/makedumpfile.h b/makedumpfile-1.6.2/makedumpfile.h
1c0632
index 010a9ce302bd..177805935b71 100644
1c0632
--- a/makedumpfile-1.6.2/makedumpfile.h
1c0632
+++ b/makedumpfile-1.6.2/makedumpfile.h
1c0632
@@ -529,6 +529,8 @@ do { \
1c0632
 #ifdef __aarch64__
1c0632
 unsigned long get_kvbase_arm64(void);
1c0632
 #define KVBASE			get_kvbase_arm64()
1c0632
+#define __START_KERNEL_map	(0xffffffff80000000UL)
1c0632
+
1c0632
 #endif /* aarch64 */
1c0632
1c0632
 #ifdef __arm__
1c0632
@@ -938,9 +940,12 @@ unsigned long long vaddr_to_paddr_arm64(unsigned long vaddr);
1c0632
 int get_versiondep_info_arm64(void);
1c0632
 int get_xen_basic_info_arm64(void);
1c0632
 int get_xen_info_arm64(void);
1c0632
+unsigned long get_kaslr_offset_arm64(unsigned long vaddr);
1c0632
+#define paddr_to_vaddr_arm64(X) (((X) - info->phys_base) | PAGE_OFFSET)
1c0632
+
1c0632
 #define find_vmemmap()		stub_false()
1c0632
 #define vaddr_to_paddr(X)	vaddr_to_paddr_arm64(X)
1c0632
-#define paddr_to_vaddr(X)	paddr_to_vaddr_general(X)
1c0632
+#define paddr_to_vaddr(X)	paddr_to_vaddr_arm64(X)
1c0632
 #define get_phys_base()		get_phys_base_arm64()
1c0632
 #define get_machdep_info()	get_machdep_info_arm64()
1c0632
 #define get_versiondep_info()	get_versiondep_info_arm64()
1c0632
--
1c0632
2.7.4