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 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;