Accepting request 570628 from home:ptesarik:branches:Kernel:kdump
- makedumpfile-always-use-bigger-SECTION_MAP_MASK.patch: Always use bigger SECTION_MAP_MASK (bsc#1066811, bsc#1067703). - Update to 1.6.3 * Support kernels up to 4.14.8 (bsc#1068864). * 86_64: handle renamed init_level4_pgt -> init_top_pgt * Fix SECTION_MAP_MASK for kernel >= v.13 * book3s/ppc64: Lower the max real address to 53 bits for kernels >= v4.11 * Support symbol __cpu_online_mask * ppc64: update hash page table geometry - Drop upstreamed patches: * makedumpfile-Fix-SECTION_MAP_MASK-for-kernel-v.13.patch * makedumpfile-handle-renamed-init_level4_pgt-init_top_pgt.patch * makedumpfile-ppc64-update-hash-page-table-geometry.patch * makedumpfile-book3s-ppc64-Lower-the-max-real-address-to-53-bits.patch * makedumpfile-__cpu_online_mask-symbol.patch * makedumpfile-vtop4_x86_64_pagetable.patch * makedumpfile-fix-KASLR-for-sadump.patch * makedumpfile-fix-KASLR-for-sadump-while-kdump.patch * makedumpfile-support-4.12.patch OBS-URL: https://build.opensuse.org/request/show/570628 OBS-URL: https://build.opensuse.org/package/show/Kernel:kdump/makedumpfile?expand=0&rev=115
This commit is contained in:
parent
4877ee4b98
commit
68172f3fda
@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:ee3d21cb4032a60bd2c802d1d8b21b9f399710e1574f8de8ead5ab50cd821a6d
|
||||
size 182149
|
3
makedumpfile-1.6.3.tar.gz
Normal file
3
makedumpfile-1.6.3.tar.gz
Normal file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:cb1afe2cf24147eac983694bfbcf8c1b149eeeb92289562d4d25fbe3b100b125
|
||||
size 186492
|
@ -1,59 +0,0 @@
|
||||
From: Pratyush Anand <panand@redhat.com>
|
||||
Date: Thu, 17 Aug 2017 12:47:13 +0900
|
||||
Subject: Fix SECTION_MAP_MASK for kernel >= v.13
|
||||
References: bnc#1066811, bsc#1067703
|
||||
Upstream: merged
|
||||
Git-commit: a02f5f078ce635dd1633dab70869306b0a62e2e2
|
||||
|
||||
* Required for kernel 4.13
|
||||
* Required for SLE15 kernel due to backport of 2d070eab2e82 => 4.12
|
||||
|
||||
commit 2d070eab2e82 "mm: consider zone which is not fully populated to
|
||||
have holes" added a new flag SECTION_IS_ONLINE and therefore
|
||||
SECTION_MAP_MASK has been changed. We are not able to find correct
|
||||
mem_map in makedumpfile for kernel version v4.13-rc1 and onward because
|
||||
of the above kernel change.
|
||||
|
||||
This patch fixes the MASK value keeping the code backward compatible
|
||||
|
||||
Signed-off-by: Pratyush Anand <panand@redhat.com>
|
||||
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
|
||||
---
|
||||
makedumpfile.c | 5 ++++-
|
||||
makedumpfile.h | 4 +++-
|
||||
2 files changed, 7 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/makedumpfile.c b/makedumpfile.c
|
||||
index 8af0c9d6c2ac..509631994abc 100644
|
||||
--- a/makedumpfile.c
|
||||
+++ b/makedumpfile.c
|
||||
@@ -3304,7 +3304,10 @@ section_mem_map_addr(unsigned long addr)
|
||||
return NOT_KV_ADDR;
|
||||
}
|
||||
map = ULONG(mem_section + OFFSET(mem_section.section_mem_map));
|
||||
- map &= SECTION_MAP_MASK;
|
||||
+ if (info->kernel_version < KERNEL_VERSION(4, 12, 0))
|
||||
+ map &= SECTION_MAP_MASK_4_12;
|
||||
+ else
|
||||
+ map &= SECTION_MAP_MASK;
|
||||
free(mem_section);
|
||||
|
||||
return map;
|
||||
diff --git a/makedumpfile.h b/makedumpfile.h
|
||||
index b0cdd02f0470..6f188e4b9b25 100644
|
||||
--- a/makedumpfile.h
|
||||
+++ b/makedumpfile.h
|
||||
@@ -183,7 +183,9 @@ isAnon(unsigned long mapping)
|
||||
#define SECTIONS_PER_ROOT() (info->sections_per_root)
|
||||
#define SECTION_ROOT_MASK() (SECTIONS_PER_ROOT() - 1)
|
||||
#define SECTION_NR_TO_ROOT(sec) ((sec) / SECTIONS_PER_ROOT())
|
||||
-#define SECTION_MAP_LAST_BIT (1UL<<2)
|
||||
+#define SECTION_IS_ONLINE (1UL<<2)
|
||||
+#define SECTION_MAP_LAST_BIT (1UL<<3)
|
||||
+#define SECTION_MAP_MASK_4_12 (~(SECTION_IS_ONLINE-1))
|
||||
#define SECTION_MAP_MASK (~(SECTION_MAP_LAST_BIT-1))
|
||||
#define NR_SECTION_ROOTS() divideup(num_section, SECTIONS_PER_ROOT())
|
||||
#define SECTION_NR_TO_PFN(sec) ((sec) << PFN_SECTION_SHIFT())
|
||||
--
|
||||
2.15.0
|
||||
|
@ -1,63 +0,0 @@
|
||||
From: Takao Indoh <indou.takao@jp.fujitsu.com>
|
||||
Date: Thu, 26 Oct 2017 20:32:48 +0900
|
||||
Subject: Support symbol __cpu_online_mask
|
||||
References: FATE#323473, bsc#1070291
|
||||
Upstream: merged
|
||||
Git-commit: d6d5b443c82471818d43cb87c9280a0252e763e7
|
||||
|
||||
In the upstream kernel, by commit 5aec01b83 cpu_online_mask was replaced
|
||||
with macros and new variables __cpu_online_mask was added instead of it.
|
||||
Sadump uses cpu_online_mask to check the cpu was online or not,
|
||||
therefore it also need __cpu_online_mask symbol for this in the latest
|
||||
kernel.
|
||||
|
||||
Signed-off-by: Takao Indoh <indou.takao@jp.fujitsu.com>
|
||||
Signed-off-by: HATAYAMA Daisuke <d.hatayama@jp.fujitsu.com>
|
||||
Acked-by: Petr Tesarik <ptesarik@suse.com>
|
||||
|
||||
---
|
||||
makedumpfile.c | 9 +++++++--
|
||||
makedumpfile.h | 1 +
|
||||
sadump_info.c | 3 ++-
|
||||
3 files changed, 10 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/makedumpfile.c
|
||||
+++ b/makedumpfile.c
|
||||
@@ -1519,8 +1519,13 @@ get_symbol_info(void)
|
||||
SYMBOL_INIT(__per_cpu_load, "__per_cpu_load");
|
||||
SYMBOL_INIT(__per_cpu_offset, "__per_cpu_offset");
|
||||
SYMBOL_INIT(cpu_online_mask, "cpu_online_mask");
|
||||
- if (SYMBOL(cpu_online_mask) == NOT_FOUND_SYMBOL)
|
||||
- SYMBOL_INIT(cpu_online_mask, "cpu_online_map");
|
||||
+ SYMBOL_INIT(__cpu_online_mask, "__cpu_online_mask");
|
||||
+ if (SYMBOL(cpu_online_mask) == NOT_FOUND_SYMBOL) {
|
||||
+ if (SYMBOL(__cpu_online_mask) == NOT_FOUND_SYMBOL)
|
||||
+ SYMBOL_INIT(cpu_online_mask, "cpu_online_map");
|
||||
+ else
|
||||
+ SYMBOL_INIT(cpu_online_mask, "__cpu_online_mask");
|
||||
+ }
|
||||
SYMBOL_INIT(kexec_crash_image, "kexec_crash_image");
|
||||
SYMBOL_INIT(node_remap_start_vaddr, "node_remap_start_vaddr");
|
||||
SYMBOL_INIT(node_remap_end_vaddr, "node_remap_end_vaddr");
|
||||
--- a/makedumpfile.h
|
||||
+++ b/makedumpfile.h
|
||||
@@ -1590,6 +1590,7 @@ struct symbol_table {
|
||||
unsigned long long __per_cpu_offset;
|
||||
unsigned long long __per_cpu_load;
|
||||
unsigned long long cpu_online_mask;
|
||||
+ unsigned long long __cpu_online_mask;
|
||||
unsigned long long kexec_crash_image;
|
||||
|
||||
/*
|
||||
--- a/sadump_info.c
|
||||
+++ b/sadump_info.c
|
||||
@@ -953,7 +953,8 @@ cpu_online_mask_init(void)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
- if (SIZE(cpumask) == NOT_FOUND_STRUCTURE)
|
||||
+ if ((SIZE(cpumask) == NOT_FOUND_STRUCTURE) ||
|
||||
+ (SYMBOL(__cpu_online_mask) != NOT_FOUND_SYMBOL))
|
||||
cpu_online_mask_addr = SYMBOL(cpu_online_mask);
|
||||
|
||||
else {
|
41
makedumpfile-always-use-bigger-SECTION_MAP_MASK.patch
Normal file
41
makedumpfile-always-use-bigger-SECTION_MAP_MASK.patch
Normal file
@ -0,0 +1,41 @@
|
||||
From: Petr Tesarik <ptesarik@suse.com>
|
||||
Date: Mon, 29 Jan 2018 14:59:28 +0200
|
||||
Subject: Always use bigger SECTION_MAP_MASK
|
||||
References: bsc#1066811, bsc#1067703
|
||||
Upstream: not yet
|
||||
|
||||
Since kernel commit 2d070eab2e82 merely reused a previously unused bit, it
|
||||
is safe to mask it off for all kernel versions, because it had always been
|
||||
zero (even in kernels < 4.13).
|
||||
|
||||
Signed-off-by: Petr Tesarik <ptesarik@suse.com>
|
||||
|
||||
---
|
||||
makedumpfile.c | 5 +----
|
||||
makedumpfile.h | 1 -
|
||||
2 files changed, 1 insertion(+), 5 deletions(-)
|
||||
|
||||
--- a/makedumpfile.c
|
||||
+++ b/makedumpfile.c
|
||||
@@ -3337,10 +3337,7 @@ section_mem_map_addr(unsigned long addr)
|
||||
return NOT_KV_ADDR;
|
||||
}
|
||||
map = ULONG(mem_section + OFFSET(mem_section.section_mem_map));
|
||||
- if (info->kernel_version < KERNEL_VERSION(4, 13, 0))
|
||||
- map &= SECTION_MAP_MASK_4_12;
|
||||
- else
|
||||
- map &= SECTION_MAP_MASK;
|
||||
+ map &= SECTION_MAP_MASK;
|
||||
free(mem_section);
|
||||
|
||||
return map;
|
||||
--- a/makedumpfile.h
|
||||
+++ b/makedumpfile.h
|
||||
@@ -186,7 +186,6 @@ isAnon(unsigned long mapping)
|
||||
#define SECTION_NR_TO_ROOT(sec) ((sec) / SECTIONS_PER_ROOT())
|
||||
#define SECTION_IS_ONLINE (1UL<<2)
|
||||
#define SECTION_MAP_LAST_BIT (1UL<<3)
|
||||
-#define SECTION_MAP_MASK_4_12 (~(SECTION_IS_ONLINE-1))
|
||||
#define SECTION_MAP_MASK (~(SECTION_MAP_LAST_BIT-1))
|
||||
#define NR_SECTION_ROOTS() divideup(num_section, SECTIONS_PER_ROOT())
|
||||
#define SECTION_NR_TO_PFN(sec) ((sec) << PFN_SECTION_SHIFT())
|
@ -1,74 +0,0 @@
|
||||
From: Bhupesh Sharma <bhsharma@redhat.com>
|
||||
Date: Wed, 13 Sep 2017 05:04:00 +0900
|
||||
Subject: book3s/ppc64: Lower the max real address to 53
|
||||
bits for kernels >= v4.11
|
||||
References: bsc#1067703
|
||||
Upstream: merged
|
||||
Git-commit: dc28bfc3213960b549bcc70f0d5379a6222d2c60
|
||||
|
||||
* Required for kernel 4.11
|
||||
|
||||
Kernel commit 2f18d533757da3899f4bedab0b2c051b080079dc lowered the
|
||||
max real address on ppc64 to 53 bits.
|
||||
|
||||
Make similar changes in makedumpfile (on basis of the underlying kernel
|
||||
version), without which the makedumpfile will fail to create a dumpfile
|
||||
and instead throw a SEGV fault as shown below on kernels >= v4.11:
|
||||
|
||||
# makedumpfile --split -d 31 -x vmlinux vmcore dumpfile_{1,2,3} 2>&1
|
||||
|
||||
The kernel version is not supported.
|
||||
The makedumpfile operation may be incomplete.
|
||||
[ 1196.252094] makedumpfile[2367]: unhandled signal 11 at
|
||||
00000100f7011ca8 nip 000000001001eecc lr 000000001001f3c0 code 30001
|
||||
Segmentation fault
|
||||
|
||||
Signed-off-by: Bhupesh Sharma <bhsharma@redhat.com>
|
||||
Acked-by: Michal Suchanek <msuchanek@suse.de>
|
||||
---
|
||||
arch/ppc64.c | 8 +++++++-
|
||||
makedumpfile.h | 5 +++++
|
||||
2 files changed, 12 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/arch/ppc64.c b/arch/ppc64.c
|
||||
index bacac778f73c..2f5a0daa16b2 100644
|
||||
--- a/arch/ppc64.c
|
||||
+++ b/arch/ppc64.c
|
||||
@@ -307,11 +307,17 @@ ppc64_vmalloc_init(void)
|
||||
}
|
||||
|
||||
info->pte_rpn_mask = PTE_RPN_MASK_DEFAULT;
|
||||
- if (info->kernel_version >= KERNEL_VERSION(4, 6, 0)) {
|
||||
+ if ((info->kernel_version >= KERNEL_VERSION(4, 6, 0)) &&
|
||||
+ (info->kernel_version < KERNEL_VERSION(4, 11, 0))) {
|
||||
info->pte_rpn_mask = PTE_RPN_MASK_L4_4_6;
|
||||
info->pte_rpn_shift = PTE_RPN_SHIFT_L4_4_6;
|
||||
}
|
||||
|
||||
+ if (info->kernel_version >= KERNEL_VERSION(4, 11, 0)) {
|
||||
+ info->pte_rpn_mask = PTE_RPN_MASK_L4_4_11;
|
||||
+ info->pte_rpn_shift = PTE_RPN_SHIFT_L4_4_11;
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
* Compute ptrs per each level
|
||||
*/
|
||||
diff --git a/makedumpfile.h b/makedumpfile.h
|
||||
index 7d81bbcf2234..f4ba02d11f09 100644
|
||||
--- a/makedumpfile.h
|
||||
+++ b/makedumpfile.h
|
||||
@@ -692,6 +692,11 @@ unsigned long get_kvbase_arm64(void);
|
||||
#define PUD_MASKED_BITS_4_7 0xc0000000000000ffUL
|
||||
#define PMD_MASKED_BITS_4_7 0xc0000000000000ffUL
|
||||
|
||||
+#define PTE_RPN_SIZE_L4_4_11 53
|
||||
+#define PTE_RPN_MASK_L4_4_11 \
|
||||
+ (((1UL << PTE_RPN_SIZE_L4_4_11) - 1) & ~((1UL << info->page_shift) - 1))
|
||||
+#define PTE_RPN_SHIFT_L4_4_11 info->page_shift
|
||||
+
|
||||
/*
|
||||
* Supported MMU types
|
||||
*/
|
||||
--
|
||||
2.13.6
|
||||
|
@ -1,353 +0,0 @@
|
||||
From: Takao Indoh <indou.takao@jp.fujitsu.com>
|
||||
Date: Thu, 26 Oct 2017 20:33:01 +0900
|
||||
Subject: sadump: Fix a KASLR problem of sadump while kdump is working
|
||||
References: FATE#323473, bsc#1070291
|
||||
Upstream: merged
|
||||
Git-commit: 09288f2058c8066a2729588ec668eed3e1140028
|
||||
|
||||
In the calc_kaslr_offset(), kaslr_offset and phys_base are calculated
|
||||
using IDTR and CR3, but this solution does not work in the following
|
||||
cases.
|
||||
|
||||
1) If the dump is captured on early stage of kernel boot, IDTR points
|
||||
early IDT table(early_idts) instead of normal IDT(idt_table).
|
||||
2) If the dump is captured whle kdump is working, IDTR points IDT table
|
||||
of 2nd kernel, not 1st kernel.
|
||||
|
||||
This patch fixes the case 2). Current implementation does not support
|
||||
the case 1), need enhancement in the future. This patch gets kernel boot
|
||||
parameter from "saved_command_line" and check if "elfcorehdr=" is
|
||||
included in the parameter. If it's included, we are in the 2nd kernel.
|
||||
Retrieve vmcoreinfo from address of "elfcorehdr=" and get kaslr_offset
|
||||
and phys_base from vmcoreinfo.
|
||||
|
||||
Signed-off-by: Takao Indoh <indou.takao@jp.fujitsu.com>
|
||||
Acked-by: Petr Tesarik <ptesarik@suse.com>
|
||||
|
||||
---
|
||||
makedumpfile.c | 1
|
||||
makedumpfile.h | 1
|
||||
sadump_info.c | 271 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 273 insertions(+)
|
||||
|
||||
--- a/makedumpfile.c
|
||||
+++ b/makedumpfile.c
|
||||
@@ -1556,6 +1556,7 @@ get_symbol_info(void)
|
||||
|
||||
SYMBOL_INIT(divide_error, "divide_error");
|
||||
SYMBOL_INIT(idt_table, "idt_table");
|
||||
+ SYMBOL_INIT(saved_command_line, "saved_command_line");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
--- a/makedumpfile.h
|
||||
+++ b/makedumpfile.h
|
||||
@@ -1596,6 +1596,7 @@ struct symbol_table {
|
||||
unsigned long long kexec_crash_image;
|
||||
unsigned long long divide_error;
|
||||
unsigned long long idt_table;
|
||||
+ unsigned long long saved_command_line;
|
||||
|
||||
/*
|
||||
* symbols on ppc64 arch
|
||||
--- a/sadump_info.c
|
||||
+++ b/sadump_info.c
|
||||
@@ -1059,6 +1059,241 @@ get_vec0_addr(ulong idtr)
|
||||
}
|
||||
|
||||
/*
|
||||
+ * Parse a string of [size[KMG]@]offset[KMG]
|
||||
+ * Import from Linux kernel(lib/cmdline.c)
|
||||
+ */
|
||||
+static ulong memparse(char *ptr, char **retptr)
|
||||
+{
|
||||
+ char *endptr;
|
||||
+
|
||||
+ unsigned long long ret = strtoull(ptr, &endptr, 0);
|
||||
+
|
||||
+ switch (*endptr) {
|
||||
+ case 'E':
|
||||
+ case 'e':
|
||||
+ ret <<= 10;
|
||||
+ case 'P':
|
||||
+ case 'p':
|
||||
+ ret <<= 10;
|
||||
+ case 'T':
|
||||
+ case 't':
|
||||
+ ret <<= 10;
|
||||
+ case 'G':
|
||||
+ case 'g':
|
||||
+ ret <<= 10;
|
||||
+ case 'M':
|
||||
+ case 'm':
|
||||
+ ret <<= 10;
|
||||
+ case 'K':
|
||||
+ case 'k':
|
||||
+ ret <<= 10;
|
||||
+ endptr++;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (retptr)
|
||||
+ *retptr = endptr;
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Find "elfcorehdr=" in the boot parameter of kernel and return the address
|
||||
+ * of elfcorehdr.
|
||||
+ */
|
||||
+static ulong
|
||||
+get_elfcorehdr(ulong cr3)
|
||||
+{
|
||||
+ char cmdline[BUFSIZE], *ptr;
|
||||
+ ulong cmdline_vaddr;
|
||||
+ ulong cmdline_paddr;
|
||||
+ ulong buf_vaddr, buf_paddr;
|
||||
+ char *end;
|
||||
+ ulong elfcorehdr_addr = 0, elfcorehdr_size = 0;
|
||||
+
|
||||
+ if (SYMBOL(saved_command_line) == NOT_FOUND_SYMBOL) {
|
||||
+ ERRMSG("Can't get the symbol of saved_command_line.\n");
|
||||
+ return 0;
|
||||
+ }
|
||||
+ cmdline_vaddr = SYMBOL(saved_command_line);
|
||||
+ if ((cmdline_paddr = vtop4_x86_64_pagetable(cmdline_vaddr, cr3)) == NOT_PADDR)
|
||||
+ return 0;
|
||||
+
|
||||
+ DEBUG_MSG("sadump: cmdline vaddr: %lx\n", cmdline_vaddr);
|
||||
+ DEBUG_MSG("sadump: cmdline paddr: %lx\n", cmdline_paddr);
|
||||
+
|
||||
+ if (!readmem(PADDR, cmdline_paddr, &buf_vaddr, sizeof(ulong)))
|
||||
+ return 0;
|
||||
+
|
||||
+ if ((buf_paddr = vtop4_x86_64_pagetable(buf_vaddr, cr3)) == NOT_PADDR)
|
||||
+ return 0;
|
||||
+
|
||||
+ DEBUG_MSG("sadump: cmdline buf vaddr: %lx\n", buf_vaddr);
|
||||
+ DEBUG_MSG("sadump: cmdline buf paddr: %lx\n", buf_paddr);
|
||||
+
|
||||
+ memset(cmdline, 0, BUFSIZE);
|
||||
+ if (!readmem(PADDR, buf_paddr, cmdline, BUFSIZE))
|
||||
+ return 0;
|
||||
+
|
||||
+ ptr = strstr(cmdline, "elfcorehdr=");
|
||||
+ if (!ptr)
|
||||
+ return 0;
|
||||
+
|
||||
+ DEBUG_MSG("sadump: 2nd kernel detected.\n");
|
||||
+
|
||||
+ ptr += strlen("elfcorehdr=");
|
||||
+ elfcorehdr_addr = memparse(ptr, &end);
|
||||
+ if (*end == '@') {
|
||||
+ elfcorehdr_size = elfcorehdr_addr;
|
||||
+ elfcorehdr_addr = memparse(end + 1, &end);
|
||||
+ }
|
||||
+
|
||||
+ DEBUG_MSG("sadump: elfcorehdr_addr: %lx\n", elfcorehdr_addr);
|
||||
+ DEBUG_MSG("sadump: elfcorehdr_size: %lx\n", elfcorehdr_size);
|
||||
+
|
||||
+ return elfcorehdr_addr;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Get vmcoreinfo from elfcorehdr.
|
||||
+ * Some codes are imported from Linux kernel(fs/proc/vmcore.c)
|
||||
+ */
|
||||
+static int
|
||||
+get_vmcoreinfo_in_kdump_kernel(ulong elfcorehdr, ulong *addr, int *len)
|
||||
+{
|
||||
+ unsigned char e_ident[EI_NIDENT];
|
||||
+ Elf64_Ehdr ehdr;
|
||||
+ Elf64_Phdr phdr;
|
||||
+ Elf64_Nhdr nhdr;
|
||||
+ ulong ptr;
|
||||
+ ulong nhdr_offset = 0;
|
||||
+ int i;
|
||||
+
|
||||
+ if (!readmem(PADDR, elfcorehdr, e_ident, EI_NIDENT))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ if (e_ident[EI_CLASS] != ELFCLASS64) {
|
||||
+ ERRMSG("Only ELFCLASS64 is supportd\n");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ if (!readmem(PADDR, elfcorehdr, &ehdr, sizeof(ehdr)))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ /* Sanity Check */
|
||||
+ if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0 ||
|
||||
+ (ehdr.e_type != ET_CORE) ||
|
||||
+ ehdr.e_ident[EI_CLASS] != ELFCLASS64 ||
|
||||
+ ehdr.e_ident[EI_VERSION] != EV_CURRENT ||
|
||||
+ ehdr.e_version != EV_CURRENT ||
|
||||
+ ehdr.e_ehsize != sizeof(Elf64_Ehdr) ||
|
||||
+ ehdr.e_phentsize != sizeof(Elf64_Phdr) ||
|
||||
+ ehdr.e_phnum == 0) {
|
||||
+ ERRMSG("Invalid elf header\n");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ ptr = elfcorehdr + ehdr.e_phoff;
|
||||
+ for (i = 0; i < ehdr.e_phnum; i++) {
|
||||
+ ulong offset;
|
||||
+ char name[16];
|
||||
+
|
||||
+ if (!readmem(PADDR, ptr, &phdr, sizeof(phdr)))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ ptr += sizeof(phdr);
|
||||
+ if (phdr.p_type != PT_NOTE)
|
||||
+ continue;
|
||||
+
|
||||
+ offset = phdr.p_offset;
|
||||
+ if (!readmem(PADDR, offset, &nhdr, sizeof(nhdr)))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ offset += divideup(sizeof(Elf64_Nhdr), sizeof(Elf64_Word))*
|
||||
+ sizeof(Elf64_Word);
|
||||
+ memset(name, 0, sizeof(name));
|
||||
+ if (!readmem(PADDR, offset, name, sizeof(name)))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ if(!strcmp(name, "VMCOREINFO")) {
|
||||
+ nhdr_offset = offset;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (!nhdr_offset)
|
||||
+ return FALSE;
|
||||
+
|
||||
+ *addr = nhdr_offset +
|
||||
+ divideup(nhdr.n_namesz, sizeof(Elf64_Word))*
|
||||
+ sizeof(Elf64_Word);
|
||||
+ *len = nhdr.n_descsz;
|
||||
+
|
||||
+ DEBUG_MSG("sadump: vmcoreinfo addr: %lx\n", *addr);
|
||||
+ DEBUG_MSG("sadump: vmcoreinfo len: %d\n", *len);
|
||||
+
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Check if current kaslr_offset/phys_base is for 1st kernel or 2nd kernel.
|
||||
+ * If we are in 2nd kernel, get kaslr_offset/phys_base from vmcoreinfo.
|
||||
+ *
|
||||
+ * 1. Get command line and try to retrieve "elfcorehdr=" boot parameter
|
||||
+ * 2. If "elfcorehdr=" is not found in command line, we are in 1st kernel.
|
||||
+ * There is nothing to do.
|
||||
+ * 3. If "elfcorehdr=" is found, we are in 2nd kernel. Find vmcoreinfo
|
||||
+ * using "elfcorehdr=" and retrieve kaslr_offset/phys_base from vmcoreinfo.
|
||||
+ */
|
||||
+int
|
||||
+get_kaslr_offset_from_vmcoreinfo(ulong cr3, ulong *kaslr_offset,
|
||||
+ ulong *phys_base)
|
||||
+{
|
||||
+ ulong elfcorehdr_addr = 0;
|
||||
+ ulong vmcoreinfo_addr;
|
||||
+ int vmcoreinfo_len;
|
||||
+ char *buf, *pos;
|
||||
+ int ret = FALSE;
|
||||
+
|
||||
+ elfcorehdr_addr = get_elfcorehdr(cr3);
|
||||
+ if (!elfcorehdr_addr)
|
||||
+ return FALSE;
|
||||
+
|
||||
+ if (!get_vmcoreinfo_in_kdump_kernel(elfcorehdr_addr, &vmcoreinfo_addr,
|
||||
+ &vmcoreinfo_len))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ if (!vmcoreinfo_len)
|
||||
+ return FALSE;
|
||||
+
|
||||
+ DEBUG_MSG("sadump: Find vmcoreinfo in kdump memory\n");
|
||||
+
|
||||
+ if (!(buf = malloc(vmcoreinfo_len))) {
|
||||
+ ERRMSG("Can't allocate vmcoreinfo buffer.\n");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ if (!readmem(PADDR, vmcoreinfo_addr, buf, vmcoreinfo_len))
|
||||
+ goto finish;
|
||||
+
|
||||
+ pos = strstr(buf, STR_NUMBER("phys_base"));
|
||||
+ if (!pos)
|
||||
+ goto finish;
|
||||
+ *phys_base = strtoull(pos + strlen(STR_NUMBER("phys_base")), NULL, 0);
|
||||
+
|
||||
+ pos = strstr(buf, STR_KERNELOFFSET);
|
||||
+ if (!pos)
|
||||
+ goto finish;
|
||||
+ *kaslr_offset = strtoull(pos + strlen(STR_KERNELOFFSET), NULL, 16);
|
||||
+ ret = TRUE;
|
||||
+
|
||||
+finish:
|
||||
+ free(buf);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
* Calculate kaslr_offset and phys_base
|
||||
*
|
||||
* kaslr_offset:
|
||||
@@ -1106,6 +1341,26 @@ get_vec0_addr(ulong idtr)
|
||||
*
|
||||
* Note that the address (A) cannot be used instead of (E) because (A) is
|
||||
* not direct map address, it's a fixed map address.
|
||||
+ *
|
||||
+ * This solution works in most every case, but does not work in the
|
||||
+ * following case.
|
||||
+ *
|
||||
+ * 1) If the dump is captured on early stage of kernel boot, IDTR points
|
||||
+ * early IDT table(early_idts) instead of normal IDT(idt_table).
|
||||
+ * 2) If the dump is captured whle kdump is working, IDTR points
|
||||
+ * IDT table of 2nd kernel, not 1st kernel.
|
||||
+ *
|
||||
+ * Current implementation does not support the case 1), need
|
||||
+ * enhancement in the future. For the case 2), get kaslr_offset and
|
||||
+ * phys_base as follows.
|
||||
+ *
|
||||
+ * 1) Get kaslr_offset and phys_base using the above solution.
|
||||
+ * 2) Get kernel boot parameter from "saved_command_line"
|
||||
+ * 3) If "elfcorehdr=" is not included in boot parameter, we are in the
|
||||
+ * first kernel, nothing to do any more.
|
||||
+ * 4) If "elfcorehdr=" is included in boot parameter, we are in the 2nd
|
||||
+ * kernel. Retrieve vmcoreinfo from address of "elfcorehdr=" and
|
||||
+ * get kaslr_offset and phys_base from vmcoreinfo.
|
||||
*/
|
||||
int
|
||||
calc_kaslr_offset(void)
|
||||
@@ -1116,6 +1371,7 @@ calc_kaslr_offset(void)
|
||||
int apicid;
|
||||
unsigned long divide_error_vmcore, divide_error_vmlinux;
|
||||
unsigned long kaslr_offset, phys_base;
|
||||
+ unsigned long kaslr_offset_kdump, phys_base_kdump;
|
||||
|
||||
memset(&zero, 0, sizeof(zero));
|
||||
for (apicid = 0; apicid < sh->nr_cpus; ++apicid) {
|
||||
@@ -1161,6 +1417,21 @@ calc_kaslr_offset(void)
|
||||
if (!get_symbol_info())
|
||||
return FALSE;
|
||||
|
||||
+ /*
|
||||
+ * Check if current kaslr_offset/phys_base is for 1st kernel or 2nd
|
||||
+ * kernel. If we are in 2nd kernel, get kaslr_offset/phys_base
|
||||
+ * from vmcoreinfo
|
||||
+ */
|
||||
+ if (get_kaslr_offset_from_vmcoreinfo(cr3, &kaslr_offset_kdump,
|
||||
+ &phys_base_kdump)) {
|
||||
+ info->kaslr_offset = kaslr_offset_kdump;
|
||||
+ info->phys_base = phys_base_kdump;
|
||||
+
|
||||
+ /* Reload symbol */
|
||||
+ if (!get_symbol_info())
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
DEBUG_MSG("sadump: kaslr_offset=%lx\n", info->kaslr_offset);
|
||||
DEBUG_MSG("sadump: phys_base=%lx\n", info->phys_base);
|
||||
|
@ -1,257 +0,0 @@
|
||||
From: Takao Indoh <indou.takao@jp.fujitsu.com>
|
||||
Date: Thu, 26 Oct 2017 20:32:54 +0900
|
||||
Subject: Fix a KASLR problem of sadump
|
||||
References: FATE#323473, bsc#1070291
|
||||
Upstream: merged
|
||||
Git-commit: e1ac694b94ebfa7204c5b1fac1a87d204b48f5b4
|
||||
|
||||
This patch fix a problem that makedumpfile cannot handle a dumpfile
|
||||
which is captured by sadump in KASLR enabled kernel.
|
||||
|
||||
When KASLR feature is enabled, a kernel is placed on the memory randomly
|
||||
and therefore makedumpfile cannot handle a dumpfile captured by sadump
|
||||
because addresses of kernel symbols in System.map or vmlinux are
|
||||
different from actual addresses.
|
||||
|
||||
To solve this problem, we need to calculate kaslr offset(the difference
|
||||
between original symbol address and actual address) and phys_base, and
|
||||
adjust symbol table of makedumpfile. In the case of dumpfile of kdump,
|
||||
these information is included in the header, but dumpfile of sadump does
|
||||
not have such a information.
|
||||
|
||||
This patch calculate kaslr offset and phys_base to solve this problem.
|
||||
Please see the comment in the calc_kaslr_offset() for the detail idea.
|
||||
The basic idea is getting register (IDTR and CR3) from dump header, and
|
||||
calculate kaslr_offset/phys_base using them.
|
||||
|
||||
Signed-off-by: Takao Indoh <indou.takao@jp.fujitsu.com>
|
||||
Acked-by: Petr Tesarik <ptesarik@suse.com>
|
||||
|
||||
---
|
||||
makedumpfile.c | 10 +++
|
||||
makedumpfile.h | 5 +
|
||||
sadump_info.c | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
3 files changed, 155 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/makedumpfile.c
|
||||
+++ b/makedumpfile.c
|
||||
@@ -1554,6 +1554,9 @@ get_symbol_info(void)
|
||||
SYMBOL_INIT(demote_segment_4k, "demote_segment_4k");
|
||||
SYMBOL_INIT(cur_cpu_spec, "cur_cpu_spec");
|
||||
|
||||
+ SYMBOL_INIT(divide_error, "divide_error");
|
||||
+ SYMBOL_INIT(idt_table, "idt_table");
|
||||
+
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -2251,6 +2254,13 @@ write_vmcoreinfo_data(void)
|
||||
WRITE_NUMBER_UNSIGNED("kimage_voffset", kimage_voffset);
|
||||
#endif
|
||||
|
||||
+ if (info->phys_base)
|
||||
+ fprintf(info->file_vmcoreinfo, "%s%lu\n", STR_NUMBER("phys_base"),
|
||||
+ info->phys_base);
|
||||
+ if (info->kaslr_offset)
|
||||
+ fprintf(info->file_vmcoreinfo, "%s%lx\n", STR_KERNELOFFSET,
|
||||
+ info->kaslr_offset);
|
||||
+
|
||||
/*
|
||||
* write the source file of 1st kernel
|
||||
*/
|
||||
--- a/makedumpfile.h
|
||||
+++ b/makedumpfile.h
|
||||
@@ -45,6 +45,7 @@
|
||||
#include "sadump_mod.h"
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
+#include <inttypes.h>
|
||||
|
||||
#define VMEMMAPSTART 0xffffea0000000000UL
|
||||
#define BITS_PER_WORD 64
|
||||
@@ -1593,6 +1594,8 @@ struct symbol_table {
|
||||
unsigned long long cpu_online_mask;
|
||||
unsigned long long __cpu_online_mask;
|
||||
unsigned long long kexec_crash_image;
|
||||
+ unsigned long long divide_error;
|
||||
+ unsigned long long idt_table;
|
||||
|
||||
/*
|
||||
* symbols on ppc64 arch
|
||||
@@ -1953,7 +1956,7 @@ int iomem_for_each_line(char *match, int
|
||||
unsigned long base,
|
||||
unsigned long length),
|
||||
void *data);
|
||||
-
|
||||
+int get_symbol_info(void);
|
||||
|
||||
/*
|
||||
* for Xen extraction
|
||||
--- a/sadump_info.c
|
||||
+++ b/sadump_info.c
|
||||
@@ -1035,6 +1035,138 @@ sadump_get_max_mapnr(void)
|
||||
|
||||
#ifdef __x86_64__
|
||||
|
||||
+/*
|
||||
+ * Get address of vector0 interrupt handler (Devide Error) form Interrupt
|
||||
+ * Descriptor Table.
|
||||
+ */
|
||||
+static unsigned long
|
||||
+get_vec0_addr(ulong idtr)
|
||||
+{
|
||||
+ struct gate_struct64 {
|
||||
+ uint16_t offset_low;
|
||||
+ uint16_t segment;
|
||||
+ uint32_t ist : 3, zero0 : 5, type : 5, dpl : 2, p : 1;
|
||||
+ uint16_t offset_middle;
|
||||
+ uint32_t offset_high;
|
||||
+ uint32_t zero1;
|
||||
+ } __attribute__((packed)) gate;
|
||||
+
|
||||
+ readmem(PADDR, idtr, &gate, sizeof(gate));
|
||||
+
|
||||
+ return ((ulong)gate.offset_high << 32)
|
||||
+ + ((ulong)gate.offset_middle << 16)
|
||||
+ + gate.offset_low;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Calculate kaslr_offset and phys_base
|
||||
+ *
|
||||
+ * kaslr_offset:
|
||||
+ * The difference between original address in vmlinux and actual address
|
||||
+ * placed randomly by kaslr feature. To be more accurate,
|
||||
+ * kaslr_offset = actual address - original address
|
||||
+ *
|
||||
+ * phys_base:
|
||||
+ * Physical address where the kerenel is placed. In other words, it's a
|
||||
+ * physical address of __START_KERNEL_map. This is also decided randomly by
|
||||
+ * kaslr.
|
||||
+ *
|
||||
+ * kaslr offset and phys_base are calculated as follows:
|
||||
+ *
|
||||
+ * kaslr_offset:
|
||||
+ * 1) Get IDTR and CR3 value from the dump header.
|
||||
+ * 2) Get a virtual address of IDT from IDTR value
|
||||
+ * --- (A)
|
||||
+ * 3) Translate (A) to physical address using CR3, which points a top of
|
||||
+ * page table.
|
||||
+ * --- (B)
|
||||
+ * 4) Get an address of vector0 (Devide Error) interrupt handler from
|
||||
+ * IDT, which are pointed by (B).
|
||||
+ * --- (C)
|
||||
+ * 5) Get an address of symbol "divide_error" form vmlinux
|
||||
+ * --- (D)
|
||||
+ *
|
||||
+ * Now we have two addresses:
|
||||
+ * (C)-> Actual address of "divide_error"
|
||||
+ * (D)-> Original address of "divide_error" in the vmlinux
|
||||
+ *
|
||||
+ * kaslr_offset can be calculated by the difference between these two
|
||||
+ * value.
|
||||
+ *
|
||||
+ * phys_base;
|
||||
+ * 1) Get IDT virtual address from vmlinux
|
||||
+ * --- (E)
|
||||
+ *
|
||||
+ * So phys_base can be calculated using relationship of directly mapped
|
||||
+ * address.
|
||||
+ *
|
||||
+ * phys_base =
|
||||
+ * Physical address(B) -
|
||||
+ * (Virtual address(E) + kaslr_offset - __START_KERNEL_map)
|
||||
+ *
|
||||
+ * Note that the address (A) cannot be used instead of (E) because (A) is
|
||||
+ * not direct map address, it's a fixed map address.
|
||||
+ */
|
||||
+int
|
||||
+calc_kaslr_offset(void)
|
||||
+{
|
||||
+ struct sadump_header *sh = si->sh_memory;
|
||||
+ uint64_t idtr = 0, cr3 = 0, idtr_paddr;
|
||||
+ struct sadump_smram_cpu_state smram, zero;
|
||||
+ int apicid;
|
||||
+ unsigned long divide_error_vmcore, divide_error_vmlinux;
|
||||
+ unsigned long kaslr_offset, phys_base;
|
||||
+
|
||||
+ memset(&zero, 0, sizeof(zero));
|
||||
+ for (apicid = 0; apicid < sh->nr_cpus; ++apicid) {
|
||||
+ if (!get_smram_cpu_state(apicid, &smram)) {
|
||||
+ ERRMSG("get_smram_cpu_state error\n");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ if (memcmp(&smram, &zero, sizeof(smram)) != 0)
|
||||
+ break;
|
||||
+ }
|
||||
+ if (apicid >= sh->nr_cpus) {
|
||||
+ ERRMSG("Can't get smram state\n");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ idtr = ((uint64_t)smram.IdtUpper)<<32 | (uint64_t)smram.IdtLower;
|
||||
+ cr3 = smram.Cr3;
|
||||
+
|
||||
+ /* Convert virtual address of IDT table to physical address */
|
||||
+ if ((idtr_paddr = vtop4_x86_64_pagetable(idtr, cr3)) == NOT_PADDR)
|
||||
+ return FALSE;
|
||||
+
|
||||
+ /* Now we can calculate kaslr_offset and phys_base */
|
||||
+ divide_error_vmlinux = SYMBOL(divide_error);
|
||||
+ divide_error_vmcore = get_vec0_addr(idtr_paddr);
|
||||
+ kaslr_offset = divide_error_vmcore - divide_error_vmlinux;
|
||||
+ phys_base = idtr_paddr -
|
||||
+ (SYMBOL(idt_table) + kaslr_offset - __START_KERNEL_map);
|
||||
+
|
||||
+ info->kaslr_offset = kaslr_offset;
|
||||
+ info->phys_base = phys_base;
|
||||
+
|
||||
+ DEBUG_MSG("sadump: idtr=%" PRIx64 "\n", idtr);
|
||||
+ DEBUG_MSG("sadump: cr3=%" PRIx64 "\n", cr3);
|
||||
+ DEBUG_MSG("sadump: idtr(phys)=%" PRIx64 "\n", idtr_paddr);
|
||||
+ DEBUG_MSG("sadump: devide_error(vmlinux)=%lx\n",
|
||||
+ divide_error_vmlinux);
|
||||
+ DEBUG_MSG("sadump: devide_error(vmcore)=%lx\n",
|
||||
+ divide_error_vmcore);
|
||||
+
|
||||
+ /* Reload symbol */
|
||||
+ if (!get_symbol_info())
|
||||
+ return FALSE;
|
||||
+
|
||||
+ DEBUG_MSG("sadump: kaslr_offset=%lx\n", info->kaslr_offset);
|
||||
+ DEBUG_MSG("sadump: phys_base=%lx\n", info->phys_base);
|
||||
+
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
int
|
||||
sadump_virt_phys_base(void)
|
||||
{
|
||||
@@ -1065,6 +1197,9 @@ sadump_virt_phys_base(void)
|
||||
}
|
||||
|
||||
failed:
|
||||
+ if (calc_kaslr_offset())
|
||||
+ return TRUE;
|
||||
+
|
||||
info->phys_base = 0;
|
||||
|
||||
DEBUG_MSG("sadump: failed to calculate phys_base; default to 0\n");
|
||||
@@ -1518,10 +1653,14 @@ cpu_to_apicid(int cpu, int *apicid)
|
||||
if (!readmem(VADDR, SYMBOL(x86_bios_cpu_apicid_early_ptr),
|
||||
&early_ptr, sizeof(early_ptr)))
|
||||
return FALSE;
|
||||
-
|
||||
+ /*
|
||||
+ * Note: SYMBOL(name) value is adjusted by info->kaslr_offset,
|
||||
+ * but per_cpu symbol does not need to be adjusted becasue it
|
||||
+ * is not affected by kaslr.
|
||||
+ */
|
||||
apicid_addr = early_ptr
|
||||
? SYMBOL(x86_bios_cpu_apicid_early_map)+cpu*sizeof(uint16_t)
|
||||
- : per_cpu_ptr(SYMBOL(x86_bios_cpu_apicid), cpu);
|
||||
+ : per_cpu_ptr(SYMBOL(x86_bios_cpu_apicid) - info->kaslr_offset, cpu);
|
||||
|
||||
if (!readmem(VADDR, apicid_addr, &apicid_u16, sizeof(uint16_t)))
|
||||
return FALSE;
|
@ -1,116 +0,0 @@
|
||||
From: Jeff Mahoney <jeffm@suse.com>
|
||||
Subject: handle renamed init_level4_pgt -> init_top_pgt
|
||||
References: bsc#1066770
|
||||
Upstream: merged
|
||||
Git-commit: 97e156b493c46fabfc4b136ab834a6495166ac66
|
||||
|
||||
* Required for kernel 4.13
|
||||
|
||||
Linux 4.13 renamed init_level4_pgt to init_top_pgt in preparation for
|
||||
introducing 5-level page tables. This patch follows the rename if
|
||||
the lookup for init_level4_pgt fails. It also checks to see if
|
||||
5-level page tables are enabled and bails if it discovers they are.
|
||||
|
||||
Signed-off-by: Jeff Mahoney <jeffm@suse.com>
|
||||
---
|
||||
arch/x86_64.c | 24 +++++++++++++++++++++---
|
||||
makedumpfile.c | 6 ++++++
|
||||
makedumpfile.h | 2 ++
|
||||
3 files changed, 29 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/arch/x86_64.c b/arch/x86_64.c
|
||||
index 08dd6b2..9b09035 100644
|
||||
--- a/arch/x86_64.c
|
||||
+++ b/arch/x86_64.c
|
||||
@@ -259,16 +259,26 @@ 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 init_level4_pgt;
|
||||
|
||||
- if (SYMBOL(init_level4_pgt) == NOT_FOUND_SYMBOL) {
|
||||
+ if (SYMBOL(init_level4_pgt) != NOT_FOUND_SYMBOL)
|
||||
+ init_level4_pgt = SYMBOL(init_level4_pgt);
|
||||
+ else if (SYMBOL(init_top_pgt) != NOT_FOUND_SYMBOL)
|
||||
+ init_level4_pgt = SYMBOL(init_top_pgt);
|
||||
+ else {
|
||||
ERRMSG("Can't get the symbol of init_level4_pgt.\n");
|
||||
return NOT_PADDR;
|
||||
}
|
||||
|
||||
+ if (SYMBOL(level4_kernel_pgt) != NOT_FOUND_SYMBOL) {
|
||||
+ ERRMSG("Kernel is built with 5-level page tables\n");
|
||||
+ return NOT_PADDR;
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
* Get PGD.
|
||||
*/
|
||||
- page_dir = SYMBOL(init_level4_pgt) - __START_KERNEL_map + info->phys_base;
|
||||
+ page_dir = init_level4_pgt - __START_KERNEL_map + info->phys_base;
|
||||
if (is_xen_memory()) {
|
||||
page_dir = ptom_xen(page_dir);
|
||||
if (page_dir == NOT_PADDR)
|
||||
@@ -549,8 +559,16 @@ find_vmemmap_x86_64()
|
||||
struct vmap_pfns *vmapp, *vmaphead = NULL, *cur, *tail;
|
||||
|
||||
init_level4_pgt = SYMBOL(init_level4_pgt);
|
||||
+ if (init_level4_pgt == NOT_FOUND_SYMBOL)
|
||||
+ init_level4_pgt = SYMBOL(init_top_pgt);
|
||||
+
|
||||
if (init_level4_pgt == NOT_FOUND_SYMBOL) {
|
||||
- ERRMSG("init_level4_pgt not found\n");
|
||||
+ ERRMSG("init_level4_pgt/init_top_pgt not found\n");
|
||||
+ return FAILED;
|
||||
+ }
|
||||
+
|
||||
+ if (SYMBOL(level4_kernel_pgt) != NOT_FOUND_SYMBOL) {
|
||||
+ ERRMSG("kernel is configured for 5-level page tables\n");
|
||||
return FAILED;
|
||||
}
|
||||
pagestructsize = size_table.page;
|
||||
diff --git a/makedumpfile.c b/makedumpfile.c
|
||||
index f85003a..6e5ec34 100644
|
||||
--- a/makedumpfile.c
|
||||
+++ b/makedumpfile.c
|
||||
@@ -1486,6 +1486,8 @@ get_symbol_info(void)
|
||||
SYMBOL_INIT(_stext, "_stext");
|
||||
SYMBOL_INIT(swapper_pg_dir, "swapper_pg_dir");
|
||||
SYMBOL_INIT(init_level4_pgt, "init_level4_pgt");
|
||||
+ SYMBOL_INIT(level4_kernel_pgt, "level4_kernel_pgt");
|
||||
+ SYMBOL_INIT(init_top_pgt, "init_top_pgt");
|
||||
SYMBOL_INIT(vmlist, "vmlist");
|
||||
SYMBOL_INIT(vmap_area_list, "vmap_area_list");
|
||||
SYMBOL_INIT(node_online_map, "node_online_map");
|
||||
@@ -2105,6 +2107,8 @@ write_vmcoreinfo_data(void)
|
||||
WRITE_SYMBOL("_stext", _stext);
|
||||
WRITE_SYMBOL("swapper_pg_dir", swapper_pg_dir);
|
||||
WRITE_SYMBOL("init_level4_pgt", init_level4_pgt);
|
||||
+ WRITE_SYMBOL("level4_kernel_pgt", level4_kernel_pgt);
|
||||
+ WRITE_SYMBOL("init_top_pgt", init_top_pgt);
|
||||
WRITE_SYMBOL("vmlist", vmlist);
|
||||
WRITE_SYMBOL("vmap_area_list", vmap_area_list);
|
||||
WRITE_SYMBOL("node_online_map", node_online_map);
|
||||
@@ -2500,6 +2504,8 @@ read_vmcoreinfo(void)
|
||||
READ_SYMBOL("_stext", _stext);
|
||||
READ_SYMBOL("swapper_pg_dir", swapper_pg_dir);
|
||||
READ_SYMBOL("init_level4_pgt", init_level4_pgt);
|
||||
+ READ_SYMBOL("level4_kernel_pgt", level4_kernel_pgt);
|
||||
+ READ_SYMBOL("init_top_pgt", init_top_pgt);
|
||||
READ_SYMBOL("vmlist", vmlist);
|
||||
READ_SYMBOL("vmap_area_list", vmap_area_list);
|
||||
READ_SYMBOL("node_online_map", node_online_map);
|
||||
diff --git a/makedumpfile.h b/makedumpfile.h
|
||||
index 8a05794..9357e47 100644
|
||||
--- a/makedumpfile.h
|
||||
+++ b/makedumpfile.h
|
||||
@@ -1517,6 +1517,8 @@ struct symbol_table {
|
||||
unsigned long long _stext;
|
||||
unsigned long long swapper_pg_dir;
|
||||
unsigned long long init_level4_pgt;
|
||||
+ unsigned long long level4_kernel_pgt;
|
||||
+ unsigned long long init_top_pgt;
|
||||
unsigned long long vmlist;
|
||||
unsigned long long vmap_area_list;
|
||||
unsigned long long phys_base;
|
||||
|
@ -1,60 +0,0 @@
|
||||
From: Hari Bathini <hbathini@linux.vnet.ibm.com>
|
||||
Date: Sat, 11 Nov 2017 02:13:54 +0900
|
||||
Subject: ppc64: update hash page table geometry
|
||||
References: bsc#1067703
|
||||
Upsream: merged
|
||||
Git-commit: 13f48cbab7207d8247834453b55d45b2a95f65cb
|
||||
|
||||
* Required for kernel 4.12
|
||||
|
||||
Starting with kernel 4.12, BOOK3S hash page table geometry is updated
|
||||
to accommodate larger virtual address range. Update here accordingly.
|
||||
|
||||
Signed-off-by: Hari Bathini <hbathini@linux.vnet.ibm.com>
|
||||
Acked-by: Michal Suchanek <msuchanek@suse.de>
|
||||
---
|
||||
arch/ppc64.c | 12 +++++++++---
|
||||
makedumpfile.h | 3 +++
|
||||
2 files changed, 12 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/arch/ppc64.c b/arch/ppc64.c
|
||||
index 2f5a0daa16b2..8bdbcc583c47 100644
|
||||
--- a/arch/ppc64.c
|
||||
+++ b/arch/ppc64.c
|
||||
@@ -245,10 +245,16 @@ ppc64_vmalloc_init(void)
|
||||
|
||||
} else if (info->kernel_version >= KERNEL_VERSION(4, 6, 0)) {
|
||||
info->l1_index_size = PTE_INDEX_SIZE_L4_64K_3_10;
|
||||
- info->l2_index_size = PMD_INDEX_SIZE_L4_64K_4_6;
|
||||
- info->l3_index_size = PUD_INDEX_SIZE_L4_64K_4_6;
|
||||
- info->l4_index_size = PGD_INDEX_SIZE_L4_64K_3_10;
|
||||
|
||||
+ if (info->kernel_version >= KERNEL_VERSION(4, 12, 0)) {
|
||||
+ info->l2_index_size = PMD_INDEX_SIZE_L4_64K_4_12;
|
||||
+ info->l3_index_size = PUD_INDEX_SIZE_L4_64K_4_12;
|
||||
+ info->l4_index_size = PGD_INDEX_SIZE_L4_64K_4_12;
|
||||
+ } else {
|
||||
+ info->l2_index_size = PMD_INDEX_SIZE_L4_64K_4_6;
|
||||
+ info->l3_index_size = PUD_INDEX_SIZE_L4_64K_4_6;
|
||||
+ info->l4_index_size = PGD_INDEX_SIZE_L4_64K_3_10;
|
||||
+ }
|
||||
} else if (info->kernel_version >= KERNEL_VERSION(3, 10, 0)) {
|
||||
info->l1_index_size = PTE_INDEX_SIZE_L4_64K_3_10;
|
||||
info->l2_index_size = PMD_INDEX_SIZE_L4_64K_3_10;
|
||||
diff --git a/makedumpfile.h b/makedumpfile.h
|
||||
index db753792bca6..b983aaf5ab03 100644
|
||||
--- a/makedumpfile.h
|
||||
+++ b/makedumpfile.h
|
||||
@@ -670,6 +670,9 @@ unsigned long get_kvbase_arm64(void);
|
||||
#define PGD_INDEX_SIZE_L4_64K_3_10 12
|
||||
#define PMD_INDEX_SIZE_L4_64K_4_6 5
|
||||
#define PUD_INDEX_SIZE_L4_64K_4_6 5
|
||||
+#define PMD_INDEX_SIZE_L4_64K_4_12 10
|
||||
+#define PUD_INDEX_SIZE_L4_64K_4_12 7
|
||||
+#define PGD_INDEX_SIZE_L4_64K_4_12 8
|
||||
#define PTE_INDEX_SIZE_RADIX_64K 5
|
||||
#define PMD_INDEX_SIZE_RADIX_64K 9
|
||||
#define PUD_INDEX_SIZE_RADIX_64K 9
|
||||
--
|
||||
2.13.6
|
||||
|
@ -1,110 +0,0 @@
|
||||
From: Takao Indoh <indou.takao@jp.fujitsu.com>
|
||||
Date: Thu, 26 Oct 2017 20:32:54 +0900
|
||||
Subject: Introduce vtop4_x86_64_pagetable
|
||||
References: FATE#323473, bsc#1070291
|
||||
Upstream: merged
|
||||
Git-commit: 8c89727155f4994b4e75a659e28e5eff16ff6cbc
|
||||
|
||||
This patch introduces new function vtop4_x86_64_pagetable
|
||||
to translate virtual address to physical address. Unlike vtop4_x86_64,
|
||||
vtop4_x86_64_pagetable need a pointer of top of pagetable like CR3.
|
||||
|
||||
Current vtop4_x86_64 implementation uses symbol value of
|
||||
init_level4_pgt, therefore vtop4_x86_64 does not work for sadump
|
||||
dumpfile of kaslr enabled kernel because it does not have vmcoreinfo to
|
||||
correct address of init_level4_pgt. vtop4_x86_64_pagetable requires
|
||||
pagetable address instead of init_level4_pgt and sadump dumpfile can
|
||||
pass CR3 value which is included in dump header.
|
||||
|
||||
Signed-off-by: Takao Indoh <indou.takao@jp.fujitsu.com>
|
||||
Signed-off-by: HATAYAMA Daisuke <d.hatayama@jp.fujitsu.com>
|
||||
Acked-by: Petr Tesarik <ptesarik@suse.com>
|
||||
|
||||
---
|
||||
arch/x86_64.c | 50 +++++++++++++++++++++++++++++++++-----------------
|
||||
makedumpfile.h | 1 +
|
||||
2 files changed, 34 insertions(+), 17 deletions(-)
|
||||
|
||||
--- a/arch/x86_64.c
|
||||
+++ b/arch/x86_64.c
|
||||
@@ -255,30 +255,15 @@ get_versiondep_info_x86_64(void)
|
||||
* Translate a virtual address to a physical address by using 4 levels paging.
|
||||
*/
|
||||
unsigned long long
|
||||
-vtop4_x86_64(unsigned long vaddr)
|
||||
+__vtop4_x86_64(unsigned long vaddr, unsigned long pagetable)
|
||||
{
|
||||
unsigned long page_dir, pml4, pgd_paddr, pgd_pte, pmd_paddr, pmd_pte;
|
||||
unsigned long pte_paddr, pte;
|
||||
- unsigned long init_level4_pgt;
|
||||
-
|
||||
- if (SYMBOL(init_level4_pgt) != NOT_FOUND_SYMBOL)
|
||||
- init_level4_pgt = SYMBOL(init_level4_pgt);
|
||||
- else if (SYMBOL(init_top_pgt) != NOT_FOUND_SYMBOL)
|
||||
- init_level4_pgt = SYMBOL(init_top_pgt);
|
||||
- else {
|
||||
- ERRMSG("Can't get the symbol of init_level4_pgt.\n");
|
||||
- return NOT_PADDR;
|
||||
- }
|
||||
-
|
||||
- if (SYMBOL(level4_kernel_pgt) != NOT_FOUND_SYMBOL) {
|
||||
- ERRMSG("Kernel is built with 5-level page tables\n");
|
||||
- return NOT_PADDR;
|
||||
- }
|
||||
|
||||
/*
|
||||
* Get PGD.
|
||||
*/
|
||||
- page_dir = init_level4_pgt - __START_KERNEL_map + info->phys_base;
|
||||
+ page_dir = pagetable;
|
||||
if (is_xen_memory()) {
|
||||
page_dir = ptom_xen(page_dir);
|
||||
if (page_dir == NOT_PADDR)
|
||||
@@ -356,6 +341,37 @@ vtop4_x86_64(unsigned long vaddr)
|
||||
return (pte & ENTRY_MASK) + PAGEOFFSET(vaddr);
|
||||
}
|
||||
|
||||
+unsigned long long
|
||||
+vtop4_x86_64(unsigned long vaddr)
|
||||
+{
|
||||
+ unsigned long pagetable;
|
||||
+ unsigned long init_level4_pgt;
|
||||
+
|
||||
+ if (SYMBOL(init_level4_pgt) != NOT_FOUND_SYMBOL)
|
||||
+ init_level4_pgt = SYMBOL(init_level4_pgt);
|
||||
+ else if (SYMBOL(init_top_pgt) != NOT_FOUND_SYMBOL)
|
||||
+ init_level4_pgt = SYMBOL(init_top_pgt);
|
||||
+ else {
|
||||
+ ERRMSG("Can't get the symbol of init_level4_pgt.\n");
|
||||
+ return NOT_PADDR;
|
||||
+ }
|
||||
+
|
||||
+ if (SYMBOL(level4_kernel_pgt) != NOT_FOUND_SYMBOL) {
|
||||
+ ERRMSG("Kernel is built with 5-level page tables\n");
|
||||
+ return NOT_PADDR;
|
||||
+ }
|
||||
+
|
||||
+ pagetable = init_level4_pgt - __START_KERNEL_map + info->phys_base;
|
||||
+
|
||||
+ return __vtop4_x86_64(vaddr, pagetable);
|
||||
+}
|
||||
+
|
||||
+unsigned long long
|
||||
+vtop4_x86_64_pagetable(unsigned long vaddr, unsigned long pagetable)
|
||||
+{
|
||||
+ return __vtop4_x86_64(vaddr, pagetable);
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* for Xen extraction
|
||||
*/
|
||||
--- a/makedumpfile.h
|
||||
+++ b/makedumpfile.h
|
||||
@@ -977,6 +977,7 @@ int get_phys_base_x86_64(void);
|
||||
int get_machdep_info_x86_64(void);
|
||||
int get_versiondep_info_x86_64(void);
|
||||
unsigned long long vtop4_x86_64(unsigned long vaddr);
|
||||
+unsigned long long vtop4_x86_64_pagetable(unsigned long vaddr, unsigned long pagetable);
|
||||
#define find_vmemmap() find_vmemmap_x86_64()
|
||||
#define get_phys_base() get_phys_base_x86_64()
|
||||
#define get_machdep_info() get_machdep_info_x86_64()
|
@ -1,3 +1,31 @@
|
||||
-------------------------------------------------------------------
|
||||
Mon Jan 29 14:01:03 UTC 2018 - ptesarik@suse.com
|
||||
|
||||
- makedumpfile-always-use-bigger-SECTION_MAP_MASK.patch: Always use
|
||||
bigger SECTION_MAP_MASK (bsc#1066811, bsc#1067703).
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Mon Jan 29 13:49:43 UTC 2018 - ptesarik@suse.com
|
||||
|
||||
- Update to 1.6.3
|
||||
* Support kernels up to 4.14.8 (bsc#1068864).
|
||||
* 86_64: handle renamed init_level4_pgt -> init_top_pgt
|
||||
* Fix SECTION_MAP_MASK for kernel >= v.13
|
||||
* book3s/ppc64: Lower the max real address to 53 bits for
|
||||
kernels >= v4.11
|
||||
* Support symbol __cpu_online_mask
|
||||
* ppc64: update hash page table geometry
|
||||
- Drop upstreamed patches:
|
||||
* makedumpfile-Fix-SECTION_MAP_MASK-for-kernel-v.13.patch
|
||||
* makedumpfile-handle-renamed-init_level4_pgt-init_top_pgt.patch
|
||||
* makedumpfile-ppc64-update-hash-page-table-geometry.patch
|
||||
* makedumpfile-book3s-ppc64-Lower-the-max-real-address-to-53-bits.patch
|
||||
* makedumpfile-__cpu_online_mask-symbol.patch
|
||||
* makedumpfile-vtop4_x86_64_pagetable.patch
|
||||
* makedumpfile-fix-KASLR-for-sadump.patch
|
||||
* makedumpfile-fix-KASLR-for-sadump-while-kdump.patch
|
||||
* makedumpfile-support-4.12.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Tue Jan 9 09:56:06 UTC 2018 - ptesarik@suse.com
|
||||
|
||||
|
@ -29,7 +29,7 @@
|
||||
%endif
|
||||
|
||||
Name: makedumpfile
|
||||
Version: 1.6.2
|
||||
Version: 1.6.3
|
||||
Release: 0
|
||||
Summary: Partial kernel dump
|
||||
License: GPL-2.0
|
||||
@ -38,15 +38,8 @@ Url: https://sourceforge.net/projects/makedumpfile/
|
||||
Source: https://sourceforge.net/projects/makedumpfile/files/makedumpfile/%{version}/%{name}-%{version}.tar.gz
|
||||
Source99: %{name}-rpmlintrc
|
||||
Patch0: %{name}-coptflags.diff
|
||||
Patch1: %{name}-Fix-SECTION_MAP_MASK-for-kernel-v.13.patch
|
||||
Patch2: %{name}-override-libtinfo.patch
|
||||
Patch3: %{name}-handle-renamed-init_level4_pgt-init_top_pgt.patch
|
||||
Patch4: %{name}-ppc64-update-hash-page-table-geometry.patch
|
||||
Patch5: %{name}-book3s-ppc64-Lower-the-max-real-address-to-53-bits.patch
|
||||
Patch6: %{name}-__cpu_online_mask-symbol.patch
|
||||
Patch7: %{name}-vtop4_x86_64_pagetable.patch
|
||||
Patch8: %{name}-fix-KASLR-for-sadump.patch
|
||||
Patch9: %{name}-fix-KASLR-for-sadump-while-kdump.patch
|
||||
Patch1: %{name}-override-libtinfo.patch
|
||||
Patch2: %{name}-always-use-bigger-SECTION_MAP_MASK.patch
|
||||
BuildRequires: libdw-devel
|
||||
BuildRequires: libebl-devel
|
||||
BuildRequires: libelf-devel
|
||||
@ -77,13 +70,6 @@ via gdb or crash utility.
|
||||
%patch0 -p1
|
||||
%patch1 -p1
|
||||
%patch2 -p1
|
||||
%patch3 -p1
|
||||
%patch4 -p1
|
||||
%patch5 -p1
|
||||
%patch6 -p1
|
||||
%patch7 -p1
|
||||
%patch8 -p1
|
||||
%patch9 -p1
|
||||
|
||||
%build
|
||||
%if %{have_snappy}
|
||||
|
Loading…
x
Reference in New Issue
Block a user