aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/i8259.c
diff options
context:
space:
mode:
authorGleb Natapov <gleb@redhat.com>2010-07-15 05:24:37 -0400
committerAvi Kivity <avi@redhat.com>2010-08-01 23:40:52 -0400
commit9195c4da26bbf8860e2e7b648dbf4ab465c7933a (patch)
treeba35ca2f03d5fd7bdfc776e608d6ed215b14ce06 /arch/x86/kvm/i8259.c
parent68be0803456b3eed33038be5566710ad7648c854 (diff)
KVM: x86: Call mask notifiers from pic
If pit delivers interrupt while pic is masking it OS will never do EOI and ack notifier will not be called so when pit will be unmasked no pit interrupts will be delivered any more. Calling mask notifiers solves this issue. Signed-off-by: Gleb Natapov <gleb@redhat.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'arch/x86/kvm/i8259.c')
-rw-r--r--arch/x86/kvm/i8259.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c
index 819b748a33f9..8d10c063d7f2 100644
--- a/arch/x86/kvm/i8259.c
+++ b/arch/x86/kvm/i8259.c
@@ -363,10 +363,20 @@ static void pic_ioport_write(void *opaque, u32 addr, u32 val)
363 } 363 }
364 } else 364 } else
365 switch (s->init_state) { 365 switch (s->init_state) {
366 case 0: /* normal mode */ 366 case 0: { /* normal mode */
367 u8 imr_diff = s->imr ^ val,
368 off = (s == &s->pics_state->pics[0]) ? 0 : 8;
367 s->imr = val; 369 s->imr = val;
370 for (irq = 0; irq < PIC_NUM_PINS/2; irq++)
371 if (imr_diff & (1 << irq))
372 kvm_fire_mask_notifiers(
373 s->pics_state->kvm,
374 SELECT_PIC(irq + off),
375 irq + off,
376 !!(s->imr & (1 << irq)));
368 pic_update_irq(s->pics_state); 377 pic_update_irq(s->pics_state);
369 break; 378 break;
379 }
370 case 1: 380 case 1:
371 s->irq_base = val & 0xf8; 381 s->irq_base = val & 0xf8;
372 s->init_state = 2; 382 s->init_state = 2;