Hi, there's two backports I'd like to pull in.
The first one is addressing broken --dump-dmesg issue towards 3.11 kernel and later. The second one fixes filter issues on powerpc when CONFIG_SPARSEMEM_VMEMMAP is set.
Actually, I only plan to pull in the 2nd patch. But since 2nd patch can not be applied directly without the 1st one and I want to keep all the backport as clean as possible. So I decide to pull in the both patches.
PS. I don't think 1st patch would cause any regression
Please review these and let me know if you have any concern.
WANG Chao (2): makedumpfile: Understand >= v3.11-rc4 dmesg. makedumpfile, ppc: Support to filter dump for kernels that use CONFIG_SPARSEMEM_VMEMMAP.
...pport-to-filter-dump-for-kernels-that-use.patch | 429 +++++++++++++++++++++ ...4-makedumpfile-Understand-v3.11-rc4-dmesg.patch | 197 ++++++++++ kexec-tools.spec | 4 + 3 files changed, 630 insertions(+) create mode 100644 kexec-tools-2.0.4-makedumpfile-Support-to-filter-dump-for-kernels-that-use.patch create mode 100644 kexec-tools-2.0.4-makedumpfile-Understand-v3.11-rc4-dmesg.patch
This is a backport of commit a01b663 ("[PATCH v2] dump-dmesg: Understand
= v3.11-rc4 dmesg."):
commit a01b663 Author: Lubomir Rintel lkundrak@v3.sk Date: Fri Sep 20 15:56:49 2013 +0900
[PATCH v2] dump-dmesg: Understand >= v3.11-rc4 dmesg.
Symbol name changed with the following commit: 62e32ac printk: rename struct log to struct printk_log
Changes for v2: * Only back values for symbol names we did actually read; * either "log" or "printk_log"
makedumpfile --dump-dmesg is broken since VMCOREINFO symbol "log" has renamed to "printk_log". This patch fixes --dump-dmesg on 3.11 kernel.
Signed-off-by: WANG Chao chaowang@redhat.com --- ...4-makedumpfile-Understand-v3.11-rc4-dmesg.patch | 197 +++++++++++++++++++++ kexec-tools.spec | 2 + 2 files changed, 199 insertions(+) create mode 100644 kexec-tools-2.0.4-makedumpfile-Understand-v3.11-rc4-dmesg.patch
diff --git a/kexec-tools-2.0.4-makedumpfile-Understand-v3.11-rc4-dmesg.patch b/kexec-tools-2.0.4-makedumpfile-Understand-v3.11-rc4-dmesg.patch new file mode 100644 index 0000000..084e7d5 --- /dev/null +++ b/kexec-tools-2.0.4-makedumpfile-Understand-v3.11-rc4-dmesg.patch @@ -0,0 +1,197 @@ +From a01b663749c4b221ecd03285fa24a4b31e742004 Mon Sep 17 00:00:00 2001 +From: Lubomir Rintel lkundrak@v3.sk +Date: Fri, 20 Sep 2013 15:56:49 +0900 +Subject: [PATCH] [PATCH v2] dump-dmesg: Understand >= v3.11-rc4 dmesg. + +Symbol name changed with the following commit: +62e32ac printk: rename struct log to struct printk_log + +Changes for v2: + * Only back values for symbol names we did actually read; + either "log" or "printk_log" + +Signed-off-by: Lubomir Rintel lkundrak@v3.sk +--- + makedumpfile.c | 69 +++++++++++++++++++++++++++++++++++++++++++--------------- + makedumpfile.h | 7 +++--- + 2 files changed, 55 insertions(+), 21 deletions(-) + +diff --git a/makedumpfile-1.5.4/makedumpfile.c b/makedumpfile-1.5.4/makedumpfile.c +index e01ff50..7bbdcc2 100644 +--- a/makedumpfile-1.5.4/makedumpfile.c ++++ b/makedumpfile-1.5.4/makedumpfile.c +@@ -1389,10 +1389,23 @@ get_structure_info(void) + OFFSET_INIT(elf64_phdr.p_paddr, "elf64_phdr", "p_paddr"); + OFFSET_INIT(elf64_phdr.p_memsz, "elf64_phdr", "p_memsz"); + +- SIZE_INIT(log, "log"); +- OFFSET_INIT(log.ts_nsec, "log", "ts_nsec"); +- OFFSET_INIT(log.len, "log", "len"); +- OFFSET_INIT(log.text_len, "log", "text_len"); ++ SIZE_INIT(printk_log, "printk_log"); ++ if (SIZE(printk_log) != NOT_FOUND_STRUCTURE) { ++ /* ++ * In kernel 3.11-rc4 the log structure name was renamed ++ * to "printk_log". ++ */ ++ info->flag_use_printk_log = TRUE; ++ OFFSET_INIT(printk_log.ts_nsec, "printk_log", "ts_nsec"); ++ OFFSET_INIT(printk_log.len, "printk_log", "len"); ++ OFFSET_INIT(printk_log.text_len, "printk_log", "text_len"); ++ } else { ++ info->flag_use_printk_log = FALSE; ++ SIZE_INIT(printk_log, "log"); ++ OFFSET_INIT(printk_log.ts_nsec, "log", "ts_nsec"); ++ OFFSET_INIT(printk_log.len, "log", "len"); ++ OFFSET_INIT(printk_log.text_len, "log", "text_len"); ++ } + + return TRUE; + } +@@ -1593,7 +1606,10 @@ write_vmcoreinfo_data(void) + WRITE_STRUCTURE_SIZE("node_memblk_s", node_memblk_s); + WRITE_STRUCTURE_SIZE("nodemask_t", nodemask_t); + WRITE_STRUCTURE_SIZE("pageflags", pageflags); +- WRITE_STRUCTURE_SIZE("log", log); ++ if (info->flag_use_printk_log) ++ WRITE_STRUCTURE_SIZE("printk_log", printk_log); ++ else ++ WRITE_STRUCTURE_SIZE("log", printk_log); + + /* + * write the member offset of 1st kernel +@@ -1628,9 +1644,16 @@ write_vmcoreinfo_data(void) + WRITE_MEMBER_OFFSET("vm_struct.addr", vm_struct.addr); + WRITE_MEMBER_OFFSET("vmap_area.va_start", vmap_area.va_start); + WRITE_MEMBER_OFFSET("vmap_area.list", vmap_area.list); +- WRITE_MEMBER_OFFSET("log.ts_nsec", log.ts_nsec); +- WRITE_MEMBER_OFFSET("log.len", log.len); +- WRITE_MEMBER_OFFSET("log.text_len", log.text_len); ++ if (info->flag_use_printk_log) { ++ WRITE_MEMBER_OFFSET("printk_log.ts_nsec", printk_log.ts_nsec); ++ WRITE_MEMBER_OFFSET("printk_log.len", printk_log.len); ++ WRITE_MEMBER_OFFSET("printk_log.text_len", printk_log.text_len); ++ } else { ++ /* Compatibility with pre-3.11-rc4 */ ++ WRITE_MEMBER_OFFSET("log.ts_nsec", printk_log.ts_nsec); ++ WRITE_MEMBER_OFFSET("log.len", printk_log.len); ++ WRITE_MEMBER_OFFSET("log.text_len", printk_log.text_len); ++ } + + if (SYMBOL(node_data) != NOT_FOUND_SYMBOL) + WRITE_ARRAY_LENGTH("node_data", node_data); +@@ -1909,7 +1932,6 @@ read_vmcoreinfo(void) + READ_STRUCTURE_SIZE("node_memblk_s", node_memblk_s); + READ_STRUCTURE_SIZE("nodemask_t", nodemask_t); + READ_STRUCTURE_SIZE("pageflags", pageflags); +- READ_STRUCTURE_SIZE("log", log); + + READ_MEMBER_OFFSET("page.flags", page.flags); + READ_MEMBER_OFFSET("page._count", page._count); +@@ -1940,9 +1962,20 @@ read_vmcoreinfo(void) + READ_MEMBER_OFFSET("vm_struct.addr", vm_struct.addr); + READ_MEMBER_OFFSET("vmap_area.va_start", vmap_area.va_start); + READ_MEMBER_OFFSET("vmap_area.list", vmap_area.list); +- READ_MEMBER_OFFSET("log.ts_nsec", log.ts_nsec); +- READ_MEMBER_OFFSET("log.len", log.len); +- READ_MEMBER_OFFSET("log.text_len", log.text_len); ++ ++ READ_STRUCTURE_SIZE("printk_log", printk_log); ++ if (SIZE(printk_log) != NOT_FOUND_STRUCTURE) { ++ info->flag_use_printk_log = TRUE; ++ READ_MEMBER_OFFSET("printk_log.ts_nsec", printk_log.ts_nsec); ++ READ_MEMBER_OFFSET("printk_log.len", printk_log.len); ++ READ_MEMBER_OFFSET("printk_log.text_len", printk_log.text_len); ++ } else { ++ info->flag_use_printk_log = FALSE; ++ READ_STRUCTURE_SIZE("log", printk_log); ++ READ_MEMBER_OFFSET("log.ts_nsec", printk_log.ts_nsec); ++ READ_MEMBER_OFFSET("log.len", printk_log.len); ++ READ_MEMBER_OFFSET("log.text_len", printk_log.text_len); ++ } + + READ_ARRAY_LENGTH("node_data", node_data); + READ_ARRAY_LENGTH("pgdat_list", pgdat_list); +@@ -3710,13 +3743,13 @@ dump_log_entry(char *logptr, int fp) + ulonglong nanos; + ulong rem; + +- text_len = USHORT(logptr + OFFSET(log.text_len)); +- ts_nsec = ULONGLONG(logptr + OFFSET(log.ts_nsec)); ++ text_len = USHORT(logptr + OFFSET(printk_log.text_len)); ++ ts_nsec = ULONGLONG(logptr + OFFSET(printk_log.ts_nsec)); + + nanos = (ulonglong)ts_nsec / (ulonglong)1000000000; + rem = (ulonglong)ts_nsec % (ulonglong)1000000000; + +- msg = logptr + SIZE(log); ++ msg = logptr + SIZE(printk_log); + + sprintf(buf, "[%5lld.%06ld] ", nanos, rem/1000); + +@@ -3754,7 +3787,7 @@ log_from_idx(unsigned int idx, char *logbuf) + * the buffer. + */ + +- msglen = USHORT(logptr + OFFSET(log.len)); ++ msglen = USHORT(logptr + OFFSET(printk_log.len)); + if (!msglen) + logptr = logbuf; + +@@ -3775,9 +3808,9 @@ log_next(unsigned int idx, char *logbuf) + * return the one after that. + */ + +- msglen = USHORT(logptr + OFFSET(log.len)); ++ msglen = USHORT(logptr + OFFSET(printk_log.len)); + if (!msglen) { +- msglen = USHORT(logbuf + OFFSET(log.len)); ++ msglen = USHORT(logbuf + OFFSET(printk_log.len)); + return msglen; + } + +diff --git a/makedumpfile-1.5.4/makedumpfile.h b/makedumpfile-1.5.4/makedumpfile.h +index c504bfb..3a7e61a 100644 +--- a/makedumpfile-1.5.4/makedumpfile.h ++++ b/makedumpfile-1.5.4/makedumpfile.h +@@ -893,6 +893,7 @@ struct DumpInfo { + int flag_force; /* overwrite existing stuff */ + int flag_exclude_xen_dom;/* exclude Domain-U from xen-kdump */ + int flag_dmesg; /* dump the dmesg log out of the vmcore file */ ++ int flag_use_printk_log; /* did we read printk_log symbol name? */ + int flag_nospace; /* the flag of "No space on device" error */ + unsigned long vaddr_for_vtop; /* virtual address for debugging */ + long page_size; /* size of page */ +@@ -1176,6 +1177,7 @@ struct size_table { + long list_head; + long node_memblk_s; + long nodemask_t; ++ long printk_log; + + /* + * for Xen extraction +@@ -1198,7 +1200,6 @@ struct size_table { + long cpumask_t; + long kexec_segment; + long elf64_hdr; +- long log; + + long pageflags; + }; +@@ -1337,11 +1338,11 @@ struct offset_table { + long p_memsz; + } elf64_phdr; + +- struct log_s { ++ struct printk_log_s { + long ts_nsec; + long len; + long text_len; +- } log; ++ } printk_log; + + }; + +-- +1.8.3.1 + diff --git a/kexec-tools.spec b/kexec-tools.spec index 00eb603..6b2a673 100644 --- a/kexec-tools.spec +++ b/kexec-tools.spec @@ -89,6 +89,7 @@ Patch608: kexec-tools-2.0.4-makedumpfile-Use-divideup-to-calculate-maximum-requi Patch609: kexec-tools-2.0.4-makedumpfile-cache-Allocate-buffers-at-initialization-t.patch Patch610: kexec-tools-2.0.4-makedumpfile-cache-Reuse-entry-in-pending-list.patch Patch611: kexec-tools-2.0.4-makedumpfile-disable-mmap.patch +Patch612: kexec-tools-2.0.4-makedumpfile-Understand-v3.11-rc4-dmesg.patch
%description kexec-tools provides /sbin/kexec binary that facilitates a new @@ -131,6 +132,7 @@ tar -z -x -v -f %{SOURCE19} %patch001 -p1 %patch002 -p1 %patch003 -p1 +%patch612 -p1
tar -z -x -v -f %{SOURCE13}
This is a backport of commit bcdba92 ("[PATCH v5] Support to filter dump for kernels that use CONFIG_SPARSEMEM_VMEMMAP."):
commit bcdba92 Author: Hari Bathini hbathini@linux.vnet.ibm.com Date: Mon Nov 25 17:20:55 2013 +0900
[PATCH v5] Support to filter dump for kernels that use CONFIG_SPARSEMEM_VMEMMAP.
Makedumpfile tool fails to filter dump for kernels that are build with CONFIG_SPARSEMEM_VMEMMAP set, as it fails to do address translations for vmemmap regions that are mapped out of zone normal. This patch provides support in makedumpfile to do vmemmap to physical address translations when they are mapped outside zone normal. Some kernel symbols are needed in vmcoreinfo for this changes to be effective. The kernel patch that adds the necessary symbols to vmcoreinfo has been posted to linuxppc devel mailing list. This patch is influenced by vmemmap to physical address translation support code in crash tool. This patch has been tested successfully at all dump filtering levels on kernels with CONFIG_SPARSEMEM_VMEMMAP set/unset. Also, tested dump filtering on already filtered vmcores (re-filtering).
Changes from v4 to v5: Trimmed patch description to be compact and readable.
Changes from v3 to v4: Rebased to devel branch.
Signed-off-by: Onkar N Mahajan onmahaja@in.ibm.com Signed-off-by: Hari Bathini hbathini@linux.vnet.ibm.com
On PPC platform, filter facility is broken since we use CONFIG_SPARSEMEM_VMEMMAP. This patch fixes this issue but also needs kernel counterpart fix to get makedumpfile filter working.
Signed-off-by: WANG Chao chaowang@redhat.com --- ...pport-to-filter-dump-for-kernels-that-use.patch | 429 +++++++++++++++++++++ kexec-tools.spec | 2 + 2 files changed, 431 insertions(+) create mode 100644 kexec-tools-2.0.4-makedumpfile-Support-to-filter-dump-for-kernels-that-use.patch
diff --git a/kexec-tools-2.0.4-makedumpfile-Support-to-filter-dump-for-kernels-that-use.patch b/kexec-tools-2.0.4-makedumpfile-Support-to-filter-dump-for-kernels-that-use.patch new file mode 100644 index 0000000..299f1a8 --- /dev/null +++ b/kexec-tools-2.0.4-makedumpfile-Support-to-filter-dump-for-kernels-that-use.patch @@ -0,0 +1,429 @@ +From bcdba922182def3dac288ca201e77e7738a1e4ab Mon Sep 17 00:00:00 2001 +From: Hari Bathini hbathini@linux.vnet.ibm.com +Date: Mon, 25 Nov 2013 17:20:55 +0900 +Subject: [PATCH] [PATCH v5] Support to filter dump for kernels that use + CONFIG_SPARSEMEM_VMEMMAP. + +Makedumpfile tool fails to filter dump for kernels that are build with +CONFIG_SPARSEMEM_VMEMMAP set, as it fails to do address translations +for vmemmap regions that are mapped out of zone normal. This patch +provides support in makedumpfile to do vmemmap to physical address +translations when they are mapped outside zone normal. Some kernel +symbols are needed in vmcoreinfo for this changes to be effective. +The kernel patch that adds the necessary symbols to vmcoreinfo has +been posted to linuxppc devel mailing list. This patch is influenced +by vmemmap to physical address translation support code in crash tool. +This patch has been tested successfully at all dump filtering levels +on kernels with CONFIG_SPARSEMEM_VMEMMAP set/unset. Also, tested dump +filtering on already filtered vmcores (re-filtering). + +Changes from v4 to v5: +Trimmed patch description to be compact and readable. + +Changes from v3 to v4: +Rebased to devel branch. + +Signed-off-by: Onkar N Mahajan onmahaja@in.ibm.com +Signed-off-by: Hari Bathini hbathini@linux.vnet.ibm.com +--- + arch/ppc64.c | 175 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- + makedumpfile.c | 39 +++++++++++++ + makedumpfile.h | 37 ++++++++++++ + 3 files changed, 247 insertions(+), 4 deletions(-) + +diff --git a/makedumpfile-1.5.4/arch/ppc64.c b/makedumpfile-1.5.4/arch/ppc64.c +index 85144f6..09c0eb3 100644 +--- a/makedumpfile-1.5.4/arch/ppc64.c ++++ b/makedumpfile-1.5.4/arch/ppc64.c +@@ -24,6 +24,154 @@ + #include "../elf_info.h" + #include "../makedumpfile.h" + ++/* ++ * This function traverses vmemmap list to get the count of vmemmap regions ++ * and populates the regions' info in info->vmemmap_list[] ++ */ ++static int ++get_vmemmap_list_info(ulong head) ++{ ++ int i, cnt; ++ long backing_size, virt_addr_offset, phys_offset, list_offset; ++ ulong curr, next; ++ char *vmemmap_buf = NULL; ++ ++ backing_size = SIZE(vmemmap_backing); ++ virt_addr_offset = OFFSET(vmemmap_backing.virt_addr); ++ phys_offset = OFFSET(vmemmap_backing.phys); ++ list_offset = OFFSET(vmemmap_backing.list); ++ info->vmemmap_list = NULL; ++ ++ /* ++ * Get list count by traversing the vmemmap list ++ */ ++ cnt = 0; ++ curr = head; ++ next = 0; ++ do { ++ if (!readmem(VADDR, (curr + list_offset), &next, ++ sizeof(next))) { ++ ERRMSG("Can't get vmemmap region addresses\n"); ++ goto err; ++ } ++ curr = next; ++ cnt++; ++ } while ((next != 0) && (next != head)); ++ ++ /* ++ * Using temporary buffer to save vmemmap region information ++ */ ++ vmemmap_buf = calloc(1, backing_size); ++ if (vmemmap_buf == NULL) { ++ ERRMSG("Can't allocate memory for vmemmap_buf. %s\n", ++ strerror(errno)); ++ goto err; ++ } ++ ++ info->vmemmap_list = calloc(1, cnt * sizeof(struct ppc64_vmemmap)); ++ if (info->vmemmap_list == NULL) { ++ ERRMSG("Can't allocate memory for vmemmap_list. %s\n", ++ strerror(errno)); ++ goto err; ++ } ++ ++ curr = head; ++ for (i = 0; i < cnt; i++) { ++ if (!readmem(VADDR, curr, vmemmap_buf, backing_size)) { ++ ERRMSG("Can't get vmemmap region info\n"); ++ goto err; ++ } ++ ++ info->vmemmap_list[i].phys = ULONG(vmemmap_buf + phys_offset); ++ info->vmemmap_list[i].virt = ULONG(vmemmap_buf + ++ virt_addr_offset); ++ curr = ULONG(vmemmap_buf + list_offset); ++ ++ if (info->vmemmap_list[i].virt < info->vmemmap_start) ++ info->vmemmap_start = info->vmemmap_list[i].virt; ++ ++ if ((info->vmemmap_list[i].virt + info->vmemmap_psize) > ++ info->vmemmap_end) ++ info->vmemmap_end = (info->vmemmap_list[i].virt + ++ info->vmemmap_psize); ++ } ++ ++ free(vmemmap_buf); ++ return cnt; ++err: ++ free(vmemmap_buf); ++ free(info->vmemmap_list); ++ return 0; ++} ++ ++/* ++ * Verify that the kernel has made the vmemmap list available, ++ * and if so, stash the relevant data required to make vtop ++ * translations. ++ */ ++static int ++ppc64_vmemmap_init(void) ++{ ++ int psize, shift; ++ ulong head; ++ ++ if ((SYMBOL(vmemmap_list) == NOT_FOUND_SYMBOL) ++ || (SYMBOL(mmu_psize_defs) == NOT_FOUND_SYMBOL) ++ || (SYMBOL(mmu_vmemmap_psize) == NOT_FOUND_SYMBOL) ++ || (SIZE(vmemmap_backing) == NOT_FOUND_STRUCTURE) ++ || (SIZE(mmu_psize_def) == NOT_FOUND_STRUCTURE) ++ || (OFFSET(mmu_psize_def.shift) == NOT_FOUND_STRUCTURE) ++ || (OFFSET(vmemmap_backing.phys) == NOT_FOUND_STRUCTURE) ++ || (OFFSET(vmemmap_backing.virt_addr) == NOT_FOUND_STRUCTURE) ++ || (OFFSET(vmemmap_backing.list) == NOT_FOUND_STRUCTURE)) ++ return FALSE; ++ ++ if (!readmem(VADDR, SYMBOL(mmu_vmemmap_psize), &psize, sizeof(int))) ++ return FALSE; ++ ++ if (!readmem(VADDR, SYMBOL(mmu_psize_defs) + ++ (SIZE(mmu_psize_def) * psize) + ++ OFFSET(mmu_psize_def.shift), &shift, sizeof(int))) ++ return FALSE; ++ info->vmemmap_psize = 1 << shift; ++ ++ if (!readmem(VADDR, SYMBOL(vmemmap_list), &head, sizeof(unsigned long))) ++ return FALSE; ++ ++ /* ++ * Get vmemmap list count and populate vmemmap regions info ++ */ ++ info->vmemmap_cnt = get_vmemmap_list_info(head); ++ if (info->vmemmap_cnt == 0) ++ return FALSE; ++ ++ info->flag_vmemmap = TRUE; ++ return TRUE; ++} ++ ++/* ++ * If the vmemmap address translation information is stored in the kernel, ++ * make the translation. ++ */ ++static unsigned long long ++ppc64_vmemmap_to_phys(unsigned long vaddr) ++{ ++ int i; ++ ulong offset; ++ unsigned long long paddr = NOT_PADDR; ++ ++ for (i = 0; i < info->vmemmap_cnt; i++) { ++ if ((vaddr >= info->vmemmap_list[i].virt) && (vaddr < ++ (info->vmemmap_list[i].virt + info->vmemmap_psize))) { ++ offset = vaddr - info->vmemmap_list[i].virt; ++ paddr = info->vmemmap_list[i].phys + offset; ++ break; ++ } ++ } ++ ++ return paddr; ++} ++ + int + set_ppc64_max_physmem_bits(void) + { +@@ -103,6 +251,16 @@ get_machdep_info_ppc64(void) + info->vmalloc_start = vmalloc_start; + DEBUG_MSG("vmalloc_start: %lx\n", vmalloc_start); + ++ if (SYMBOL(vmemmap_list) != NOT_FOUND_SYMBOL) { ++ info->vmemmap_start = VMEMMAP_REGION_ID << REGION_SHIFT; ++ info->vmemmap_end = info->vmemmap_start; ++ if (ppc64_vmemmap_init() == FALSE) { ++ ERRMSG("Can't get vmemmap list info.\n"); ++ return FALSE; ++ } ++ DEBUG_MSG("vmemmap_start: %lx\n", info->vmemmap_start); ++ } ++ + return TRUE; + } + +@@ -121,14 +279,23 @@ vaddr_to_paddr_ppc64(unsigned long vaddr) + if (paddr != NOT_PADDR) + return paddr; + +- if ((SYMBOL(vmlist) == NOT_FOUND_SYMBOL) +- || (OFFSET(vm_struct.addr) == NOT_FOUND_STRUCTURE)) { +- ERRMSG("Can't get necessary information for vmalloc translation.\n"); +- return NOT_PADDR; ++ if ((SYMBOL(vmap_area_list) == NOT_FOUND_SYMBOL) ++ || (OFFSET(vmap_area.va_start) == NOT_FOUND_STRUCTURE) ++ || (OFFSET(vmap_area.list) == NOT_FOUND_STRUCTURE)) { ++ if ((SYMBOL(vmlist) == NOT_FOUND_SYMBOL) ++ || (OFFSET(vm_struct.addr) == NOT_FOUND_STRUCTURE)) { ++ ERRMSG("Can't get info for vmalloc translation.\n"); ++ return NOT_PADDR; ++ } + } + if (!is_vmalloc_addr_ppc64(vaddr)) + return (vaddr - info->kernel_start); + ++ if ((info->flag_vmemmap) ++ && (vaddr >= info->vmemmap_start)) { ++ return ppc64_vmemmap_to_phys(vaddr); ++ } ++ + /* + * TODO: Support vmalloc translation. + */ +diff --git a/makedumpfile-1.5.4/makedumpfile.c b/makedumpfile-1.5.4/makedumpfile.c +index 3746cf6..0c68f32 100644 +--- a/makedumpfile-1.5.4/makedumpfile.c ++++ b/makedumpfile-1.5.4/makedumpfile.c +@@ -1107,6 +1107,10 @@ get_symbol_info(void) + SYMBOL_ARRAY_LENGTH_INIT(node_remap_start_pfn, + "node_remap_start_pfn"); + ++ SYMBOL_INIT(vmemmap_list, "vmemmap_list"); ++ SYMBOL_INIT(mmu_psize_defs, "mmu_psize_defs"); ++ SYMBOL_INIT(mmu_vmemmap_psize, "mmu_vmemmap_psize"); ++ + return TRUE; + } + +@@ -1417,6 +1421,20 @@ get_structure_info(void) + OFFSET_INIT(printk_log.text_len, "log", "text_len"); + } + ++ /* ++ * Get offsets of the vmemmap_backing's members. ++ */ ++ SIZE_INIT(vmemmap_backing, "vmemmap_backing"); ++ OFFSET_INIT(vmemmap_backing.phys, "vmemmap_backing", "phys"); ++ OFFSET_INIT(vmemmap_backing.virt_addr, "vmemmap_backing", "virt_addr"); ++ OFFSET_INIT(vmemmap_backing.list, "vmemmap_backing", "list"); ++ ++ /* ++ * Get offsets of the mmu_psize_def's members. ++ */ ++ SIZE_INIT(mmu_psize_def, "mmu_psize_def"); ++ OFFSET_INIT(mmu_psize_def.shift, "mmu_psize_def", "shift"); ++ + return TRUE; + } + +@@ -1603,6 +1621,9 @@ write_vmcoreinfo_data(void) + WRITE_SYMBOL("node_remap_start_vaddr", node_remap_start_vaddr); + WRITE_SYMBOL("node_remap_end_vaddr", node_remap_end_vaddr); + WRITE_SYMBOL("node_remap_start_pfn", node_remap_start_pfn); ++ WRITE_SYMBOL("vmemmap_list", vmemmap_list); ++ WRITE_SYMBOL("mmu_psize_defs", mmu_psize_defs); ++ WRITE_SYMBOL("mmu_vmemmap_psize", mmu_vmemmap_psize); + + /* + * write the structure size of 1st kernel +@@ -1620,6 +1641,8 @@ write_vmcoreinfo_data(void) + WRITE_STRUCTURE_SIZE("printk_log", printk_log); + else + WRITE_STRUCTURE_SIZE("log", printk_log); ++ WRITE_STRUCTURE_SIZE("vmemmap_backing", vmemmap_backing); ++ WRITE_STRUCTURE_SIZE("mmu_psize_def", mmu_psize_def); + + /* + * write the member offset of 1st kernel +@@ -1664,6 +1687,11 @@ write_vmcoreinfo_data(void) + WRITE_MEMBER_OFFSET("log.len", printk_log.len); + WRITE_MEMBER_OFFSET("log.text_len", printk_log.text_len); + } ++ WRITE_MEMBER_OFFSET("vmemmap_backing.phys", vmemmap_backing.phys); ++ WRITE_MEMBER_OFFSET("vmemmap_backing.virt_addr", ++ vmemmap_backing.virt_addr); ++ WRITE_MEMBER_OFFSET("vmemmap_backing.list", vmemmap_backing.list); ++ WRITE_MEMBER_OFFSET("mmu_psize_def.shift", mmu_psize_def.shift); + + if (SYMBOL(node_data) != NOT_FOUND_SYMBOL) + WRITE_ARRAY_LENGTH("node_data", node_data); +@@ -1932,6 +1960,9 @@ read_vmcoreinfo(void) + READ_SYMBOL("node_remap_start_vaddr", node_remap_start_vaddr); + READ_SYMBOL("node_remap_end_vaddr", node_remap_end_vaddr); + READ_SYMBOL("node_remap_start_pfn", node_remap_start_pfn); ++ READ_SYMBOL("vmemmap_list", vmemmap_list); ++ READ_SYMBOL("mmu_psize_defs", mmu_psize_defs); ++ READ_SYMBOL("mmu_vmemmap_psize", mmu_vmemmap_psize); + + READ_STRUCTURE_SIZE("page", page); + READ_STRUCTURE_SIZE("mem_section", mem_section); +@@ -1942,6 +1973,9 @@ read_vmcoreinfo(void) + READ_STRUCTURE_SIZE("node_memblk_s", node_memblk_s); + READ_STRUCTURE_SIZE("nodemask_t", nodemask_t); + READ_STRUCTURE_SIZE("pageflags", pageflags); ++ READ_STRUCTURE_SIZE("vmemmap_backing", vmemmap_backing); ++ READ_STRUCTURE_SIZE("mmu_psize_def", mmu_psize_def); ++ + + READ_MEMBER_OFFSET("page.flags", page.flags); + READ_MEMBER_OFFSET("page._count", page._count); +@@ -1972,6 +2006,11 @@ read_vmcoreinfo(void) + READ_MEMBER_OFFSET("vm_struct.addr", vm_struct.addr); + READ_MEMBER_OFFSET("vmap_area.va_start", vmap_area.va_start); + READ_MEMBER_OFFSET("vmap_area.list", vmap_area.list); ++ READ_MEMBER_OFFSET("vmemmap_backing.phys", vmemmap_backing.phys); ++ READ_MEMBER_OFFSET("vmemmap_backing.virt_addr", ++ vmemmap_backing.virt_addr); ++ READ_MEMBER_OFFSET("vmemmap_backing.list", vmemmap_backing.list); ++ READ_MEMBER_OFFSET("mmu_psize_def.shift", mmu_psize_def.shift); + + READ_STRUCTURE_SIZE("printk_log", printk_log); + if (SIZE(printk_log) != NOT_FOUND_STRUCTURE) { +diff --git a/makedumpfile-1.5.4/makedumpfile.h b/makedumpfile-1.5.4/makedumpfile.h +index 3a7e61a..517e16e 100644 +--- a/makedumpfile-1.5.4/makedumpfile.h ++++ b/makedumpfile-1.5.4/makedumpfile.h +@@ -576,6 +576,8 @@ do { \ + #define _SECTION_SIZE_BITS (24) + #define _MAX_PHYSMEM_BITS_ORIG (44) + #define _MAX_PHYSMEM_BITS_3_7 (46) ++#define REGION_SHIFT (60UL) ++#define VMEMMAP_REGION_ID (0xfUL) + #endif + + #ifdef __powerpc32__ +@@ -862,6 +864,11 @@ struct splitting_info { + unsigned long size_eraseinfo; + } splitting_info_t; + ++struct ppc64_vmemmap { ++ unsigned long phys; ++ unsigned long virt; ++}; ++ + struct DumpInfo { + int32_t kernel_version; /* version of first kernel*/ + struct timeval timestamp; +@@ -895,6 +902,7 @@ struct DumpInfo { + int flag_dmesg; /* dump the dmesg log out of the vmcore file */ + int flag_use_printk_log; /* did we read printk_log symbol name? */ + int flag_nospace; /* the flag of "No space on device" error */ ++ int flag_vmemmap; /* kernel supports vmemmap address space */ + unsigned long vaddr_for_vtop; /* virtual address for debugging */ + long page_size; /* size of page */ + long page_shift; +@@ -909,6 +917,9 @@ struct DumpInfo { + unsigned long vmalloc_end; + unsigned long vmemmap_start; + unsigned long vmemmap_end; ++ int vmemmap_psize; ++ int vmemmap_cnt; ++ struct ppc64_vmemmap *vmemmap_list; + + /* + * Filter config file containing filter commands to filter out kernel +@@ -1166,6 +1177,13 @@ struct symbol_table { + unsigned long long __per_cpu_load; + unsigned long long cpu_online_mask; + unsigned long long kexec_crash_image; ++ ++ /* ++ * vmemmap symbols on ppc64 arch ++ */ ++ unsigned long long vmemmap_list; ++ unsigned long long mmu_vmemmap_psize; ++ unsigned long long mmu_psize_defs; + }; + + struct size_table { +@@ -1201,6 +1219,12 @@ struct size_table { + long kexec_segment; + long elf64_hdr; + ++ /* ++ * vmemmap symbols on ppc64 arch ++ */ ++ long vmemmap_backing; ++ long mmu_psize_def; ++ + long pageflags; + }; + +@@ -1344,6 +1368,19 @@ struct offset_table { + long text_len; + } printk_log; + ++ /* ++ * vmemmap symbols on ppc64 arch ++ */ ++ struct mmu_psize_def { ++ long shift; ++ } mmu_psize_def; ++ ++ struct vmemmap_backing { ++ long phys; ++ long virt_addr; ++ long list; ++ } vmemmap_backing; ++ + }; + + /* +-- +1.8.3.1 + diff --git a/kexec-tools.spec b/kexec-tools.spec index 6b2a673..12bfc14 100644 --- a/kexec-tools.spec +++ b/kexec-tools.spec @@ -69,6 +69,7 @@ Patch101: kexec-tools-2.0.4-kdump-x86-Process-multiple-Crash-kernel-in-proc-iome # Patches 301 through 400 are meant for ppc64 kexec-tools enablement # Patch301: kexec-tools-2.0.4-makedumpfile-Add-vmap_area_list-definition-for-ppc-ppc64.patch +Patch302: kexec-tools-2.0.4-makedumpfile-Support-to-filter-dump-for-kernels-that-use.patch
# # Patches 401 through 500 are meant for s390 kexec-tools enablement @@ -133,6 +134,7 @@ tar -z -x -v -f %{SOURCE19} %patch002 -p1 %patch003 -p1 %patch612 -p1 +%patch302 -p1
tar -z -x -v -f %{SOURCE13}
On 11/27/2013 11:08 AM, WANG Chao wrote:
This is a backport of commit bcdba92 ("[PATCH v5] Support to filter dump for kernels that use CONFIG_SPARSEMEM_VMEMMAP."):
commit bcdba92 Author: Hari Bathini hbathini@linux.vnet.ibm.com Date: Mon Nov 25 17:20:55 2013 +0900
[PATCH v5] Support to filter dump for kernels that use CONFIG_SPARSEMEM_VMEMMAP. Makedumpfile tool fails to filter dump for kernels that are build with CONFIG_SPARSEMEM_VMEMMAP set, as it fails to do address translations for vmemmap regions that are mapped out of zone normal. This patch provides support in makedumpfile to do vmemmap to physical address translations when they are mapped outside zone normal. Some kernel symbols are needed in vmcoreinfo for this changes to be effective. The kernel patch that adds the necessary symbols to vmcoreinfo has been posted to linuxppc devel mailing list. This patch is influenced by vmemmap to physical address translation support code in crash tool. This patch has been tested successfully at all dump filtering levels on kernels with CONFIG_SPARSEMEM_VMEMMAP set/unset. Also, tested dump filtering on already filtered vmcores (re-filtering). Changes from v4 to v5: Trimmed patch description to be compact and readable. Changes from v3 to v4: Rebased to devel branch. Signed-off-by: Onkar N Mahajan <onmahaja@in.ibm.com> Signed-off-by: Hari Bathini <hbathini@linux.vnet.ibm.com>
On PPC platform, filter facility is broken since we use CONFIG_SPARSEMEM_VMEMMAP. This patch fixes this issue but also needs kernel counterpart fix to get makedumpfile filter working.
Signed-off-by: WANG Chao chaowang@redhat.com
...pport-to-filter-dump-for-kernels-that-use.patch | 429 +++++++++++++++++++++ kexec-tools.spec | 2 + 2 files changed, 431 insertions(+) create mode 100644 kexec-tools-2.0.4-makedumpfile-Support-to-filter-dump-for-kernels-that-use.patch
diff --git a/kexec-tools-2.0.4-makedumpfile-Support-to-filter-dump-for-kernels-that-use.patch b/kexec-tools-2.0.4-makedumpfile-Support-to-filter-dump-for-kernels-that-use.patch new file mode 100644 index 0000000..299f1a8 --- /dev/null +++ b/kexec-tools-2.0.4-makedumpfile-Support-to-filter-dump-for-kernels-that-use.patch @@ -0,0 +1,429 @@ +From bcdba922182def3dac288ca201e77e7738a1e4ab Mon Sep 17 00:00:00 2001 +From: Hari Bathini hbathini@linux.vnet.ibm.com +Date: Mon, 25 Nov 2013 17:20:55 +0900 +Subject: [PATCH] [PATCH v5] Support to filter dump for kernels that use
- CONFIG_SPARSEMEM_VMEMMAP.
+Makedumpfile tool fails to filter dump for kernels that are build with +CONFIG_SPARSEMEM_VMEMMAP set, as it fails to do address translations +for vmemmap regions that are mapped out of zone normal. This patch +provides support in makedumpfile to do vmemmap to physical address +translations when they are mapped outside zone normal. Some kernel +symbols are needed in vmcoreinfo for this changes to be effective. +The kernel patch that adds the necessary symbols to vmcoreinfo has +been posted to linuxppc devel mailing list. This patch is influenced +by vmemmap to physical address translation support code in crash tool. +This patch has been tested successfully at all dump filtering levels +on kernels with CONFIG_SPARSEMEM_VMEMMAP set/unset. Also, tested dump +filtering on already filtered vmcores (re-filtering).
+Changes from v4 to v5: +Trimmed patch description to be compact and readable.
+Changes from v3 to v4: +Rebased to devel branch.
+Signed-off-by: Onkar N Mahajan onmahaja@in.ibm.com +Signed-off-by: Hari Bathini hbathini@linux.vnet.ibm.com +---
- arch/ppc64.c | 175 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
- makedumpfile.c | 39 +++++++++++++
- makedumpfile.h | 37 ++++++++++++
- 3 files changed, 247 insertions(+), 4 deletions(-)
Acked-by: Steve Bestsbest@redhat.com
On Thu, Nov 28, 2013 at 12:08:51AM +0800, WANG Chao wrote:
Hi, there's two backports I'd like to pull in.
The first one is addressing broken --dump-dmesg issue towards 3.11 kernel and later. The second one fixes filter issues on powerpc when CONFIG_SPARSEMEM_VMEMMAP is set.
Actually, I only plan to pull in the 2nd patch. But since 2nd patch can not be applied directly without the 1st one and I want to keep all the backport as clean as possible. So I decide to pull in the both patches.
PS. I don't think 1st patch would cause any regression
Please review these and let me know if you have any concern.
Hi Chao,
Looks good to me.
Acked-by: Vivek Goyal vgoyal@redhat.com
Vivek
WANG Chao (2): makedumpfile: Understand >= v3.11-rc4 dmesg. makedumpfile, ppc: Support to filter dump for kernels that use CONFIG_SPARSEMEM_VMEMMAP.
...pport-to-filter-dump-for-kernels-that-use.patch | 429 +++++++++++++++++++++ ...4-makedumpfile-Understand-v3.11-rc4-dmesg.patch | 197 ++++++++++ kexec-tools.spec | 4 + 3 files changed, 630 insertions(+) create mode 100644 kexec-tools-2.0.4-makedumpfile-Support-to-filter-dump-for-kernels-that-use.patch create mode 100644 kexec-tools-2.0.4-makedumpfile-Understand-v3.11-rc4-dmesg.patch
-- 1.8.3.1