aboutsummaryrefslogtreecommitdiffstats
path: root/virt/kvm/ioapic.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/ioapic.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/ioapic.c')
-rw-r--r--virt/kvm/ioapic.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c
index 1c986ac59ad6..c3b99def9cbc 100644
--- a/virt/kvm/ioapic.c
+++ b/virt/kvm/ioapic.c
@@ -83,19 +83,22 @@ static unsigned long ioapic_read_indirect(struct kvm_ioapic *ioapic,
83 return result; 83 return result;
84} 84}
85 85
86static void ioapic_service(struct kvm_ioapic *ioapic, unsigned int idx) 86static int ioapic_service(struct kvm_ioapic *ioapic, unsigned int idx)
87{ 87{
88 union ioapic_redir_entry *pent; 88 union ioapic_redir_entry *pent;
89 int injected = -1;
89 90
90 pent = &ioapic->redirtbl[idx]; 91 pent = &ioapic->redirtbl[idx];
91 92
92 if (!pent->fields.mask) { 93 if (!pent->fields.mask) {
93 int injected = ioapic_deliver(ioapic, idx); 94 injected = ioapic_deliver(ioapic, idx);
94 if (injected && pent->fields.trig_mode == IOAPIC_LEVEL_TRIG) 95 if (injected && pent->fields.trig_mode == IOAPIC_LEVEL_TRIG)
95 pent->fields.remote_irr = 1; 96 pent->fields.remote_irr = 1;
96 } 97 }
97 if (!pent->fields.trig_mode) 98 if (!pent->fields.trig_mode)
98 ioapic->irr &= ~(1 << idx); 99 ioapic->irr &= ~(1 << idx);
100
101 return injected;
99} 102}
100 103
101static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val) 104static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val)
@@ -207,7 +210,7 @@ static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq)
207 u8 trig_mode = ioapic->redirtbl[irq].fields.trig_mode; 210 u8 trig_mode = ioapic->redirtbl[irq].fields.trig_mode;
208 u32 deliver_bitmask; 211 u32 deliver_bitmask;
209 struct kvm_vcpu *vcpu; 212 struct kvm_vcpu *vcpu;
210 int vcpu_id, r = 0; 213 int vcpu_id, r = -1;
211 214
212 ioapic_debug("dest=%x dest_mode=%x delivery_mode=%x " 215 ioapic_debug("dest=%x dest_mode=%x delivery_mode=%x "
213 "vector=%x trig_mode=%x\n", 216 "vector=%x trig_mode=%x\n",
@@ -247,7 +250,9 @@ static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq)
247 deliver_bitmask &= ~(1 << vcpu_id); 250 deliver_bitmask &= ~(1 << vcpu_id);
248 vcpu = ioapic->kvm->vcpus[vcpu_id]; 251 vcpu = ioapic->kvm->vcpus[vcpu_id];
249 if (vcpu) { 252 if (vcpu) {
250 r = ioapic_inj_irq(ioapic, vcpu, vector, 253 if (r < 0)
254 r = 0;
255 r += ioapic_inj_irq(ioapic, vcpu, vector,
251 trig_mode, delivery_mode); 256 trig_mode, delivery_mode);
252 } 257 }
253 } 258 }
@@ -258,8 +263,10 @@ static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq)
258 continue; 263 continue;
259 deliver_bitmask &= ~(1 << vcpu_id); 264 deliver_bitmask &= ~(1 << vcpu_id);
260 vcpu = ioapic->kvm->vcpus[vcpu_id]; 265 vcpu = ioapic->kvm->vcpus[vcpu_id];
261 if (vcpu) 266 if (vcpu) {
262 ioapic_inj_nmi(vcpu); 267 ioapic_inj_nmi(vcpu);
268 r = 1;
269 }
263 else 270 else
264 ioapic_debug("NMI to vcpu %d failed\n", 271 ioapic_debug("NMI to vcpu %d failed\n",
265 vcpu->vcpu_id); 272 vcpu->vcpu_id);
@@ -273,11 +280,12 @@ static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq)
273 return r; 280 return r;
274} 281}
275 282
276void kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level) 283int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level)
277{ 284{
278 u32 old_irr = ioapic->irr; 285 u32 old_irr = ioapic->irr;
279 u32 mask = 1 << irq; 286 u32 mask = 1 << irq;
280 union ioapic_redir_entry entry; 287 union ioapic_redir_entry entry;
288 int ret = 1;
281 289
282 if (irq >= 0 && irq < IOAPIC_NUM_PINS) { 290 if (irq >= 0 && irq < IOAPIC_NUM_PINS) {
283 entry = ioapic->redirtbl[irq]; 291 entry = ioapic->redirtbl[irq];
@@ -288,9 +296,10 @@ void kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level)
288 ioapic->irr |= mask; 296 ioapic->irr |= mask;
289 if ((!entry.fields.trig_mode && old_irr != ioapic->irr) 297 if ((!entry.fields.trig_mode && old_irr != ioapic->irr)
290 || !entry.fields.remote_irr) 298 || !entry.fields.remote_irr)
291 ioapic_service(ioapic, irq); 299 ret = ioapic_service(ioapic, irq);
292 } 300 }
293 } 301 }
302 return ret;
294} 303}
295 304
296static void __kvm_ioapic_update_eoi(struct kvm_ioapic *ioapic, int pin, 305static void __kvm_ioapic_update_eoi(struct kvm_ioapic *ioapic, int pin,