diff options
Diffstat (limited to 'arch/x86/kvm/lapic.c')
-rw-r--r-- | arch/x86/kvm/lapic.c | 25 |
1 files changed, 16 insertions, 9 deletions
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 3e22536a7031..0b734025fc87 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c | |||
@@ -384,14 +384,16 @@ int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu) | |||
384 | } | 384 | } |
385 | 385 | ||
386 | static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode, | 386 | static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode, |
387 | int vector, int level, int trig_mode); | 387 | int vector, int level, int trig_mode, |
388 | unsigned long *dest_map); | ||
388 | 389 | ||
389 | int kvm_apic_set_irq(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq) | 390 | int kvm_apic_set_irq(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq, |
391 | unsigned long *dest_map) | ||
390 | { | 392 | { |
391 | struct kvm_lapic *apic = vcpu->arch.apic; | 393 | struct kvm_lapic *apic = vcpu->arch.apic; |
392 | 394 | ||
393 | return __apic_accept_irq(apic, irq->delivery_mode, irq->vector, | 395 | return __apic_accept_irq(apic, irq->delivery_mode, irq->vector, |
394 | irq->level, irq->trig_mode); | 396 | irq->level, irq->trig_mode, dest_map); |
395 | } | 397 | } |
396 | 398 | ||
397 | static int pv_eoi_put_user(struct kvm_vcpu *vcpu, u8 val) | 399 | static int pv_eoi_put_user(struct kvm_vcpu *vcpu, u8 val) |
@@ -564,7 +566,7 @@ int kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source, | |||
564 | } | 566 | } |
565 | 567 | ||
566 | bool kvm_irq_delivery_to_apic_fast(struct kvm *kvm, struct kvm_lapic *src, | 568 | bool kvm_irq_delivery_to_apic_fast(struct kvm *kvm, struct kvm_lapic *src, |
567 | struct kvm_lapic_irq *irq, int *r) | 569 | struct kvm_lapic_irq *irq, int *r, unsigned long *dest_map) |
568 | { | 570 | { |
569 | struct kvm_apic_map *map; | 571 | struct kvm_apic_map *map; |
570 | unsigned long bitmap = 1; | 572 | unsigned long bitmap = 1; |
@@ -575,7 +577,7 @@ bool kvm_irq_delivery_to_apic_fast(struct kvm *kvm, struct kvm_lapic *src, | |||
575 | *r = -1; | 577 | *r = -1; |
576 | 578 | ||
577 | if (irq->shorthand == APIC_DEST_SELF) { | 579 | if (irq->shorthand == APIC_DEST_SELF) { |
578 | *r = kvm_apic_set_irq(src->vcpu, irq); | 580 | *r = kvm_apic_set_irq(src->vcpu, irq, dest_map); |
579 | return true; | 581 | return true; |
580 | } | 582 | } |
581 | 583 | ||
@@ -620,7 +622,7 @@ bool kvm_irq_delivery_to_apic_fast(struct kvm *kvm, struct kvm_lapic *src, | |||
620 | continue; | 622 | continue; |
621 | if (*r < 0) | 623 | if (*r < 0) |
622 | *r = 0; | 624 | *r = 0; |
623 | *r += kvm_apic_set_irq(dst[i]->vcpu, irq); | 625 | *r += kvm_apic_set_irq(dst[i]->vcpu, irq, dest_map); |
624 | } | 626 | } |
625 | 627 | ||
626 | ret = true; | 628 | ret = true; |
@@ -634,7 +636,8 @@ out: | |||
634 | * Return 1 if successfully added and 0 if discarded. | 636 | * Return 1 if successfully added and 0 if discarded. |
635 | */ | 637 | */ |
636 | static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode, | 638 | static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode, |
637 | int vector, int level, int trig_mode) | 639 | int vector, int level, int trig_mode, |
640 | unsigned long *dest_map) | ||
638 | { | 641 | { |
639 | int result = 0; | 642 | int result = 0; |
640 | struct kvm_vcpu *vcpu = apic->vcpu; | 643 | struct kvm_vcpu *vcpu = apic->vcpu; |
@@ -647,6 +650,9 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode, | |||
647 | if (unlikely(!apic_enabled(apic))) | 650 | if (unlikely(!apic_enabled(apic))) |
648 | break; | 651 | break; |
649 | 652 | ||
653 | if (dest_map) | ||
654 | __set_bit(vcpu->vcpu_id, dest_map); | ||
655 | |||
650 | if (trig_mode) { | 656 | if (trig_mode) { |
651 | apic_debug("level trig mode for vector %d", vector); | 657 | apic_debug("level trig mode for vector %d", vector); |
652 | apic_set_vector(vector, apic->regs + APIC_TMR); | 658 | apic_set_vector(vector, apic->regs + APIC_TMR); |
@@ -805,7 +811,7 @@ static void apic_send_ipi(struct kvm_lapic *apic) | |||
805 | irq.trig_mode, irq.level, irq.dest_mode, irq.delivery_mode, | 811 | irq.trig_mode, irq.level, irq.dest_mode, irq.delivery_mode, |
806 | irq.vector); | 812 | irq.vector); |
807 | 813 | ||
808 | kvm_irq_delivery_to_apic(apic->vcpu->kvm, apic, &irq); | 814 | kvm_irq_delivery_to_apic(apic->vcpu->kvm, apic, &irq, NULL); |
809 | } | 815 | } |
810 | 816 | ||
811 | static u32 apic_get_tmcct(struct kvm_lapic *apic) | 817 | static u32 apic_get_tmcct(struct kvm_lapic *apic) |
@@ -1441,7 +1447,8 @@ int kvm_apic_local_deliver(struct kvm_lapic *apic, int lvt_type) | |||
1441 | vector = reg & APIC_VECTOR_MASK; | 1447 | vector = reg & APIC_VECTOR_MASK; |
1442 | mode = reg & APIC_MODE_MASK; | 1448 | mode = reg & APIC_MODE_MASK; |
1443 | trig_mode = reg & APIC_LVT_LEVEL_TRIGGER; | 1449 | trig_mode = reg & APIC_LVT_LEVEL_TRIGGER; |
1444 | return __apic_accept_irq(apic, mode, vector, 1, trig_mode); | 1450 | return __apic_accept_irq(apic, mode, vector, 1, trig_mode, |
1451 | NULL); | ||
1445 | } | 1452 | } |
1446 | return 0; | 1453 | return 0; |
1447 | } | 1454 | } |