[PATCH] aarch64: kern_paddr_start calculation makes more accurate legacy check

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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



[Index of Archives]     [LM Sensors]     [Linux Sound]     [ALSA Users]     [ALSA Devel]     [Linux Audio Users]     [Linux Media]     [Kernel]     [Gimp]     [Yosemite News]     [Linux Media]

  Powered by Linux