diff options
author | Yang Zhang <yang.z.zhang@Intel.com> | 2013-04-11 07:21:37 -0400 |
---|---|---|
committer | Marcelo Tosatti <mtosatti@redhat.com> | 2013-04-15 22:20:34 -0400 |
commit | b4f2225c07dd4d8eef7aa7f5b36a3b72c3cbbe5b (patch) | |
tree | 47cecd1a3cec51c6dee70e8558aa749b744ca0e9 | |
parent | 8dc6aade5bdc9d436d4ab8328cb15f0adbbc47bf (diff) |
KVM: Return destination vcpu on interrupt injection
Add a new parameter to know vcpus who received the interrupt.
Signed-off-by: Yang Zhang <yang.z.zhang@Intel.com>
Reviewed-by: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
-rw-r--r-- | arch/x86/kvm/lapic.c | 25 | ||||
-rw-r--r-- | arch/x86/kvm/lapic.h | 5 | ||||
-rw-r--r-- | virt/kvm/ioapic.c | 2 | ||||
-rw-r--r-- | virt/kvm/ioapic.h | 2 | ||||
-rw-r--r-- | virt/kvm/irq_comm.c | 12 |
5 files changed, 27 insertions, 19 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 | } |
diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h index baa20cfb95ae..3e5a43160cb7 100644 --- a/arch/x86/kvm/lapic.h +++ b/arch/x86/kvm/lapic.h | |||
@@ -55,11 +55,12 @@ void kvm_apic_set_version(struct kvm_vcpu *vcpu); | |||
55 | 55 | ||
56 | int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest); | 56 | int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest); |
57 | int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda); | 57 | int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda); |
58 | int kvm_apic_set_irq(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq); | 58 | int kvm_apic_set_irq(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq, |
59 | unsigned long *dest_map); | ||
59 | int kvm_apic_local_deliver(struct kvm_lapic *apic, int lvt_type); | 60 | int kvm_apic_local_deliver(struct kvm_lapic *apic, int lvt_type); |
60 | 61 | ||
61 | bool kvm_irq_delivery_to_apic_fast(struct kvm *kvm, struct kvm_lapic *src, | 62 | bool kvm_irq_delivery_to_apic_fast(struct kvm *kvm, struct kvm_lapic *src, |
62 | struct kvm_lapic_irq *irq, int *r); | 63 | struct kvm_lapic_irq *irq, int *r, unsigned long *dest_map); |
63 | 64 | ||
64 | u64 kvm_get_apic_base(struct kvm_vcpu *vcpu); | 65 | u64 kvm_get_apic_base(struct kvm_vcpu *vcpu); |
65 | void kvm_set_apic_base(struct kvm_vcpu *vcpu, u64 data); | 66 | void kvm_set_apic_base(struct kvm_vcpu *vcpu, u64 data); |
diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c index 1d8906d39214..27ae8dd64e29 100644 --- a/virt/kvm/ioapic.c +++ b/virt/kvm/ioapic.c | |||
@@ -217,7 +217,7 @@ static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq) | |||
217 | irqe.level = 1; | 217 | irqe.level = 1; |
218 | irqe.shorthand = 0; | 218 | irqe.shorthand = 0; |
219 | 219 | ||
220 | return kvm_irq_delivery_to_apic(ioapic->kvm, NULL, &irqe); | 220 | return kvm_irq_delivery_to_apic(ioapic->kvm, NULL, &irqe, NULL); |
221 | } | 221 | } |
222 | 222 | ||
223 | int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int irq_source_id, | 223 | int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int irq_source_id, |
diff --git a/virt/kvm/ioapic.h b/virt/kvm/ioapic.h index 87cd94bae372..761e5b57099e 100644 --- a/virt/kvm/ioapic.h +++ b/virt/kvm/ioapic.h | |||
@@ -92,7 +92,7 @@ int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int irq_source_id, | |||
92 | void kvm_ioapic_clear_all(struct kvm_ioapic *ioapic, int irq_source_id); | 92 | void kvm_ioapic_clear_all(struct kvm_ioapic *ioapic, int irq_source_id); |
93 | void kvm_ioapic_reset(struct kvm_ioapic *ioapic); | 93 | void kvm_ioapic_reset(struct kvm_ioapic *ioapic); |
94 | int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src, | 94 | int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src, |
95 | struct kvm_lapic_irq *irq); | 95 | struct kvm_lapic_irq *irq, unsigned long *dest_map); |
96 | int kvm_get_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state); | 96 | int kvm_get_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state); |
97 | int kvm_set_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state); | 97 | int kvm_set_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state); |
98 | void kvm_ioapic_make_eoibitmap_request(struct kvm *kvm); | 98 | void kvm_ioapic_make_eoibitmap_request(struct kvm *kvm); |
diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c index e9073cf4d040..2f07d2e59a2d 100644 --- a/virt/kvm/irq_comm.c +++ b/virt/kvm/irq_comm.c | |||
@@ -63,7 +63,7 @@ inline static bool kvm_is_dm_lowest_prio(struct kvm_lapic_irq *irq) | |||
63 | } | 63 | } |
64 | 64 | ||
65 | int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src, | 65 | int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src, |
66 | struct kvm_lapic_irq *irq) | 66 | struct kvm_lapic_irq *irq, unsigned long *dest_map) |
67 | { | 67 | { |
68 | int i, r = -1; | 68 | int i, r = -1; |
69 | struct kvm_vcpu *vcpu, *lowest = NULL; | 69 | struct kvm_vcpu *vcpu, *lowest = NULL; |
@@ -74,7 +74,7 @@ int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src, | |||
74 | irq->delivery_mode = APIC_DM_FIXED; | 74 | irq->delivery_mode = APIC_DM_FIXED; |
75 | } | 75 | } |
76 | 76 | ||
77 | if (kvm_irq_delivery_to_apic_fast(kvm, src, irq, &r)) | 77 | if (kvm_irq_delivery_to_apic_fast(kvm, src, irq, &r, dest_map)) |
78 | return r; | 78 | return r; |
79 | 79 | ||
80 | kvm_for_each_vcpu(i, vcpu, kvm) { | 80 | kvm_for_each_vcpu(i, vcpu, kvm) { |
@@ -88,7 +88,7 @@ int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src, | |||
88 | if (!kvm_is_dm_lowest_prio(irq)) { | 88 | if (!kvm_is_dm_lowest_prio(irq)) { |
89 | if (r < 0) | 89 | if (r < 0) |
90 | r = 0; | 90 | r = 0; |
91 | r += kvm_apic_set_irq(vcpu, irq); | 91 | r += kvm_apic_set_irq(vcpu, irq, dest_map); |
92 | } else if (kvm_lapic_enabled(vcpu)) { | 92 | } else if (kvm_lapic_enabled(vcpu)) { |
93 | if (!lowest) | 93 | if (!lowest) |
94 | lowest = vcpu; | 94 | lowest = vcpu; |
@@ -98,7 +98,7 @@ int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src, | |||
98 | } | 98 | } |
99 | 99 | ||
100 | if (lowest) | 100 | if (lowest) |
101 | r = kvm_apic_set_irq(lowest, irq); | 101 | r = kvm_apic_set_irq(lowest, irq, dest_map); |
102 | 102 | ||
103 | return r; | 103 | return r; |
104 | } | 104 | } |
@@ -130,7 +130,7 @@ int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e, | |||
130 | 130 | ||
131 | kvm_set_msi_irq(e, &irq); | 131 | kvm_set_msi_irq(e, &irq); |
132 | 132 | ||
133 | return kvm_irq_delivery_to_apic(kvm, NULL, &irq); | 133 | return kvm_irq_delivery_to_apic(kvm, NULL, &irq, NULL); |
134 | } | 134 | } |
135 | 135 | ||
136 | 136 | ||
@@ -142,7 +142,7 @@ static int kvm_set_msi_inatomic(struct kvm_kernel_irq_routing_entry *e, | |||
142 | 142 | ||
143 | kvm_set_msi_irq(e, &irq); | 143 | kvm_set_msi_irq(e, &irq); |
144 | 144 | ||
145 | if (kvm_irq_delivery_to_apic_fast(kvm, NULL, &irq, &r)) | 145 | if (kvm_irq_delivery_to_apic_fast(kvm, NULL, &irq, &r, NULL)) |
146 | return r; | 146 | return r; |
147 | else | 147 | else |
148 | return -EWOULDBLOCK; | 148 | return -EWOULDBLOCK; |