arm: io.h: Fix io accessors for KVM
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.
- It will emit ldr + add or str + add instead of ldr/str(post increment)
in somne cases
- 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 add a Kconfig option
to turn it off by default apart from our QEMU builds.
Reported-by: Mikko Rapeli <mikko.rapeli@linaro.org>
Tested-by: Mikko Rapeli <mikko.rapeli@linaro.org>
Signed-off-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>