usb-host: device never reattached after its third re-enumeration (errcount never reset on successful open)

Host environment

  • Operating system: Proxmox VE 9.2 (pve-manager/9.2.10)
  • OS/kernel version: Linux pve 7.0.14-11-pve #1 SMP PREEMPT_DYNAMIC PMX 7.0.14-11 (2026-08-06T23:36Z) x86_64 GNU/Linux
  • Architecture: x86_64
  • QEMU flavor: qemu-system-x86_64
  • QEMU version: 11.0.3 (Proxmox pve-qemu-kvm 11.0.3-2)
  • QEMU command line (USB part of the Proxmox-generated line; the rest is disks, network and TPM):
    /usr/bin/kvm -machine type=pc-q35-11.0+pve0 -m 4096 -smp 8 -cpu host \
      -device 'qemu-xhci,p2=15,p3=15,id=xhci,bus=pci.1,addr=0x1b' \
      -device 'usb-host,bus=xhci.0,port=1,hostbus=3,hostport=1,id=usb0'

Emulated/Virtualized environment

  • Operating system: Windows PE
  • OS/kernel version: n/a (the failure is on the host side: QEMU stops opening the host device; the guest only sees it disappear)
  • Architecture: x86_64

Description of problem

A USB device passed through by host bus/port is reattached after it re-enumerates (reboots itself and comes back with a new address) the first two times. After the third time QEMU never opens it again: the host kernel binds its own drivers (usbhid, usb-storage, cdc_acm) and the guest loses the device until the usb-host device is removed and re-added.

Cause, from usb_host_auto_check() in hw/usb/host-libusb.c (unchanged in master): it stops opening a matching device once s->errcount >= 3, and resets errcount only when a scan finds no matching device at all; a successful open does not reset it. On each re-enumeration QEMU gets NO_DEVICE, closes the handle and rescans immediately; libusb still lists the old address, so that open fails (errcount + 1). The 2 s rescan then opens the new address, but errcount keeps its value. The port is empty for under 1 s, so no scan resets it, and the third re-enumeration reaches 3.

Steps to reproduce

  1. Pass a USB device through by port (hostbus=3,hostport=1).
  2. Make the device re-enumerate (a firmware reboot; ~0.8 s off the bus).
  3. Repeat: the 1st and 2nd reattach after ~2 s, the 3rd never does.

Reproduced every time; re-adding the usb-host device resets it. A device that stays off the bus for more than 2 s does not trigger it (the empty scan resets errcount).

Additional information

Trace (log trace:usb_host_*, transfers removed). Good re-enumeration:

usb_host_close dev 3:24
usb_host_release_interface dev 3:24, if 0
kvm: libusb_release_interface: -4 [NO_DEVICE]
...
usb_host_open_started dev 3:24
usb_host_open_failure dev 3:24
usb_host_open_started dev 3:25
usb_host_open_success dev 3:25

Third one; nothing follows for 20+ minutes:

usb_host_close dev 3:25
usb_host_release_interface dev 3:25, if 0
kvm: libusb_release_interface: -4 [NO_DEVICE]
...
usb_host_open_started dev 3:25
usb_host_open_failure dev 3:25

Proposed fix (also attached as a patch): reset the count after a successful open, so it limits consecutive failures only.

--- a/hw/usb/host-libusb.c
+++ b/hw/usb/host-libusb.c
@@ -1056,6 +1056,7 @@
     }
 
     trace_usb_host_open_success(bus_num, addr);
+    s->errcount = 0;
     return 0;
 
 fail:

The analysis of the QEMU source and trace was done with the help of an LLM (Claude); I reproduced the failure and its predicted pattern (third re-enumeration fails, re-add recovers) on my host.

0001-usb-host-reset-errcount-on-successful-open.patch