From: Mahesh Salgaonkar <mahesh(a)linux.vnet.ibm.com>
So far s390x kernel was using 42 bits for MAX_PHYSMEM_BITS that use to
support maximum of 4TB of memory. In order to support bigger systems,
the newer s390x kernel will now use 46 bits for MAX_PHYSMEM_BITS to support
maximum of 64TB of memory.
This patch enhances crash utility to auto-detect the correct value to use
for MAX_PHYSMEM_BITS by examining the mem_section array size from the vmcore
being analyzed.
Signed-off-by: Mahesh Salgaonkar <mahesh(a)linux.vnet.ibm.com>
---
defs.h | 3 ++-
s390x.c | 26 +++++++++++++++++++++++++-
2 files changed, 27 insertions(+), 2 deletions(-)
diff --git a/defs.h b/defs.h
index 381e8c2..eb992d1 100755
--- a/defs.h
+++ b/defs.h
@@ -2954,7 +2954,8 @@ struct efi_memory_desc_t {
#define TIF_SIGPENDING (2)
#define _SECTION_SIZE_BITS 28
-#define _MAX_PHYSMEM_BITS 42
+#define _MAX_PHYSMEM_BITS_OLD 42
+#define _MAX_PHYSMEM_BITS_NEW 46
#endif /* S390X */
diff --git a/s390x.c b/s390x.c
index 22e29a9..53bf272 100755
--- a/s390x.c
+++ b/s390x.c
@@ -282,6 +282,29 @@ static void s390x_process_elf_notes(void *note_ptr, unsigned long
size_note)
}
}
+static int
+set_s390x_max_physmem_bits(void)
+{
+ int array_len = get_array_length("mem_section", NULL, 0);
+ /*
+ * The older s390x kernels uses _MAX_PHYSMEM_BITS as 42 and the
+ * newer kernels uses 46 bits.
+ */
+
+ STRUCT_SIZE_INIT(mem_section, "mem_section");
+ machdep->max_physmem_bits = _MAX_PHYSMEM_BITS_OLD;
+ if ((array_len == (NR_MEM_SECTIONS() / _SECTIONS_PER_ROOT_EXTREME()))
+ || (array_len == (NR_MEM_SECTIONS() / _SECTIONS_PER_ROOT())))
+ return TRUE;
+
+ machdep->max_physmem_bits = _MAX_PHYSMEM_BITS_NEW;
+ if ((array_len == (NR_MEM_SECTIONS() / _SECTIONS_PER_ROOT_EXTREME()))
+ || (array_len == (NR_MEM_SECTIONS() / _SECTIONS_PER_ROOT())))
+ return TRUE;
+
+ return FALSE;
+}
+
/*
* Do all necessary machine-specific setup here. This is called several
* times during initialization.
@@ -350,7 +373,8 @@ s390x_init(int when)
if (!machdep->hz)
machdep->hz = HZ;
machdep->section_size_bits = _SECTION_SIZE_BITS;
- machdep->max_physmem_bits = _MAX_PHYSMEM_BITS;
+ if (!set_s390x_max_physmem_bits())
+ error(FATAL, "Can't detect max_physmem_bits.");
s390x_offsets_init();
break;