aboutsummaryrefslogtreecommitdiffstats
path: root/virt/kvm/ioapic.c
diff options
context:
space:
mode:
authorMarcelo Tosatti <mtosatti@redhat.com>2008-07-26 16:01:00 -0400
committerAvi Kivity <avi@qumranet.com>2008-10-15 04:15:16 -0400
commitf52447261bc8c21dfd4635196e32d2da1352f589 (patch)
treea0de6cefa7fbfdd07285bd60c4f61e4e2f2d4ed6 /virt/kvm/ioapic.c
parent564f15378f04921d5749f27ec53d5e68a6d1d446 (diff)
KVM: irq ack notification
Based on a patch from: Ben-Ami Yassour <benami@il.ibm.com> which was based on a patch from: Amit Shah <amit.shah@qumranet.com> Notify IRQ acking on PIC/APIC emulation. The previous patch missed two things: - Edge triggered interrupts on IOAPIC - PIC reset with IRR/ISR set should be equivalent to ack (LAPIC probably needs something similar). Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com> CC: Amit Shah <amit.shah@qumranet.com> CC: Ben-Ami Yassour <benami@il.ibm.com> Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'virt/kvm/ioapic.c')
-rw-r--r--virt/kvm/ioapic.c20
1 files changed, 13 insertions, 7 deletions
diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c
index c0d22870ee9c..515cd7ce761c 100644
--- a/virt/kvm/ioapic.c
+++ b/virt/kvm/ioapic.c
@@ -39,6 +39,7 @@
39 39
40#include "ioapic.h" 40#include "ioapic.h"
41#include "lapic.h" 41#include "lapic.h"
42#include "irq.h"
42 43
43#if 0 44#if 0
44#define ioapic_debug(fmt,arg...) printk(KERN_WARNING fmt,##arg) 45#define ioapic_debug(fmt,arg...) printk(KERN_WARNING fmt,##arg)
@@ -285,26 +286,31 @@ void kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level)
285 } 286 }
286} 287}
287 288
288static void __kvm_ioapic_update_eoi(struct kvm_ioapic *ioapic, int gsi) 289static void __kvm_ioapic_update_eoi(struct kvm_ioapic *ioapic, int gsi,
290 int trigger_mode)
289{ 291{
290 union ioapic_redir_entry *ent; 292 union ioapic_redir_entry *ent;
291 293
292 ent = &ioapic->redirtbl[gsi]; 294 ent = &ioapic->redirtbl[gsi];
293 ASSERT(ent->fields.trig_mode == IOAPIC_LEVEL_TRIG);
294 295
295 ent->fields.remote_irr = 0; 296 kvm_notify_acked_irq(ioapic->kvm, gsi);
296 if (!ent->fields.mask && (ioapic->irr & (1 << gsi))) 297
297 ioapic_service(ioapic, gsi); 298 if (trigger_mode == IOAPIC_LEVEL_TRIG) {
299 ASSERT(ent->fields.trig_mode == IOAPIC_LEVEL_TRIG);
300 ent->fields.remote_irr = 0;
301 if (!ent->fields.mask && (ioapic->irr & (1 << gsi)))
302 ioapic_service(ioapic, gsi);
303 }
298} 304}
299 305
300void kvm_ioapic_update_eoi(struct kvm *kvm, int vector) 306void kvm_ioapic_update_eoi(struct kvm *kvm, int vector, int trigger_mode)
301{ 307{
302 struct kvm_ioapic *ioapic = kvm->arch.vioapic; 308 struct kvm_ioapic *ioapic = kvm->arch.vioapic;
303 int i; 309 int i;
304 310
305 for (i = 0; i < IOAPIC_NUM_PINS; i++) 311 for (i = 0; i < IOAPIC_NUM_PINS; i++)
306 if (ioapic->redirtbl[i].fields.vector == vector) 312 if (ioapic->redirtbl[i].fields.vector == vector)
307 __kvm_ioapic_update_eoi(ioapic, i); 313 __kvm_ioapic_update_eoi(ioapic, i, trigger_mode);
308} 314}
309 315
310static int ioapic_in_range(struct kvm_io_device *this, gpa_t addr, 316static int ioapic_in_range(struct kvm_io_device *this, gpa_t addr,