diff options
author | Marcelo Tosatti <mtosatti@redhat.com> | 2008-07-26 16:01:00 -0400 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2008-10-15 04:15:16 -0400 |
commit | f52447261bc8c21dfd4635196e32d2da1352f589 (patch) | |
tree | a0de6cefa7fbfdd07285bd60c4f61e4e2f2d4ed6 /virt | |
parent | 564f15378f04921d5749f27ec53d5e68a6d1d446 (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')
-rw-r--r-- | virt/kvm/ioapic.c | 20 | ||||
-rw-r--r-- | virt/kvm/ioapic.h | 3 |
2 files changed, 15 insertions, 8 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 | ||
288 | static void __kvm_ioapic_update_eoi(struct kvm_ioapic *ioapic, int gsi) | 289 | static 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 | ||
300 | void kvm_ioapic_update_eoi(struct kvm *kvm, int vector) | 306 | void 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 | ||
310 | static int ioapic_in_range(struct kvm_io_device *this, gpa_t addr, | 316 | static int ioapic_in_range(struct kvm_io_device *this, gpa_t addr, |
diff --git a/virt/kvm/ioapic.h b/virt/kvm/ioapic.h index 7f16675fe783..b52732f493c1 100644 --- a/virt/kvm/ioapic.h +++ b/virt/kvm/ioapic.h | |||
@@ -58,6 +58,7 @@ struct kvm_ioapic { | |||
58 | } redirtbl[IOAPIC_NUM_PINS]; | 58 | } redirtbl[IOAPIC_NUM_PINS]; |
59 | struct kvm_io_device dev; | 59 | struct kvm_io_device dev; |
60 | struct kvm *kvm; | 60 | struct kvm *kvm; |
61 | void (*ack_notifier)(void *opaque, int irq); | ||
61 | }; | 62 | }; |
62 | 63 | ||
63 | #ifdef DEBUG | 64 | #ifdef DEBUG |
@@ -87,7 +88,7 @@ static inline int irqchip_in_kernel(struct kvm *kvm) | |||
87 | 88 | ||
88 | struct kvm_vcpu *kvm_get_lowest_prio_vcpu(struct kvm *kvm, u8 vector, | 89 | struct kvm_vcpu *kvm_get_lowest_prio_vcpu(struct kvm *kvm, u8 vector, |
89 | unsigned long bitmap); | 90 | unsigned long bitmap); |
90 | void kvm_ioapic_update_eoi(struct kvm *kvm, int vector); | 91 | void kvm_ioapic_update_eoi(struct kvm *kvm, int vector, int trigger_mode); |
91 | int kvm_ioapic_init(struct kvm *kvm); | 92 | int kvm_ioapic_init(struct kvm *kvm); |
92 | void kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level); | 93 | void kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level); |
93 | void kvm_ioapic_reset(struct kvm_ioapic *ioapic); | 94 | void kvm_ioapic_reset(struct kvm_ioapic *ioapic); |