From f1197543d1c4f16523469a062e80c4bdb82ea0ff Mon Sep 17 00:00:00 2001
From: Bhupesh Sharma <bhsharma@redhat.com>
Date: Thu, 10 Sep 2020 11:03:03 +0530
Subject: [PATCH 1/2] [PATCH] Retrieve MAX_PHYSMEM_BITS from vmcoreinfo

Add a common feature for architectures (except arm64, for which
similar support is added via a subsequent patch) to retrieve
MAX_PHYSMEM_BITS from vmcoreinfo, which was added by kernel commit
1d50e5d0c505 ("crash_core, vmcoreinfo: Append 'MAX_PHYSMEM_BITS'
to vmcoreinfo").  This makes makedumpfile adaptable for future
MAX_PHYSMEM_BITS changes.

Also ensure backward compatibility for kernel versions in which
MAX_PHYSMEM_BITS is not available in vmcoreinfo.

Signed-off-by: Bhupesh Sharma <bhsharma@redhat.com>
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
---
 arch/arm.c     | 8 +++++++-
 arch/ia64.c    | 7 ++++++-
 arch/ppc.c     | 8 +++++++-
 arch/ppc64.c   | 7 +++++++
 arch/s390x.c   | 7 +++++++
 arch/sparc64.c | 9 +++++++--
 arch/x86.c     | 5 +++++
 arch/x86_64.c  | 8 ++++----
 8 files changed, 50 insertions(+), 9 deletions(-)

diff --git a/arch/arm.c b/arch/arm.c
index af7442a..33536fc 100644
--- a/arch/arm.c
+++ b/arch/arm.c
@@ -81,7 +81,13 @@ int
 get_machdep_info_arm(void)
 {
 	info->page_offset = SYMBOL(_stext) & 0xffff0000UL;
-	info->max_physmem_bits = _MAX_PHYSMEM_BITS;
+
+	/* Check if we can get MAX_PHYSMEM_BITS from vmcoreinfo */
+	if (NUMBER(MAX_PHYSMEM_BITS) != NOT_FOUND_NUMBER)
+		info->max_physmem_bits = NUMBER(MAX_PHYSMEM_BITS);
+	else
+		info->max_physmem_bits = _MAX_PHYSMEM_BITS;
+
 	info->kernel_start = SYMBOL(_stext);
 	info->section_size_bits = _SECTION_SIZE_BITS;
 
diff --git a/arch/ia64.c b/arch/ia64.c
index 6c33cc7..fb44dda 100644
--- a/arch/ia64.c
+++ b/arch/ia64.c
@@ -85,7 +85,12 @@ get_machdep_info_ia64(void)
 	}
 
 	info->section_size_bits = _SECTION_SIZE_BITS;
-	info->max_physmem_bits  = _MAX_PHYSMEM_BITS;
+
+	/* Check if we can get MAX_PHYSMEM_BITS from vmcoreinfo */
+	if (NUMBER(MAX_PHYSMEM_BITS) != NOT_FOUND_NUMBER)
+		info->max_physmem_bits = NUMBER(MAX_PHYSMEM_BITS);
+	else
+		info->max_physmem_bits  = _MAX_PHYSMEM_BITS;
 
 	return TRUE;
 }
diff --git a/arch/ppc.c b/arch/ppc.c
index 37c6a3b..ed94474 100644
--- a/arch/ppc.c
+++ b/arch/ppc.c
@@ -31,7 +31,13 @@ get_machdep_info_ppc(void)
 	unsigned long vmlist, vmap_area_list, vmalloc_start;
 
 	info->section_size_bits = _SECTION_SIZE_BITS;
-	info->max_physmem_bits  = _MAX_PHYSMEM_BITS;
+
+	/* Check if we can get MAX_PHYSMEM_BITS from vmcoreinfo */
+	if (NUMBER(MAX_PHYSMEM_BITS) != NOT_FOUND_NUMBER)
+		info->max_physmem_bits = NUMBER(MAX_PHYSMEM_BITS);
+	else
+		info->max_physmem_bits  = _MAX_PHYSMEM_BITS;
+
 	info->page_offset = __PAGE_OFFSET;
 
 	if (SYMBOL(_stext) != NOT_FOUND_SYMBOL)
