Dear QEMU maintainers,
I would like to submit a patch for preventing the guest VM crash caused by the assertion failure in usb_host_ep_update() during USB hotplug/unplug on host passthrough.
QEMU issue submitted:
https://gitlab.com/qemu-project/qemu/-/issues/3189
Please help to review below patch, thanks!
===============================
Author: Liang1 Yang liang1.yang@intel.com<mailto:liang1.yang@intel.com>
Date: Thu Oct 30 20:07:41 2025 +0800
hw/usb/host-libusb: Do not assert when detects invalid alt
Log warning and skip the interface instead of asserting in qemu
host-libusb when there is invalid altsetting index during fast
USB device hotplug/unplug.
This is to prevent guest vm from crashing which is caused by
QEMU task abort.
Signed-off-by: Liang1 Yang liang1.yang@intel.com<mailto:liang1.yang@intel.com>
diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
index 691bc881fb..3a08caafa5 100644
--- a/hw/usb/host-libusb.c
+++ b/hw/usb/host-libusb.c
@@ -885,6 +885,15 @@ static void usb_host_ep_update(USBHostDevice *s)
trace_usb_host_parse_config(s->bus_num, s->addr,
conf->bConfigurationValue, true);
+ /* Log and skip if configuration is NULL or has no interfaces */
+ if (!conf || conf->bNumInterfaces == 0) {
+ warn_report("usb-host: ignoring invalid configuration "
+ "for device %s (bus=%03d, addr=%03d)",
+ udev->product_desc ? udev->product_desc : "unknown",
+ s->bus_num, s->addr);
+ return;
+ }
+
for (i = 0; i < conf->bNumInterfaces; i++) {
/*
* The udev->altsetting array indexes alternate settings
@@ -896,7 +905,21 @@ static void usb_host_ep_update(USBHostDevice *s)
alt = udev->altsetting[intf->bInterfaceNumber];
if (alt != 0) {
- assert(alt < conf->interface[i].num_altsetting);
+ if (alt >= conf->interface[i].num_altsetting) {
+ /*
+ * Recommend fix: sometimes libusb reports a temporary
+ * invalid altsetting index during fast hotplug/unplug.
+ * Instead of aborting, log a warning and skip the interface.
+ */
+ warn_report("usb-host: ignoring invalid altsetting=%d (max=%d) "
+ "for interface=%d on %s (bus=%03d, addr=%03d)",
+ alt,
+ conf->interface[i].num_altsetting ? conf->interface[i].num_altsetting - 1 : -1,
+ i,
+ udev->product_desc ? udev->product_desc : "unknown",
+ s->bus_num, s->addr);
+ continue;
+ }
intf = &conf->interface[i].altsetting[alt];
}
Best regards,
Yang Liang
© 2016 - 2025 Red Hat, Inc.