In the latest openembedded with aarch64 image that uses 6.4.3 kernel on qemu I tried to run makedumpfile in secondary kernel with /proc/vmcore. It failed as follows: > root@qemuarm64:~# makedumpfile -c -F /proc/vmcore > /dev/null > read_from_vmcore: Can't seek the dump memory(/proc/vmcore). (offset: ffffffc0123fa000) Invalid argument > readpage_elf: Can't read the dump memory(/proc/vmcore). > <snip> It turns out that not all parts for /proc/vmcore are readable: > root@qemuarm64:~# cat /proc/vmcore > /dev/null > [ 136.394931] Internal error: synchronous external abort: 0000000096000010 [#1] PREEMPT SMP > [ 136.422434] Modules linked in: > <snip> Binary search of different kernel versions I found that the issue goes back to 5.11. It works fine with 5.10 version of the kernel. After running secondary kernel under qemu gdb, I've found that the primary kernel main memory segment in elfcorehdr has wrong address and size. Looking at kexec output with debug enabled at the time when it loads secondary crash kernel I saw the following: > Kernel text Elf header: p_type = 1, p_offset = 0x4030200000 p_paddr = 0x4030200000 p_vaddr = 0xffffffffffffffff p_filesz = 0xffffffc011410000 p_memsz = 0xffffffc011410000 These values come from elf_info variable and are set in iomem_range_callback function. The function gets the following input on my system: root@qemuarm64:~# cat /proc/iomem | grep "Kernel code" 40210000-40feffff : Kernel code root@qemuarm64:~# cat /proc/kallsyms | grep -e ' _text$' root@qemuarm64:~# cat /proc/kallsyms | grep -e ' _stext$' ffffffc010010000 T _stext root@qemuarm64:~# cat /proc/kallsyms | grep -e ' __init_begin$' ffffffc010df0000 T __init_begin the function calculates elf_info.kern_paddr_start address similar to these manual steps: base = 0x40210000 length = 0x40feffff - 0x40210000 + 0x1 = 0xde0000 kva_text_end - kva_stext = 0xffffffc010df0000 - 0xffffffc010010000 = 0xde0000 elf_info.kern_paddr_start = base - (kva_stext - kva_text) = 0x40210000 - 0xffffffc010010000 = 0x4030200000 since 'length' and 'kva_text_end - kva_stext' are equal the function calculate elf_info.kern_paddr_start as in legacy case: if (kva_text_end - kva_stext == length) elf_info.kern_paddr_start = base - (kva_stext - kva_text); // <--------- else elf_info.kern_paddr_start = base; but my kernel is not legacy and kva_text is zero. The fix is just to add a check for kva_text not being zero before following the legacy case. Signed-off-by: Alexander Kamensky <alexander.kamensky42@xxxxxxxxx> --- kexec/arch/arm64/crashdump-arm64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kexec/arch/arm64/crashdump-arm64.c b/kexec/arch/arm64/crashdump-arm64.c index 3098315..639c82a 100644 --- a/kexec/arch/arm64/crashdump-arm64.c +++ b/kexec/arch/arm64/crashdump-arm64.c @@ -82,7 +82,7 @@ static int iomem_range_callback(void *UNUSED(data), int UNUSED(nr), * For compatibility, deduce by comparing the gap "__init_begin - _stext" * and the res size of "Kernel code" in /proc/iomem */ - if (kva_text_end - kva_stext == length) + if ((kva_text_end - kva_stext == length) && (kva_text != 0)) elf_info.kern_paddr_start = base - (kva_stext - kva_text); else elf_info.kern_paddr_start = base; -- 2.41.0 _______________________________________________ kexec mailing list kexec@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/kexec