diff --git a/arch/ppc64.c b/arch/ppc64.c
index 9d8f252..5e70acb 100644
--- a/arch/ppc64.c
+++ b/arch/ppc64.c
@@ -466,6 +466,13 @@ int
 set_ppc64_max_physmem_bits(void)
 {
 	long array_len = ARRAY_LENGTH(mem_section);
+
+	/* Check if we can get MAX_PHYSMEM_BITS from vmcoreinfo */
+	if (NUMBER(MAX_PHYSMEM_BITS) != NOT_FOUND_NUMBER) {
+		info->max_physmem_bits = NUMBER(MAX_PHYSMEM_BITS);
+		return TRUE;
+	}
+
 	/*
 	 * The older ppc64 kernels uses _MAX_PHYSMEM_BITS as 42 and the
 	 * newer kernels 3.7 onwards uses 46 bits.
diff --git a/arch/s390x.c b/arch/s390x.c
index bf9d58e..c4fed6f 100644
--- a/arch/s390x.c
+++ b/arch/s390x.c
@@ -63,6 +63,13 @@ int
 set_s390x_max_physmem_bits(void)
 {
 	long array_len = ARRAY_LENGTH(mem_section);
+
+	/* Check if we can get MAX_PHYSMEM_BITS from vmcoreinfo */
+	if (NUMBER(MAX_PHYSMEM_BITS) != NOT_FOUND_NUMBER) {
+		info->max_physmem_bits = NUMBER(MAX_PHYSMEM_BITS);
+		return TRUE;
+	}
+
 	/*
 	 * The older s390x kernels uses _MAX_PHYSMEM_BITS as 42 and the
 	 * newer kernels uses 46 bits.
diff --git a/arch/sparc64.c b/arch/sparc64.c
index 1cfaa85..b93a05b 100644
--- a/arch/sparc64.c
+++ b/arch/sparc64.c
@@ -25,10 +25,15 @@ int get_versiondep_info_sparc64(void)
 {
 	info->section_size_bits = _SECTION_SIZE_BITS;
 
-	if (info->kernel_version >= KERNEL_VERSION(3, 8, 13))
+	/* Check if we can get MAX_PHYSMEM_BITS from vmcoreinfo */
+	if (NUMBER(MAX_PHYSMEM_BITS) != NOT_FOUND_NUMBER)
+		info->max_physmem_bits = NUMBER(MAX_PHYSMEM_BITS);
+	else if (info->kernel_version >= KERNEL_VERSION(3, 8, 13))
 		info->max_physmem_bits = _MAX_PHYSMEM_BITS_L4;
-	else {
+	else
 		info->max_physmem_bits = _MAX_PHYSMEM_BITS_L3;
+
+	if (info->kernel_version < KERNEL_VERSION(3, 8, 13)) {
 		info->flag_vmemmap = TRUE;
 		info->vmemmap_start = VMEMMAP_BASE_SPARC64;
 		info->vmemmap_end = VMEMMAP_BASE_SPARC64 +
diff --git a/arch/x86.c b/arch/x86.c
index 3fdae93..7899329 100644
--- a/arch/x86.c
+++ b/arch/x86.c
@@ -87,6 +87,11 @@ get_machdep_info_x86(void)
 		DEBUG_MSG("PAE          : OFF\n");
 		info->max_physmem_bits  = _MAX_PHYSMEM_BITS;
 	}
+
+	/* Check if we can get MAX_PHYSMEM_BITS from vmcoreinfo */
+	if (NUMBER(MAX_PHYSMEM_BITS) != NOT_FOUND_NUMBER)
+		info->max_physmem_bits = NUMBER(MAX_PHYSMEM_BITS);
+
 	info->page_offset = __PAGE_OFFSET;
 
 	if (SYMBOL(_stext) == NOT_FOUND_SYMBOL) {
diff --git a/arch/x86_64.c b/arch/x86_64.c
index b5e2954..58b5c0b 100644
--- a/arch/x86_64.c
+++ b/arch/x86_64.c
@@ -268,10 +268,10 @@ get_machdep_info_x86_64(void)
 int
 get_versiondep_info_x86_64(void)
 {
-	/*
-	 * On linux-2.6.26, MAX_PHYSMEM_BITS is changed to 44 from 40.
-	 */
-	if (info->kernel_version < KERNEL_VERSION(2, 6, 26))
+	/* Check if we can get MAX_PHYSMEM_BITS from vmcoreinfo */
+	if (NUMBER(MAX_PHYSMEM_BITS) != NOT_FOUND_NUMBER)
+		info->max_physmem_bits = NUMBER(MAX_PHYSMEM_BITS);
+	else if (info->kernel_version < KERNEL_VERSION(2, 6, 26))
 		info->max_physmem_bits  = _MAX_PHYSMEM_BITS_ORIG;
 	else if (info->kernel_version < KERNEL_VERSION(2, 6, 31))
 		info->max_physmem_bits  = _MAX_PHYSMEM_BITS_2_6_26;
-- 
2.30.2

