KVM: IOAPIC: only set remote_irr if interrupt was injected
authorMarcelo Tosatti <mtosatti@redhat.com>
Thu, 5 Jun 2008 03:08:11 +0000 (00:08 -0300)
committerAvi Kivity <avi@qumranet.com>
Fri, 6 Jun 2008 18:32:39 +0000 (21:32 +0300)
commitff4b9df877b30b8a371d706d3552999dee450738
treef2195b2d4305643b59b78be266e98215a31bdcf4
parent8d2d73b9a5c35f2c6abf427afba7888cfc4cc65d
KVM: IOAPIC: only set remote_irr if interrupt was injected

There's a bug in the IOAPIC code for level-triggered interrupts. Its
relatively easy to trigger by sharing (virtio-blk + usbtablet was the
testcase, initially reported by Gerd von Egidy).

The "remote_irr" variable is used to indicate accepted but not yet acked
interrupts. Its cleared from the EOI handler.

Problem is that the EOI handler clears remote_irr unconditionally, even
if it reinjected another pending interrupt.

In that case, kvm_ioapic_set_irq() proceeds to ioapic_service() which
sets remote_irr even if it failed to inject (since the IRR was high due
to EOI reinjection).

Since the TMR bit has been cleared by the first EOI, the second one
fails to clear remote_irr.

End result is interrupt line dead.

Fix it by setting remote_irr only if a new pending interrupt has been
generated (and the TMR bit for vector in question set).

Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
virt/kvm/ioapic.c