diff options
Diffstat (limited to 'arch/x86/kvm/ioapic.c')
-rw-r--r-- | arch/x86/kvm/ioapic.c | 26 |
1 files changed, 13 insertions, 13 deletions
diff --git a/arch/x86/kvm/ioapic.c b/arch/x86/kvm/ioapic.c index b1947e0f3e10..28146f03c514 100644 --- a/arch/x86/kvm/ioapic.c +++ b/arch/x86/kvm/ioapic.c | |||
@@ -206,6 +206,8 @@ static int ioapic_set_irq(struct kvm_ioapic *ioapic, unsigned int irq, | |||
206 | 206 | ||
207 | old_irr = ioapic->irr; | 207 | old_irr = ioapic->irr; |
208 | ioapic->irr |= mask; | 208 | ioapic->irr |= mask; |
209 | if (edge) | ||
210 | ioapic->irr_delivered &= ~mask; | ||
209 | if ((edge && old_irr == ioapic->irr) || | 211 | if ((edge && old_irr == ioapic->irr) || |
210 | (!edge && entry.fields.remote_irr)) { | 212 | (!edge && entry.fields.remote_irr)) { |
211 | ret = 0; | 213 | ret = 0; |
@@ -349,7 +351,7 @@ static int ioapic_service(struct kvm_ioapic *ioapic, int irq, bool line_status) | |||
349 | irqe.shorthand = 0; | 351 | irqe.shorthand = 0; |
350 | 352 | ||
351 | if (irqe.trig_mode == IOAPIC_EDGE_TRIG) | 353 | if (irqe.trig_mode == IOAPIC_EDGE_TRIG) |
352 | ioapic->irr &= ~(1 << irq); | 354 | ioapic->irr_delivered |= 1 << irq; |
353 | 355 | ||
354 | if (irq == RTC_GSI && line_status) { | 356 | if (irq == RTC_GSI && line_status) { |
355 | /* | 357 | /* |
@@ -422,6 +424,7 @@ static void __kvm_ioapic_update_eoi(struct kvm_vcpu *vcpu, | |||
422 | struct kvm_ioapic *ioapic, int vector, int trigger_mode) | 424 | struct kvm_ioapic *ioapic, int vector, int trigger_mode) |
423 | { | 425 | { |
424 | int i; | 426 | int i; |
427 | struct kvm_lapic *apic = vcpu->arch.apic; | ||
425 | 428 | ||
426 | for (i = 0; i < IOAPIC_NUM_PINS; i++) { | 429 | for (i = 0; i < IOAPIC_NUM_PINS; i++) { |
427 | union kvm_ioapic_redirect_entry *ent = &ioapic->redirtbl[i]; | 430 | union kvm_ioapic_redirect_entry *ent = &ioapic->redirtbl[i]; |
@@ -443,7 +446,8 @@ static void __kvm_ioapic_update_eoi(struct kvm_vcpu *vcpu, | |||
443 | kvm_notify_acked_irq(ioapic->kvm, KVM_IRQCHIP_IOAPIC, i); | 446 | kvm_notify_acked_irq(ioapic->kvm, KVM_IRQCHIP_IOAPIC, i); |
444 | spin_lock(&ioapic->lock); | 447 | spin_lock(&ioapic->lock); |
445 | 448 | ||
446 | if (trigger_mode != IOAPIC_LEVEL_TRIG) | 449 | if (trigger_mode != IOAPIC_LEVEL_TRIG || |
450 | kvm_apic_get_reg(apic, APIC_SPIV) & APIC_SPIV_DIRECTED_EOI) | ||
447 | continue; | 451 | continue; |
448 | 452 | ||
449 | ASSERT(ent->fields.trig_mode == IOAPIC_LEVEL_TRIG); | 453 | ASSERT(ent->fields.trig_mode == IOAPIC_LEVEL_TRIG); |
@@ -471,13 +475,6 @@ static void __kvm_ioapic_update_eoi(struct kvm_vcpu *vcpu, | |||
471 | } | 475 | } |
472 | } | 476 | } |
473 | 477 | ||
474 | bool kvm_ioapic_handles_vector(struct kvm *kvm, int vector) | ||
475 | { | ||
476 | struct kvm_ioapic *ioapic = kvm->arch.vioapic; | ||
477 | smp_rmb(); | ||
478 | return test_bit(vector, ioapic->handled_vectors); | ||
479 | } | ||
480 | |||
481 | void kvm_ioapic_update_eoi(struct kvm_vcpu *vcpu, int vector, int trigger_mode) | 478 | void kvm_ioapic_update_eoi(struct kvm_vcpu *vcpu, int vector, int trigger_mode) |
482 | { | 479 | { |
483 | struct kvm_ioapic *ioapic = vcpu->kvm->arch.vioapic; | 480 | struct kvm_ioapic *ioapic = vcpu->kvm->arch.vioapic; |
@@ -498,8 +495,8 @@ static inline int ioapic_in_range(struct kvm_ioapic *ioapic, gpa_t addr) | |||
498 | (addr < ioapic->base_address + IOAPIC_MEM_LENGTH))); | 495 | (addr < ioapic->base_address + IOAPIC_MEM_LENGTH))); |
499 | } | 496 | } |
500 | 497 | ||
501 | static int ioapic_mmio_read(struct kvm_io_device *this, gpa_t addr, int len, | 498 | static int ioapic_mmio_read(struct kvm_vcpu *vcpu, struct kvm_io_device *this, |
502 | void *val) | 499 | gpa_t addr, int len, void *val) |
503 | { | 500 | { |
504 | struct kvm_ioapic *ioapic = to_ioapic(this); | 501 | struct kvm_ioapic *ioapic = to_ioapic(this); |
505 | u32 result; | 502 | u32 result; |
@@ -541,8 +538,8 @@ static int ioapic_mmio_read(struct kvm_io_device *this, gpa_t addr, int len, | |||
541 | return 0; | 538 | return 0; |
542 | } | 539 | } |
543 | 540 | ||
544 | static int ioapic_mmio_write(struct kvm_io_device *this, gpa_t addr, int len, | 541 | static int ioapic_mmio_write(struct kvm_vcpu *vcpu, struct kvm_io_device *this, |
545 | const void *val) | 542 | gpa_t addr, int len, const void *val) |
546 | { | 543 | { |
547 | struct kvm_ioapic *ioapic = to_ioapic(this); | 544 | struct kvm_ioapic *ioapic = to_ioapic(this); |
548 | u32 data; | 545 | u32 data; |
@@ -597,6 +594,7 @@ static void kvm_ioapic_reset(struct kvm_ioapic *ioapic) | |||
597 | ioapic->base_address = IOAPIC_DEFAULT_BASE_ADDRESS; | 594 | ioapic->base_address = IOAPIC_DEFAULT_BASE_ADDRESS; |
598 | ioapic->ioregsel = 0; | 595 | ioapic->ioregsel = 0; |
599 | ioapic->irr = 0; | 596 | ioapic->irr = 0; |
597 | ioapic->irr_delivered = 0; | ||
600 | ioapic->id = 0; | 598 | ioapic->id = 0; |
601 | memset(ioapic->irq_eoi, 0x00, IOAPIC_NUM_PINS); | 599 | memset(ioapic->irq_eoi, 0x00, IOAPIC_NUM_PINS); |
602 | rtc_irq_eoi_tracking_reset(ioapic); | 600 | rtc_irq_eoi_tracking_reset(ioapic); |
@@ -654,6 +652,7 @@ int kvm_get_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state) | |||
654 | 652 | ||
655 | spin_lock(&ioapic->lock); | 653 | spin_lock(&ioapic->lock); |
656 | memcpy(state, ioapic, sizeof(struct kvm_ioapic_state)); | 654 | memcpy(state, ioapic, sizeof(struct kvm_ioapic_state)); |
655 | state->irr &= ~ioapic->irr_delivered; | ||
657 | spin_unlock(&ioapic->lock); | 656 | spin_unlock(&ioapic->lock); |
658 | return 0; | 657 | return 0; |
659 | } | 658 | } |
@@ -667,6 +666,7 @@ int kvm_set_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state) | |||
667 | spin_lock(&ioapic->lock); | 666 | spin_lock(&ioapic->lock); |
668 | memcpy(ioapic, state, sizeof(struct kvm_ioapic_state)); | 667 | memcpy(ioapic, state, sizeof(struct kvm_ioapic_state)); |
669 | ioapic->irr = 0; | 668 | ioapic->irr = 0; |
669 | ioapic->irr_delivered = 0; | ||
670 | update_handled_vectors(ioapic); | 670 | update_handled_vectors(ioapic); |
671 | kvm_vcpu_request_scan_ioapic(kvm); | 671 | kvm_vcpu_request_scan_ioapic(kvm); |
672 | kvm_ioapic_inject_all(ioapic, state->irr); | 672 | kvm_ioapic_inject_all(ioapic, state->irr); |