]> git.baikalelectronics.ru Git - kernel.git/commit
KVM: IOAPIC: Fix level-triggered irq injection hang
authorMark McLoughlin <markmc@redhat.com>
Fri, 4 Jul 2008 17:23:15 +0000 (18:23 +0100)
committerAvi Kivity <avi@qumranet.com>
Sun, 6 Jul 2008 08:05:35 +0000 (11:05 +0300)
commit39a2e78d61e73ceacd85d9109a34351e5d575527
treef239537b52023a63ab562c2e31b118214c502aa9
parentc6bcf4b02cbeb1b37d743286e736295fa7ea748a
KVM: IOAPIC: Fix level-triggered irq injection hang

The "remote_irr" variable is used to indicate an interrupt
which has been received by the LAPIC, but not acked.

In our EOI handler, we unset remote_irr and re-inject the
interrupt if the interrupt line is still asserted.

However, we do not set remote_irr here, leading to a
situation where if kvm_ioapic_set_irq() is called, then we go
ahead and call ioapic_service(). This means that IRR is
re-asserted even though the interrupt is currently in service
(i.e. LAPIC IRR is cleared and ISR/TMR set)

The issue with this is that when the currently executing
interrupt handler finishes and writes LAPIC EOI, then TMR is
unset and EOI sent to the IOAPIC. Since IRR is now asserted,
but TMR is not, then when the second interrupt is handled,
no EOI is sent and if there is any pending interrupt, it is
not re-injected.

This fixes a hang only seen while running mke2fs -j on an
8Gb virtio disk backed by a fully sparse raw file, with
aliguori "avoid fragmented virtio-blk transfers by copying"
changes.

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