On 04/11/17 at 06:59am, Pratyush Anand wrote:
Resolves: bz1440587
https://bugzilla.redhat.com/show_bug.cgi?id=1440587
Current fc25 kernel version is v4.10.
4.9+ kernel has phys_base virtual address in vmcoreinfo rather it's
symbol address. Therefore, backport makedumpfile patch "Adapt code to
get value of phys_base"
While doing that, also backport "kexec-tools/x86:
get_kernel_vaddr_and_size off-by-one fix" to fix following with kexec
-p:
"Can't find kernel text map area from kcore"
v4.11 kernel will have another fix for kcore ( 464920104bf7 /proc/kcore:
update physical address for kcore ram and text)which allows only valid
physical address to pass in PT_LOAD.With that fix in kernel, kexec-tools
may not work always until we backport "build_mem_phdrs(): check if
p_paddr is invalid" from kexec-tools. Since there does not seem any side
effect of taking that kexec-tools commit even for v4.10 because
"phdr->p_paddr != (unsigned long long)-1" will always be TRUE for them,
therefore we take that kexec-tools patch as well.
Signed-off-by: Pratyush Anand <panand(a)redhat.com>
ACK again, thanks.
> ---
> Build info:
https://koji.fedoraproject.org/koji/taskinfo?taskID=18908776
> FC25 crash does not like the vmcore, however crash/master worked fine.
> Probably, FC25 crash will need to backport atleast following commit:
> commit 24a696228c56fd4354d29abe05b206373e0c8bfb
>
> Fix for Linux 4.10 commit 7fd8329ba502ef76dd91db561c7aed696b2c7720
> "taint/module: Clean up global and module taint flags handling".
>
> v1 -> v2:
> v1 missed to apply Patchc611 in spec file. Since that patch does
> not affect kernel < v4.11, so it had worked. However, v2 fixes that as we
> talk about it in commit log.
>
>
> ...ild_mem_phdrs-check-if-p_paddr-is-invalid.patch | 43 +++++++
> ...-x86-get_kernel_vaddr_and_size-off-by-one.patch | 43 +++++++
> ...file-Adapt-code-to-get-value-of-phys_base.patch | 126 +++++++++++++++++++++
> kexec-tools.spec | 6 +
> 4 files changed, 218 insertions(+)
> create mode 100644
kexec-tools-2.0.13-build_mem_phdrs-check-if-p_paddr-is-invalid.patch
> create mode 100644
kexec-tools-2.0.13-kexec-tools-x86-get_kernel_vaddr_and_size-off-by-one.patch
> create mode 100644
kexec-tools-2.0.13-makedumpfile-Adapt-code-to-get-value-of-phys_base.patch
>
> diff --git a/kexec-tools-2.0.13-build_mem_phdrs-check-if-p_paddr-is-invalid.patch
b/kexec-tools-2.0.13-build_mem_phdrs-check-if-p_paddr-is-invalid.patch
> new file mode 100644
> index 000000000000..4d4f34361b45
> --- /dev/null
> +++ b/kexec-tools-2.0.13-build_mem_phdrs-check-if-p_paddr-is-invalid.patch
> @@ -0,0 +1,43 @@
> +From ed15ba1b9977e506637ff1697821d97127b2c919 Mon Sep 17 00:00:00 2001
> +Message-Id:
<ed15ba1b9977e506637ff1697821d97127b2c919.1491794671.git.panand(a)redhat.com>
> +From: Pratyush Anand <panand(a)redhat.com>
> +Date: Wed, 1 Mar 2017 11:19:42 +0530
> +Subject: [PATCH] build_mem_phdrs(): check if p_paddr is invalid
> +
> +Currently, all the p_paddr of PT_LOAD headers are assigned to 0, which
> +is not correct and could be misleading, since 0 is a valid physical
> +address.
> +
> +Upstream kernel commit "464920104bf7 /proc/kcore: update physical
> +address for kcore ram and text" fixed it and now invalid PT_LOAD is
> +assigned as -1.
> +
> +kexec/arch/i386/crashdump-x86.c:get_kernel_vaddr_and_size() uses kcore
> +interface and so calls build_mem_phdrs() for kcore PT_LOAD headers.
> +
> +This patch fixes build_mem_phdrs() to check if p_paddr is invalid.
> +
> +Signed-off-by: Pratyush Anand <panand(a)redhat.com>
> +Acked-by: Dave Young <dyoung(a)redhat.com>
> +Signed-off-by: Simon Horman <horms(a)verge.net.au>
> +---
> + kexec/kexec-elf.c | 3 ++-
> + 1 file changed, 2 insertions(+), 1 deletion(-)
> +
> +diff --git a/kexec/kexec-elf.c b/kexec/kexec-elf.c
> +index 1d6320a2f0e6..be60bbd48486 100644
> +--- a/kexec/kexec-elf.c
> ++++ b/kexec/kexec-elf.c
> +@@ -432,7 +432,8 @@ static int build_mem_phdrs(const char *buf, off_t len, struct
mem_ehdr *ehdr,
> + }
> + return -1;
> + }
> +- if ((phdr->p_paddr + phdr->p_memsz) < phdr->p_paddr) {
> ++ if (phdr->p_paddr != (unsigned long long)-1 &&
> ++ (phdr->p_paddr + phdr->p_memsz) < phdr->p_paddr) {
> + /* The memory address wraps */
> + if (probe_debug) {
> + fprintf(stderr, "ELF address wrap around\n");
> +--
> +2.9.3
> +
> diff --git
a/kexec-tools-2.0.13-kexec-tools-x86-get_kernel_vaddr_and_size-off-by-one.patch
b/kexec-tools-2.0.13-kexec-tools-x86-get_kernel_vaddr_and_size-off-by-one.patch
> new file mode 100644
> index 000000000000..c707c8ec0e07
> --- /dev/null
> +++ b/kexec-tools-2.0.13-kexec-tools-x86-get_kernel_vaddr_and_size-off-by-one.patch
> @@ -0,0 +1,43 @@
> +From dbb99d938810b60035122a1bcc68c4d585a0e57f Mon Sep 17 00:00:00 2001
> +Message-Id:
<dbb99d938810b60035122a1bcc68c4d585a0e57f.1491799333.git.panand(a)redhat.com>
> +From: Dave Young <dyoung(a)redhat.com>
> +Date: Thu, 8 Dec 2016 10:52:22 +0800
> +Subject: [PATCH] kexec-tools/x86: get_kernel_vaddr_and_size off-by-one fix
> +
> +I got below error while tesing kexec -p:
> +"Can't find kernel text map area from kcore"
> +
> +The case is the pt_load start addr was same as stext_sym. The checking
> +code should really be saddr <= stext_sym so that the right pt_load area
> +includes stext_sym can be matched.
> +
> +This was not reported by people previously because it will fail over to
> +use hardcode X86_64__START_KERNEL_map to match the pt_load areas again
> +in later code and it sometimes succeeds because of kernel address
> +randomization.
> +
> +With this change according to my test stext_sym checking can garantee
> +falling into right pt_load area if we get correct stext_sym.
> +
> +Signed-off-by: Dave Young <dyoung(a)redhat.com>
> +Signed-off-by: Simon Horman <horms(a)verge.net.au>
> +---
> + kexec/arch/i386/crashdump-x86.c | 2 +-
> + 1 file changed, 1 insertion(+), 1 deletion(-)
> +
> +diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c
> +index ab833d416320..88aeee33572b 100644
> +--- a/kexec/arch/i386/crashdump-x86.c
> ++++ b/kexec/arch/i386/crashdump-x86.c
> +@@ -205,7 +205,7 @@ static int get_kernel_vaddr_and_size(struct kexec_info
*UNUSED(info),
> + unsigned long long size;
> +
> + /* Look for kernel text mapping header. */
> +- if (saddr < stext_sym && eaddr > stext_sym) {
> ++ if (saddr <= stext_sym && eaddr > stext_sym) {
> + saddr = _ALIGN_DOWN(saddr, X86_64_KERN_VADDR_ALIGN);
> + elf_info->kern_vaddr_start = saddr;
> + size = eaddr - saddr;
> +--
> +2.9.3
> +
> diff --git
a/kexec-tools-2.0.13-makedumpfile-Adapt-code-to-get-value-of-phys_base.patch
b/kexec-tools-2.0.13-makedumpfile-Adapt-code-to-get-value-of-phys_base.patch
> new file mode 100644
> index 000000000000..c0b16655dc4d
> --- /dev/null
> +++ b/kexec-tools-2.0.13-makedumpfile-Adapt-code-to-get-value-of-phys_base.patch
> @@ -0,0 +1,126 @@
> +From acdbb1d6aee9207ccdea697326574e8d6142cd73 Mon Sep 17 00:00:00 2001
> +Message-Id:
<acdbb1d6aee9207ccdea697326574e8d6142cd73.1491806706.git.panand(a)redhat.com>
> +From: Baoquan He <bhe(a)redhat.com>
> +Date: Thu, 10 Nov 2016 15:30:57 +0900
> +Subject: [PATCH] [PATCH v2 1/2] Adapt code to get value of phys_base
> +
> +* Required for kernel 4.9
> +
> +Kernel code only exports virtual address of phys_base now and it's helpless
> +for Crash and Makedumpfile. Below patch which changes code to export value
> +of phys_base has been posted to upstream. So adapt code to get it.
> +
> +kexec: Change to export the value of phys_base instead of symbol address
> +marc.info/?l=linux-kernel&m=147856863629624&w=2
> +
> +Signed-off-by: Baoquan He <bhe(a)redhat.com>
> +---
> + arch/x86_64.c | 12 +++++-------
> + makedumpfile.c | 5 ++---
> + makedumpfile.h | 2 +-
> + 3 files changed, 8 insertions(+), 11 deletions(-)
> +
> +diff --git a/makedumpfile-1.6.0/arch/x86_64.c b/makedumpfile-1.6.0/arch/x86_64.c
> +index 3ef33ae4ef2d..010ea10e6fa8 100644
> +--- a/makedumpfile-1.6.0/arch/x86_64.c
> ++++ b/makedumpfile-1.6.0/arch/x86_64.c
> +@@ -62,6 +62,10 @@ get_phys_base_x86_64(void)
> + * Get the relocatable offset
> + */
> + info->phys_base = 0; /* default/traditional */
> ++ if (NUMBER(phys_base) != NOT_FOUND_NUMBER) {
> ++ info->phys_base = NUMBER(phys_base);
> ++ return TRUE;
> ++ }
> +
> + for (i = 0; get_pt_load(i, &phys_start, NULL, &virt_start, NULL); i++) {
> + if (virt_start >= __START_KERNEL_map) {
> +@@ -187,12 +191,6 @@ vtop4_x86_64(unsigned long vaddr)
> + {
> + unsigned long page_dir, pml4, pgd_paddr, pgd_pte, pmd_paddr, pmd_pte;
> + unsigned long pte_paddr, pte;
> +- unsigned long phys_base;
> +-
> +- if (SYMBOL(phys_base) != NOT_FOUND_SYMBOL)
> +- phys_base = info->phys_base;
> +- else
> +- phys_base = 0;
> +
> + if (SYMBOL(init_level4_pgt) == NOT_FOUND_SYMBOL) {
> + ERRMSG("Can't get the symbol of init_level4_pgt.\n");
> +@@ -202,7 +200,7 @@ vtop4_x86_64(unsigned long vaddr)
> + /*
> + * Get PGD.
> + */
> +- page_dir = SYMBOL(init_level4_pgt) - __START_KERNEL_map + phys_base;
> ++ page_dir = SYMBOL(init_level4_pgt) - __START_KERNEL_map + info->phys_base;
> + page_dir += pml4_index(vaddr) * sizeof(unsigned long);
> + if (!readmem(PADDR, page_dir, &pml4, sizeof pml4)) {
> + ERRMSG("Can't get pml4 (page_dir:%lx).\n", page_dir);
> +diff --git a/makedumpfile-1.6.0/makedumpfile.c b/makedumpfile-1.6.0/makedumpfile.c
> +index b916dfb8b189..a3f711e3e9bf 100644
> +--- a/makedumpfile-1.6.0/makedumpfile.c
> ++++ b/makedumpfile-1.6.0/makedumpfile.c
> +@@ -1507,7 +1507,6 @@ get_symbol_info(void)
> + SYMBOL_INIT(init_level4_pgt, "init_level4_pgt");
> + SYMBOL_INIT(vmlist, "vmlist");
> + SYMBOL_INIT(vmap_area_list, "vmap_area_list");
> +- SYMBOL_INIT(phys_base, "phys_base");
> + SYMBOL_INIT(node_online_map, "node_online_map");
> + SYMBOL_INIT(node_states, "node_states");
> + SYMBOL_INIT(node_memblk, "node_memblk");
> +@@ -2134,7 +2133,6 @@ write_vmcoreinfo_data(void)
> + WRITE_SYMBOL("init_level4_pgt", init_level4_pgt);
> + WRITE_SYMBOL("vmlist", vmlist);
> + WRITE_SYMBOL("vmap_area_list", vmap_area_list);
> +- WRITE_SYMBOL("phys_base", phys_base);
> + WRITE_SYMBOL("node_online_map", node_online_map);
> + WRITE_SYMBOL("node_states", node_states);
> + WRITE_SYMBOL("node_data", node_data);
> +@@ -2261,6 +2259,7 @@ write_vmcoreinfo_data(void)
> +
> + WRITE_NUMBER("PAGE_BUDDY_MAPCOUNT_VALUE", PAGE_BUDDY_MAPCOUNT_VALUE);
> + WRITE_NUMBER("KERNEL_IMAGE_SIZE", KERNEL_IMAGE_SIZE);
> ++ WRITE_NUMBER("phys_base", phys_base);
> +
> + WRITE_NUMBER("HUGETLB_PAGE_DTOR", HUGETLB_PAGE_DTOR);
> +
> +@@ -2488,7 +2487,6 @@ read_vmcoreinfo(void)
> + READ_SYMBOL("init_level4_pgt", init_level4_pgt);
> + READ_SYMBOL("vmlist", vmlist);
> + READ_SYMBOL("vmap_area_list", vmap_area_list);
> +- READ_SYMBOL("phys_base", phys_base);
> + READ_SYMBOL("node_online_map", node_online_map);
> + READ_SYMBOL("node_states", node_states);
> + READ_SYMBOL("node_data", node_data);
> +@@ -2609,6 +2607,7 @@ read_vmcoreinfo(void)
> +
> + READ_NUMBER("PAGE_BUDDY_MAPCOUNT_VALUE", PAGE_BUDDY_MAPCOUNT_VALUE);
> + READ_NUMBER("KERNEL_IMAGE_SIZE", KERNEL_IMAGE_SIZE);
> ++ READ_NUMBER("phys_base", phys_base);
> +
> + READ_NUMBER("HUGETLB_PAGE_DTOR", HUGETLB_PAGE_DTOR);
> +
> +diff --git a/makedumpfile-1.6.0/makedumpfile.h b/makedumpfile-1.6.0/makedumpfile.h
> +index 338c651388f0..422b6bed102b 100644
> +--- a/makedumpfile-1.6.0/makedumpfile.h
> ++++ b/makedumpfile-1.6.0/makedumpfile.h
> +@@ -1394,7 +1394,6 @@ struct symbol_table {
> + unsigned long long init_level4_pgt;
> + unsigned long long vmlist;
> + unsigned long long vmap_area_list;
> +- unsigned long long phys_base;
> + unsigned long long node_online_map;
> + unsigned long long node_states;
> + unsigned long long node_memblk;
> +@@ -1718,6 +1717,7 @@ struct number_table {
> + long SECTION_SIZE_BITS;
> + long MAX_PHYSMEM_BITS;
> + long HUGETLB_PAGE_DTOR;
> ++ long phys_base;
> + };
> +
> + struct srcfile_table {
> +--
> +2.9.3
> +
> diff --git a/kexec-tools.spec b/kexec-tools.spec
> index 3f9f9ae668fb..71c2979563c7 100644
> --- a/kexec-tools.spec
> +++ b/kexec-tools.spec
> @@ -97,6 +97,9 @@ Patch605:
kexec-tools-2.0.13-makedumpfile-x86-64-translate-all-VA-to-PA-using-pa
> Patch606: kexec-tools-2.0.13-makedumpfile-x86-64-kill-is-vmalloc-addr-x86-64.patch
> Patch607:
kexec-tools-2.0.13-makedumpfile-x86-64-kill-some-unused-initialization.patch
> Patch608: kexec-tools-2.0.13-makedumpfile-x86_64-fix-page_offset-calculation.patch
> +Patch609:
kexec-tools-2.0.13-makedumpfile-Adapt-code-to-get-value-of-phys_base.patch
> +Patch610:
kexec-tools-2.0.13-kexec-tools-x86-get_kernel_vaddr_and_size-off-by-one.patch
> +Patch611: kexec-tools-2.0.13-build_mem_phdrs-check-if-p_paddr-is-invalid.patch
>
> %description
> kexec-tools provides /sbin/kexec binary that facilitates a new
> @@ -134,6 +137,9 @@ tar -z -x -v -f %{SOURCE23}
> %patch606 -p1
> %patch607 -p1
> %patch608 -p1
> +%patch609 -p1
> +%patch610 -p1
> +%patch611 -p1
>
> %ifarch ppc
> %define archdef ARCH=ppc
> --
> 2.9.3
>