kexec on arm fails, possibly due to memdup_user

Amr Bekhit amr at helmpcb.com
Tue Jul 4 10:48:26 PDT 2023


> It could be:
>
>         /*
>          * Validate that if the current HW supports SMP, then the SW supports
>          * and implements CPU hotplug for the current HW. If not, we won't be
>          * able to kexec reliably, so fail the prepare operation.
>          */
>         if (num_possible_cpus() > 1 && platform_can_secondary_boot() &&
>             !platform_can_cpu_hotplug())
>                 return -EINVAL;

Thanks - this was exactly the issue. memdup_user was a red herring
caused by some missing printk's due to me not adding newlines. It's
now clear that for my CPU (IPQ4019), the cpu_kill function is not
implemented in the smp_operations struct.

Looking online, I was able to see that kexec does work on my cpu as
long as nr_cpus=1 is specified in the kernel command line (see
https://patchwork.kernel.org/project/linux-arm-msm/patch/CAAGQ2nQNQ-aFkcrQHNA6H5TZ1tTovtfO_0Ohfndn9jXy13Hc6A@mail.gmail.com/#22064531).

I've tried this myself, and indeed setting this option allows the
kexec load to perform successfully. However, when I run kexec -e,
after the "Bye!" message the system just hangs and reboots after a
while, presumably due to a watchdog timeout:

~ # kexec -d --dtb=/data/image-qcom-ipq4019-nerd.dtb -l /data/zImage-openwrt
Try gzip decompression.
Try LZMA decompression.
lzma_decompress_file: read on /data/zImage-openwrt of 65536 bytes failed
kernel: 0xb6b4b090 kernel_size: 0x325e10
MEMORY RANGES
0000000080000000-0000000087dfffff (0)
0000000088000000-000000009fffffff (0)
zImage header: 0x016f2818 0x00000000 0x00325e10
zImage size 0x325e10, file size 0x325e10
  offset 0x00004a08 tag 0x5a534c4b size 24
zImage requires 0x00336e10 bytes
Decompressed kernel sizes:
 text+data 0x00b90b00 bss 0x0003b8bc total 0x00bcc3bc
Resulting kernel space: 0x00ec7910
Kernel: address=0x80008000 size=0x00ec7910
DT    : address=0x80ed1000 size=0x00004c0d
kexec_load: entry = 0x80008000 flags = 0x280000
nr_segments = 2
segment[0].buf   = 0xb6b4b090
segment[0].bufsz = 0x325e10
segment[0].mem   = 0x80008000
segment[0].memsz = 0x326000
segment[1].buf   = 0xb6b460b0
segment[1].bufsz = 0x4c0d
segment[1].mem   = 0x80ed1000
segment[1].memsz = 0x5000
~ # kexec -e
[   47.431861] kexec_core: Starting new kernel
[   47.431908] Bye!

Any pointers as to what could be wrong at this point?



More information about the linux-arm-kernel mailing list