Subject: [PATCH] s390x: Obtain the vmalloc_start value from high_memory for s390x arch.

BZ: https://bugzilla.redhat.com/show_bug.cgi?id=782674

From: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>

Currently the vmalloc_start address for s390x is obtained by using
vmlist.addr symbol, which is not correct. The correct vmalloc_start address
can be obtained using 'high_memory' symbol. Even crash utility is depend
on high_memory symbol to get vmalloc_start address for s390x arch.

Without this patch makedumpfile fails to translate some virtual addresses to
to physical addresses on s390x.

  [root@h4245043 makedumpfile]# ./makedumpfile -d 16 -x /root/dump.makedumpfile_problem/vmlinux /root/dump.makedumpfile_problem/vmcore /tmp/out.dump
  The kernel version is not supported.
  The created dumpfile may be incomplete.
  Checking for memory holes          : [100 %] readmem: Can't convert a physical address(3d2805c1830) to offset.
  readmem: type_addr: 0, addr:3d2805c1830, size:8
  reset_bitmap_of_free_pages: Can't get prev list_head.

  makedumpfile Failed.
  [root@h4245043 makedumpfile]#

Tested by IBM.

Beaker:
It is in the same package with "[RHEL6 Patch] support dump over vlan tagged bonding"

---
 makedumpfile-1.3.5/makedumpfile.c |    3 +++
 makedumpfile-1.3.5/makedumpfile.h |    5 +++++
 makedumpfile-1.3.5/s390x.c        |   19 ++++++-------------
 3 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/makedumpfile-1.3.5/makedumpfile.c b/makedumpfile-1.3.5/makedumpfile.c
index e0c6ed8..1dda455 100644
--- a/makedumpfile-1.3.5/makedumpfile.c
+++ b/makedumpfile-1.3.5/makedumpfile.c
@@ -2536,6 +2536,7 @@ get_symbol_info(void)
 	SYMBOL_INIT(log_end, "log_end");
 	SYMBOL_INIT(max_pfn, "max_pfn");
 	SYMBOL_INIT(modules, "modules");
+	SYMBOL_INIT(high_memory, "high_memory");
 
 	if (SYMBOL(node_data) != NOT_FOUND_SYMBOL)
 		SYMBOL_ARRAY_TYPE_INIT(node_data, "node_data");
@@ -2890,6 +2891,7 @@ generate_vmcoreinfo(void)
 	WRITE_SYMBOL("log_buf_len", log_buf_len);
 	WRITE_SYMBOL("log_end", log_end);
 	WRITE_SYMBOL("max_pfn", max_pfn);
+	WRITE_SYMBOL("high_memory", high_memory);
 
 	/*
 	 * write the structure size of 1st kernel
@@ -3148,6 +3150,7 @@ read_vmcoreinfo(void)
 	READ_SYMBOL("log_buf_len", log_buf_len);
 	READ_SYMBOL("log_end", log_end);
 	READ_SYMBOL("max_pfn", max_pfn);
+	READ_SYMBOL("high_memory", high_memory);
 
 	READ_STRUCTURE_SIZE("page", page);
 	READ_STRUCTURE_SIZE("mem_section", mem_section);
diff --git a/makedumpfile-1.3.5/makedumpfile.h b/makedumpfile-1.3.5/makedumpfile.h
index 6cc36c4..f8238b4 100644
--- a/makedumpfile-1.3.5/makedumpfile.h
+++ b/makedumpfile-1.3.5/makedumpfile.h
@@ -1071,6 +1071,11 @@ struct symbol_table {
 	 */
 
 	unsigned long long	modules;
+
+	/*
+	 * vmalloc_start address on s390x arch
+	 */
+	unsigned long long	high_memory;
 };
 
 struct size_table {
diff --git a/makedumpfile-1.3.5/s390x.c b/makedumpfile-1.3.5/s390x.c
index 5e136de..a7af982 100644
--- a/makedumpfile-1.3.5/s390x.c
+++ b/makedumpfile-1.3.5/s390x.c
@@ -60,7 +60,7 @@
 int
 get_machdep_info_s390x(void)
 {
-	unsigned long vmlist, vmalloc_start;
+	unsigned long vmalloc_start;
 	char *term_str = getenv("TERM");
 
 	if (term_str && strcmp(term_str, "dumb") == 0)
@@ -79,19 +79,13 @@ get_machdep_info_s390x(void)
 	DEBUG_MSG("kernel_start : %lx\n", info->kernel_start);
 
 	/*
-	 * For the compatibility, makedumpfile should run without the symbol
-	 * vmlist and the offset of vm_struct.addr if they are not necessary.
+	 * Obtain the vmalloc_start address from high_memory symbol.
 	 */
-	if ((SYMBOL(vmlist) == NOT_FOUND_SYMBOL)
-	    || (OFFSET(vm_struct.addr) == NOT_FOUND_STRUCTURE)) {
+	if (SYMBOL(high_memory) == NOT_FOUND_SYMBOL) {
 		return TRUE;
 	}
-	if (!readmem(VADDR, SYMBOL(vmlist), &vmlist, sizeof(vmlist))) {
-		ERRMSG("Can't get vmlist.\n");
-		return FALSE;
-	}
-	if (!readmem(VADDR, vmlist + OFFSET(vm_struct.addr), &vmalloc_start,
-	    sizeof(vmalloc_start))) {
+	if (!readmem(VADDR, SYMBOL(high_memory), &vmalloc_start,
+			sizeof(vmalloc_start))) {
 		ERRMSG("Can't get vmalloc_start.\n");
 		return FALSE;
 	}
@@ -263,8 +257,7 @@ vaddr_to_paddr_s390x(unsigned long vaddr)
 	if (paddr != NOT_PADDR)
 		return paddr;
 
-	if ((SYMBOL(vmlist) == NOT_FOUND_SYMBOL)
-	    || (OFFSET(vm_struct.addr) == NOT_FOUND_STRUCTURE)) {
+	if (SYMBOL(high_memory) == NOT_FOUND_SYMBOL) {
 		ERRMSG("Can't get necessary information for vmalloc "
 			"translation.\n");
 		return NOT_PADDR;
