From d015e6df8bd320fbabcd98cc157acf655fc0851b Mon Sep 17 00:00:00 2001 From: "Hatayama, Daisuke" Date: Tue, 30 Oct 2018 02:47:22 +0000 Subject: [PATCH] makedumpfile: sadump: fix failure of reading 640 KB backup region if at over 4GB location Currently, in function sadump_kdump_backup_region_init(), variable mem holding physical memory to read as a candidate of the ELF core header is of type unsigned int with just 4 byte length: for (i = 0; i < ARRAY_LENGTH(kimage.segment); ++i) { char e_ident[EI_NIDENT]; unsigned mem; mem=ULONG(buf+i*SIZE(kexec_segment)+OFFSET(kexec_segment.mem)); if (!mem) continue; if (!readmem(PADDR, mem, e_ident, SELFMAG)) { DEBUG_MSG("sadump: failed to read elfcorehdr buffer\n"); return; } Thus, if backup region for the first 640KB physical memory is located at over 4GB location thanks to crashkernel=size,high like: # grep crashkernel /proc/cmdline BOOT_IMAGE=(hd0,gpt2)/vmlinuz-4.18 root=/dev/mapper/rhel-root ro crashkernel=512M,high # grep Crash /proc/iomem 06000000-15ffffff : Crash kernel 107f000000-109effffff : Crash kernel crash> rd -p 0x109ef5d000 109ef5d000: 00010102464c457f .ELF.... the upper 32-bit of the physical address in mem variable is dropped and readmem() fails while outputting the following debug message: # LANG=C ./makedumpfile --message-level 8 -f -l -d 31 -x ./vmlinux /dev/sdc vmcore-ld31 sadump: read dump device as single partition sadump: single partition configuration page_size : 4096 sadump: timezone information is missing sadump: idtr=fffffe0000000000 sadump: cr3=86b42e000 sadump: idtr(phys)=4c35cc000 sadump: devide_error(vmlinux)=ffffffff81a00c50 sadump: devide_error(vmcore)=ffffffffa0c00c50 sadump: cmdline vaddr: ffffffffa1bcf008 sadump: cmdline paddr: 4c35cf008 sadump: cmdline buf vaddr: ffff8ae89ffceec0 sadump: cmdline buf paddr: 109ffceec0 sadump: kaslr_offset=1f200000 sadump: phys_base=4a1a00000 sadump: online cpus: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 [...] sadump: nr_cpus: 60 sadump: failed to read elfcorehdr buffer <--- This is the debug message indicating reading ELF core header fails Then, the generated vmcore has invalid data in its first 640KB part. The variable mem needs to have type of 64-bit length. With this patch, kdump backup region is successfully found as follows: # LANG=C ./makedumpfile --message-level 31 -f -l -d 31 -x ./vmlinux /dev/sdc vmcore-ld31 sadump: read dump device as single partition sadump: single partition configuration page_size : 4096 sadump: timezone information is missing sadump: idtr=fffffe0000000000 sadump: cr3=86b42e000 sadump: idtr(phys)=4c35cc000 sadump: devide_error(vmlinux)=ffffffff81a00c50 sadump: devide_error(vmcore)=ffffffffa0c00c50 sadump: cmdline vaddr: ffffffffa1bcf008 sadump: cmdline paddr: 4c35cf008 sadump: cmdline buf vaddr: ffff8ae89ffceec0 sadump: cmdline buf paddr: 109ffceec0 sadump: kaslr_offset=1f200000 sadump: phys_base=4a1a00000 sadump: online cpus: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 [...] sadump: nr_cpus: 60 The kernel version is not supported. The makedumpfile operation may be incomplete. sadump: SRC_START: 0x00000000001000 SRC_SIZE: 0x0000000009f000 SRC_OFFSET: 0x0000109ef61000 sadump: kdump backup region used ...... By the way, before crashkernel=size,high was introduced, there was limitation that ELF core header resides at under 4GB location, so defining it as unsigned int was not entirely wrong at that time. Signed-off-by: HATAYAMA Daisuke --- sadump_info.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/makedumpfile-1.6.4/sadump_info.c b/makedumpfile-1.6.4/sadump_info.c index 34b568c..46867ce 100644 --- a/makedumpfile-1.6.4/sadump_info.c +++ b/makedumpfile-1.6.4/sadump_info.c @@ -2395,7 +2395,7 @@ sadump_kdump_backup_region_init(void) elfcorehdr_p = 0; for (i = 0; i < ARRAY_LENGTH(kimage.segment); ++i) { char e_ident[EI_NIDENT]; - unsigned mem; + unsigned long mem; mem=ULONG(buf+i*SIZE(kexec_segment)+OFFSET(kexec_segment.mem)); if (!mem) -- 2.17.1