diff mbox series

[RFC,v1] usb: xhci: fix crash with arm64 QEMU and KVM

Message ID 20250610121803.3111973-1-jerome.forissier@linaro.org
State New
Headers show
Series [RFC,v1] usb: xhci: fix crash with arm64 QEMU and KVM | expand

Commit Message

Jerome Forissier June 10, 2025, 12:17 p.m. UTC
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@linaro.org>
Signed-off-by: Jerome Forissier <jerome.forissier@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(+)

Comments

Ilias Apalodimas June 16, 2025, 7:58 a.m. UTC | #1
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@linaro.org>
> Signed-off-by: Jerome Forissier <jerome.forissier@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);
diff mbox series

Patch

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));
 	temp = xhci_readl(&hcor->or_usbcmd);
 	temp |= (CMD_RUN);
 	xhci_writel(&hcor->or_usbcmd, temp);