Blob Blame History Raw
From d015e6df8bd320fbabcd98cc157acf655fc0851b Mon Sep 17 00:00:00 2001
From: "Hatayama, Daisuke" <d.hatayama@jp.fujitsu.com>
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
    ...<snip>...

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 <d.hatayama@jp.fujitsu.com>
---
 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