summaryrefslogtreecommitdiffstats
path: root/virt/kvm/ioapic.h
diff options
context:
space:
mode:
authorZhang Haoyu <zhanghy@sangfor.com>2014-09-11 10:47:04 +0200
committerPaolo Bonzini <pbonzini@redhat.com>2014-09-16 14:44:48 +0200
commit184564efae4d775225c8fe3b762a56956fb1f827 (patch)
treece6630689fb883ec69b5c18e299b638c4b1b9454 /virt/kvm/ioapic.h
parentKVM: x86: Use kvm_make_request when applicable (diff)
downloadlinux-184564efae4d775225c8fe3b762a56956fb1f827.tar.xz
linux-184564efae4d775225c8fe3b762a56956fb1f827.zip
kvm: ioapic: conditionally delay irq delivery duringeoi broadcast
Currently, we call ioapic_service() immediately when we find the irq is still active during eoi broadcast. But for real hardware, there's some delay between the EOI writing and irq delivery. If we do not emulate this behavior, and re-inject the interrupt immediately after the guest sends an EOI and re-enables interrupts, a guest might spend all its time in the ISR if it has a broken handler for a level-triggered interrupt. Such livelock actually happens with Windows guests when resuming from hibernation. As there's no way to recognize the broken handle from new raised ones, this patch delays an interrupt if 10.000 consecutive EOIs found that the interrupt was still high. The guest can then make a little forward progress, until a proper IRQ handler is set or until some detection routine in the guest (such as Linux's note_interrupt()) recognizes the situation. Cc: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Jason Wang <jasowang@redhat.com> Signed-off-by: Zhang Haoyu <zhanghy@sangfor.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'virt/kvm/ioapic.h')
-rw-r--r--virt/kvm/ioapic.h2
1 files changed, 2 insertions, 0 deletions
diff --git a/virt/kvm/ioapic.h b/virt/kvm/ioapic.h
index 90d43e95dcf8..e23b70634f1e 100644
--- a/virt/kvm/ioapic.h
+++ b/virt/kvm/ioapic.h
@@ -59,6 +59,8 @@ struct kvm_ioapic {
spinlock_t lock;
DECLARE_BITMAP(handled_vectors, 256);
struct rtc_status rtc_status;
+ struct delayed_work eoi_inject;
+ u32 irq_eoi[IOAPIC_NUM_PINS];
};
#ifdef DEBUG