diff options
author | Gleb Natapov <gleb@redhat.com> | 2010-07-15 05:24:37 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2010-08-01 23:40:52 -0400 |
commit | 9195c4da26bbf8860e2e7b648dbf4ab465c7933a (patch) | |
tree | ba35ca2f03d5fd7bdfc776e608d6ed215b14ce06 /arch | |
parent | 68be0803456b3eed33038be5566710ad7648c854 (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')
-rw-r--r-- | arch/x86/kvm/i8259.c | 12 |
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; |