summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGleb Natapov <gleb@redhat.com>2012-07-26 10:00:45 +0300
committerAvi Kivity <avi@redhat.com>2012-07-26 12:19:06 +0300
commitaea218f3cbbcaac249b6b2c98930a00d6d931f1e (patch)
treea21917407b485a5cbd21741e0d7a42dd6bf4a578
parentbdc0077af574800d24318b6945cf2344e8dbb050 (diff)
downloadlinux-3.10-aea218f3cbbcaac249b6b2c98930a00d6d931f1e.tar.gz
linux-3.10-aea218f3cbbcaac249b6b2c98930a00d6d931f1e.tar.bz2
linux-3.10-aea218f3cbbcaac249b6b2c98930a00d6d931f1e.zip
KVM: PIC: call ack notifiers for irqs that are dropped form irr
After commit 242ec97c358256 PIT interrupts are no longer delivered after PIC reset. It happens because PIT injects interrupt only if previous one was acked, but since on PIC reset it is dropped from irr it will never be delivered and hence acknowledged. Fix that by calling ack notifier on PIC reset. Signed-off-by: Gleb Natapov <gleb@redhat.com> Signed-off-by: Avi Kivity <avi@redhat.com>
-rw-r--r--arch/x86/kvm/i8259.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c
index 1df8fb9e1d5..e498b18f010 100644
--- a/arch/x86/kvm/i8259.c
+++ b/arch/x86/kvm/i8259.c
@@ -316,6 +316,11 @@ static void pic_ioport_write(void *opaque, u32 addr, u32 val)
addr &= 1;
if (addr == 0) {
if (val & 0x10) {
+ u8 edge_irr = s->irr & ~s->elcr;
+ int i;
+ bool found;
+ struct kvm_vcpu *vcpu;
+
s->init4 = val & 1;
s->last_irr = 0;
s->irr &= s->elcr;
@@ -333,6 +338,18 @@ static void pic_ioport_write(void *opaque, u32 addr, u32 val)
if (val & 0x08)
pr_pic_unimpl(
"level sensitive irq not supported");
+
+ kvm_for_each_vcpu(i, vcpu, s->pics_state->kvm)
+ if (kvm_apic_accept_pic_intr(vcpu)) {
+ found = true;
+ break;
+ }
+
+
+ if (found)
+ for (irq = 0; irq < PIC_NUM_PINS/2; irq++)
+ if (edge_irr & (1 << irq))
+ pic_clear_isr(s, irq);
} else if (val & 0x08) {
if (val & 0x04)
s->poll = 1;