aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/lapic.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kvm/lapic.c')
-rw-r--r--arch/x86/kvm/lapic.c25
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
386static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode, 386static 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
389int kvm_apic_set_irq(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq) 390int 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
397static int pv_eoi_put_user(struct kvm_vcpu *vcpu, u8 val) 399static 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
566bool kvm_irq_delivery_to_apic_fast(struct kvm *kvm, struct kvm_lapic *src, 568bool 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 */
636static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode, 638static 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
811static u32 apic_get_tmcct(struct kvm_lapic *apic) 817static 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}