diff options
Diffstat (limited to 'virt/kvm/ioapic.c')
| -rw-r--r-- | virt/kvm/ioapic.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c index c0d22870ee9c..53772bb46320 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, |
| @@ -380,7 +386,7 @@ static void ioapic_mmio_write(struct kvm_io_device *this, gpa_t addr, int len, | |||
| 380 | break; | 386 | break; |
| 381 | #ifdef CONFIG_IA64 | 387 | #ifdef CONFIG_IA64 |
| 382 | case IOAPIC_REG_EOI: | 388 | case IOAPIC_REG_EOI: |
| 383 | kvm_ioapic_update_eoi(ioapic->kvm, data); | 389 | kvm_ioapic_update_eoi(ioapic->kvm, data, IOAPIC_LEVEL_TRIG); |
| 384 | break; | 390 | break; |
| 385 | #endif | 391 | #endif |
| 386 | 392 | ||
