A device's reports (the tablet, a keyboard) are delivered on the back end's
own thread through hci_intr (pci_xhci_dev_intr()). It runs the endpoint and
writes the Event Ring without the controller lock, while vCPU threads insert
command-completion and transfer events and recount the ring on ERDP writes
under sc->mtx. Two writers on one ring lose events or leave a slot with a
stale cycle bit, which stops the guest's handler there, and the event count
drifts until the controller reports Event Ring Full.
Observed on a Windows 10 guest driven over a remote-desktop front end: fast
pointer input made Windows reset the controller again and again (Stop
Endpoint then HCRST) and finally give up, leaving the tablet gone.
Take sc->mtx around the device interrupt, the same lock every MMIO access
already holds; nothing calls hci_intr holding it.
Found and fixed in keelOS (keelos.dev).
Signed-off-by: Wanpeng Qian <wanpengqian@gmail.com>
Sponsored by: keelos.dev