> qemu hack: > > hw/usb/hcd-ohci.c | 11 +++++++++++ > hw/usb/hcd-ohci.h | 1 + > 2 files changed, 12 insertions(+) > > diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c > index fc8fc91a1d..99e52ad13a 100644 > --- a/hw/usb/hcd-ohci.c > +++ b/hw/usb/hcd-ohci.c > @@ -267,6 +267,10 @@ static inline void ohci_intr_update(OHCIState *ohci) > (ohci->intr_status & ohci->intr)) > level = 1; > > + if (level && ohci->level) > + qemu_set_irq(ohci->irq, 0); > + > + ohci->level = level; > qemu_set_irq(ohci->irq, level); > } > > diff --git a/hw/usb/hcd-ohci.h b/hw/usb/hcd-ohci.h > index e1827227ac..6f82e72bd9 100644 > --- a/hw/usb/hcd-ohci.h > +++ b/hw/usb/hcd-ohci.h > @@ -52,6 +52,7 @@ struct OHCIState { > uint32_t ctl, status; > uint32_t intr_status; > uint32_t intr; > + int level; > > /* memory pointer partition */ > uint32_t hcca; Phew. Disclaimer: Havn't looked at the ohci emulation code for years. It should not be needed to store the interrupt level that way. It is possible to calculate what the interrupt level should be, based on the interrupt status register and the interrupt mask register, and the code above seems to do exactly that (the "ohci->intr_status & ohci->intr" bit). ohci_intr_update() must be called if one of these two registers changes, i.e. if the guest changes the mask, if the guest acks an IRQ by clearing an status bit, if the device raises an IRQ by setting an status bit. Might be the ohci emulation has a bug here. Another possible trouble spot is that the timing behavior is different on virtual vs. physical hardware. Specifically with the emulated hardware some actions appear to complete instantly (when the vmexit to handle the mmio register write returns it's finished already), which will never complete that quickly on physical hardware. So drivers can have race conditions which only trigger on virtual hardware. The error pattern you are describing sounds like this could be the case here. HTH & take care, Gerd