[PATCH] arm: io.h: Fix io accessors for KVM

Mikko Rapeli mikko.rapeli at linaro.org
Mon Jun 16 15:48:53 CEST 2025


Hi,

On Mon, Jun 16, 2025 at 10:50:32AM +0300, Ilias Apalodimas wrote:
> commit 2e2c2a5e72a8 ("arm: qemu: override flash accessors to use virtualizable instructions")
> explains why we can't have instructions with multiple output registers
> when running under QEMU + KVM and the instruction leads to an exception
> to the hypervisor.
> 
> USB XHCI is such a case (MMIO) where a ldr w1, [x0], #4 is emitted for
> xhci_start() which works fine with QEMU but crashes for QEMU + KVM.
> 
> These instructions cannot be emulated by KVM as they do not produce
> syndrome information data that KVM can use to infer the destination
> register, the faulting address, whether it was a load or store, or
> if it's a 32 or 64 bit general-purpose register.
> As a result an external abort is injected from QEMU, via ext_dabt_pending
> to KVM and we end up throwing an exception that looks like
> 
>  U-Boot 2025.07-rc4 (Jun 10 2025 - 12:00:15 +0000)
>  [...]
>  Register 8001040 NbrPorts 8
>  Starting the controller
>  "Synchronous Abort" handler, esr 0x96000010, far 0x10100040
>  elr: 000000000005b1c8 lr : 000000000005b1ac (reloc)
>  elr: 00000000476fc1c8 lr : 00000000476fc1ac
>  x0 : 0000000010100040 x1 : 0000000000000001
>  x2 : 0000000000000000 x3 : 0000000000003e80
>  x4 : 0000000000000000 x5 : 00000000477a5694
>  x6 : 0000000000000038 x7 : 000000004666f360
>  x8 : 0000000000000000 x9 : 00000000ffffffd8
>  x10: 000000000000000d x11: 0000000000000006
>  x12: 0000000046560a78 x13: 0000000046560dd0
>  x14: 00000000ffffffff x15: 000000004666eed2
>  x16: 00000000476ee2f0 x17: 0000000000000000
>  x18: 0000000046660dd0 x19: 000000004666f480
>  x20: 0000000000000000 x21: 0000000010100040
>  x22: 0000000010100000 x23: 0000000000000000
>  x24: 0000000000000000 x25: 0000000000000000
>  x26: 0000000000000000 x27: 0000000000000000
>  x28: 0000000000000000 x29: 000000004666f360
> 
>  Code: d5033fbf aa1503e0 5287d003 52800002 (b8004401)
>  Resetting CPU ...
> 
> There are two problems making this the default.
> - Some v7 platforms throw an error looking like
>   {standard input}: Assembler messages:
>   {standard input}:1259: Error: lo register required -- `ldrh ip,[r1]'
>   We can change the asm constraints from "r" to "l" for  Thumb.
>   However, it overcomplicates the macros for no apparent reason.
>   Running armv7 + KVM is unlikely. The pipeline [0] contains the details
>   of what needs to change.
> - Some platforms that depend on TPL/SPL grow in size enough so that the
>   binary doesn't fit anymore.
> 
> So let's add proper I/O accessors for arvm8 only and add a Kconfig option
> to turn it off by default if TPL is selected.
> 
> [0] https://source.denx.de/u-boot/custodians/u-boot-tpm/-/pipelines/26673
> 
> Reported-by: Mikko Rapeli <mikko.rapeli at linaro.org>
> Signed-off-by: Ilias Apalodimas <ilias.apalodimas at linaro.org>

Tested on yocto master branch builds for qemuarm64 machine and this
patch fixes the boot hang when USB devices are enabled (like they are
on qemuarm64 yocto target machine config). Included u-boot update from 2025.04
to newer master branch commit b22a276f039f818d5564bec6637071cfc8a7e432
in the build.

$ bitbake core-image-minimal u-boot && \
BIOS=tmp/deploy/images/qemuarm64/u-boot.bin runqemu slirp nographic novga snapshot kvm
...
runqemu - INFO - Running /home/mcfrisk/src/base/repo/poky/build_qemuarm64/tmp/work/aarch64-linux/qemu-helper-native/1.0/recipe-sysroot-native/usr/bin/qemu-system-aarch64 -device virtio-net-pci,netdev=net0,mac=52:54:00:12:35:02 -netdev user,id=net0,hostfwd=tcp:127.0.0.1:2222-:22,hostfwd=tcp:127.0.0.1:2323-:23,tftp=/home/mcfrisk/src/base/repo/poky/build_qemuarm64/tmp/deploy/images/qemuarm64 -object rng-random,filename=/dev/urandom,id=rng0 -device virtio-rng-pci,rng=rng0 -drive id=disk0,file=/home/mcfrisk/src/base/repo/poky/build_qemuarm64/tmp/deploy/images/qemuarm64/core-image-minimal-qemuarm64.rootfs-20250616133755.ext4,if=none,format=raw -device virtio-blk-pci,drive=disk0 -device qemu-xhci -device usb-tablet -device usb-kbd  -machine virt -cpu host -machine gic-version=3 -smp 4 -enable-kvm -m 256 -snapshot -serial mon:stdio -serial null -nographic -vga none -bios tmp/deploy/images/qemuarm64/u-boot.bin -kernel /home/mcfrisk/src/base/repo/poky/build_qemuarm64/tmp/deploy/images/qemuarm64/Image -append 'root=/dev/vda rw  mem=256M ip=dhcp console=ttyAMA0 console=hvc0 swiotlb=0 '
...
U-Boot 2025.07-rc3 (May 30 2025 - 19:44:05 +0000)
...
[    0.000000] Booting Linux on physical CPU 0x0000000000 [0x413fd0c1]
[    0.000000] Linux version 6.12.31-yocto-standard (oe-user at oe-host) (aarch64-poky-linux-gcc (GCC) 15.1.0, GNU ld (GNU Binutils) 2.44.0.20250429) #1 SMP PREEMPT Thu Jun  5 02:14:18 UTC 2025

Tested-by: Mikko Rapeli <mikko.rapeli at linaro.org>

Cheers,

-Mikko


More information about the U-Boot mailing list