[RFC PATCH v1] usb: xhci: fix crash with arm64 QEMU and KVM
Ilias Apalodimas
ilias.apalodimas at linaro.org
Mon Jun 16 09:58:38 CEST 2025
Hi Jerome,
On Tue Jun 10, 2025 at 3:17 PM EEST, Jerome Forissier wrote:
> Add a xhci_flush_cache() call to xhci_start() to fix the following
> issue when running arm64 QEMU with KVM support (on a arm64 host):
>
> $ make qemu_arm64_defconfig
> $ sed -i 's/CONFIG_BLOBLIST=y/# CONFIG_BLOBLIST is not set/' .config
> $ make -j$(nproc)
> $ qemu-system-aarch64 -machine virt -cpu host -enable-kvm -nographic \
> -bios u-boot.bin \
> -device qemu-xhci -device usb-kbd
> 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 ...
>
> Reported-by: Mikko Rapeli <mikko.rapeli at linaro.org>
> Signed-off-by: Jerome Forissier <jerome.forissier at linaro.org>
> ---
> This is sent as an RFC because I am really not sure what is happening
> here. Is this the proper thing to do? xhci_flush_cache() or
> xhci_inval_cache()? Where exactly? Which size?
>
> drivers/usb/host/xhci.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
> index 3ee1f67190f..7c5a898cf3d 100644
> --- a/drivers/usb/host/xhci.c
> +++ b/drivers/usb/host/xhci.c
> @@ -159,6 +159,7 @@ static int xhci_start(struct xhci_hcor *hcor)
> int ret;
>
> puts("Starting the controller\n");
> + xhci_flush_cache((uintptr_t)&hcor, sizeof(hcor));
So this is kind of random. It's not the cache flush it self that is needed.
We just have to make sure that code which causes a hypervisor exception does
not use instructions that modify both registers.
I've posted [0] that fixes this
[0] https://lore.kernel.org/u-boot/20250616075035.1144220-1-ilias.apalodimas@linaro.org/T/#u
Cheers
/Ilias
> temp = xhci_readl(&hcor->or_usbcmd);
> temp |= (CMD_RUN);
> xhci_writel(&hcor->or_usbcmd, temp);
More information about the U-Boot
mailing list