aboutsummaryrefslogtreecommitdiffstats
path: root/virt/kvm/irq_comm.c
diff options
context:
space:
mode:
Diffstat (limited to 'virt/kvm/irq_comm.c')
-rw-r--r--virt/kvm/irq_comm.c41
1 files changed, 28 insertions, 13 deletions
diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c
index 6bc7439eff6e..be8aba791554 100644
--- a/virt/kvm/irq_comm.c
+++ b/virt/kvm/irq_comm.c
@@ -29,22 +29,24 @@
29 29
30#include "ioapic.h" 30#include "ioapic.h"
31 31
32static void kvm_set_pic_irq(struct kvm_kernel_irq_routing_entry *e, 32static int kvm_set_pic_irq(struct kvm_kernel_irq_routing_entry *e,
33 struct kvm *kvm, int level) 33 struct kvm *kvm, int level)
34{ 34{
35#ifdef CONFIG_X86 35#ifdef CONFIG_X86
36 kvm_pic_set_irq(pic_irqchip(kvm), e->irqchip.pin, level); 36 return kvm_pic_set_irq(pic_irqchip(kvm), e->irqchip.pin, level);
37#else
38 return -1;
37#endif 39#endif
38} 40}
39 41
40static void kvm_set_ioapic_irq(struct kvm_kernel_irq_routing_entry *e, 42static int kvm_set_ioapic_irq(struct kvm_kernel_irq_routing_entry *e,
41 struct kvm *kvm, int level) 43 struct kvm *kvm, int level)
42{ 44{
43 kvm_ioapic_set_irq(kvm->arch.vioapic, e->irqchip.pin, level); 45 return kvm_ioapic_set_irq(kvm->arch.vioapic, e->irqchip.pin, level);
44} 46}
45 47
46static void kvm_set_msi(struct kvm_kernel_irq_routing_entry *e, 48static int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e,
47 struct kvm *kvm, int level) 49 struct kvm *kvm, int level)
48{ 50{
49 int vcpu_id; 51 int vcpu_id;
50 struct kvm_vcpu *vcpu; 52 struct kvm_vcpu *vcpu;
@@ -88,13 +90,20 @@ static void kvm_set_msi(struct kvm_kernel_irq_routing_entry *e,
88 default: 90 default:
89 break; 91 break;
90 } 92 }
93 return 1;
91} 94}
92 95
93/* This should be called with the kvm->lock mutex held */ 96/* This should be called with the kvm->lock mutex held
94void kvm_set_irq(struct kvm *kvm, int irq_source_id, int irq, int level) 97 * Return value:
98 * < 0 Interrupt was ignored (masked or not delivered for other reasons)
99 * = 0 Interrupt was coalesced (previous irq is still pending)
100 * > 0 Number of CPUs interrupt was delivered to
101 */
102int kvm_set_irq(struct kvm *kvm, int irq_source_id, int irq, int level)
95{ 103{
96 struct kvm_kernel_irq_routing_entry *e; 104 struct kvm_kernel_irq_routing_entry *e;
97 unsigned long *irq_state, sig_level; 105 unsigned long *irq_state, sig_level;
106 int ret = -1;
98 107
99 if (irq < KVM_IOAPIC_NUM_PINS) { 108 if (irq < KVM_IOAPIC_NUM_PINS) {
100 irq_state = (unsigned long *)&kvm->arch.irq_states[irq]; 109 irq_state = (unsigned long *)&kvm->arch.irq_states[irq];
@@ -113,8 +122,14 @@ void kvm_set_irq(struct kvm *kvm, int irq_source_id, int irq, int level)
113 * writes to the unused one. 122 * writes to the unused one.
114 */ 123 */
115 list_for_each_entry(e, &kvm->irq_routing, link) 124 list_for_each_entry(e, &kvm->irq_routing, link)
116 if (e->gsi == irq) 125 if (e->gsi == irq) {
117 e->set(e, kvm, sig_level); 126 int r = e->set(e, kvm, sig_level);
127 if (r < 0)
128 continue;
129
130 ret = r + ((ret < 0) ? 0 : ret);
131 }
132 return ret;
118} 133}
119 134
120void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin) 135void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin)
@@ -232,7 +247,7 @@ int setup_routing_entry(struct kvm_kernel_irq_routing_entry *e,
232 e->set = kvm_set_pic_irq; 247 e->set = kvm_set_pic_irq;
233 break; 248 break;
234 case KVM_IRQCHIP_PIC_SLAVE: 249 case KVM_IRQCHIP_PIC_SLAVE:
235 e->set = kvm_set_pic_irq; 250 e->set = kvm_set_pic_irq;
236 delta = 8; 251 delta = 8;
237 break; 252 break;
238 case KVM_IRQCHIP_IOAPIC: 253 case KVM_IRQCHIP_IOAPIC: