aboutsummaryrefslogtreecommitdiffstats
path: root/virt/kvm/irq_comm.c
diff options
context:
space:
mode:
authorGleb Natapov <gleb@redhat.com>2009-02-04 10:28:14 -0500
committerAvi Kivity <avi@redhat.com>2009-03-24 05:03:11 -0400
commit4925663a079c77d95d8685228ad6675fc5639c8e (patch)
tree52e93df78b23a44ed21d015f835688f673dd351a /virt/kvm/irq_comm.c
parent452425dbaa1974e9fc489e64a8de46a47b4c2754 (diff)
KVM: Report IRQ injection status to userspace.
IRQ injection status is either -1 (if there was no CPU found that should except the interrupt because IRQ was masked or ioapic was misconfigured or ...) or >= 0 in that case the number indicates to how many CPUs interrupt was injected. If the value is 0 it means that the interrupt was coalesced and probably should be reinjected. Signed-off-by: Gleb Natapov <gleb@redhat.com> Signed-off-by: Avi Kivity <avi@redhat.com>
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: