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 |
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 --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);
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(+)