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

Pingfan Liu piliu at redhat.com
Thu Aug 24 23:16:53 PDT 2023


On Sun, Aug 20, 2023 at 3:16 AM Alexander Kamensky
<alexander.kamensky42 at gmail.com> wrote:
>
> 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 at 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 at 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 at qemuarm64:~# cat /proc/iomem | grep "Kernel code"
>   40210000-40feffff : Kernel code
> root at qemuarm64:~# cat /proc/kallsyms | grep -e ' _text$'

This is the crux of the problem. Could you say something about how it
disappeared?

On my side, I can see this info on 6.2.14-300.fc38.aarch64

grep -w _text /proc/kallsyms
ffffc705d8500000 T _text

Thanks,

Pingfan
> root at qemuarm64:~# cat /proc/kallsyms | grep -e ' _stext$'
> ffffffc010010000 T _stext
> root at 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 at gmail.com>
> ---
>  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 at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec
>




More information about the kexec mailing list