pci_xhci_deassert_interrupt() asserted the INTx line when MSI was off,
and nothing else ever deasserted it. The UEFI firmware writes IMAN with
IE clear when it starts the controller, so from then on the line stayed
up until the guest driver enabled MSI. A guest that uses INTx, or a
device sharing the pin with the xHCI, sees an interrupt after every EOI.
Follow the specification instead: INTx stays asserted only while
USBCMD.INTE is set and the interrupter has IMAN.IP and IMAN.IE set.
Re-evaluate that after every write to IMAN and USBCMD, and after a
write to ERDP that clears EHB, which here also clears IMAN.IP. Without
the latter the line stays up when an event arrives while the guest's
handler runs: the handler consumes it and acknowledges it through ERDP,
and then sees thousands of interrupts with nothing pending until the
next event.
Signed-off-by: Wanpeng Qian <wanpengqian@gmail.com>
Sponsored by: keelos.dev