diff options
Diffstat (limited to 'virt/kvm/ioapic.c')
-rw-r--r-- | virt/kvm/ioapic.c | 24 |
1 files changed, 13 insertions, 11 deletions
diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c index 3b5371299dd1..7c2cb2bd1199 100644 --- a/virt/kvm/ioapic.c +++ b/virt/kvm/ioapic.c | |||
@@ -203,7 +203,7 @@ void kvm_ioapic_get_delivery_bitmask(struct kvm_ioapic *ioapic, u8 dest, | |||
203 | static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq) | 203 | static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq) |
204 | { | 204 | { |
205 | union kvm_ioapic_redirect_entry entry = ioapic->redirtbl[irq]; | 205 | union kvm_ioapic_redirect_entry entry = ioapic->redirtbl[irq]; |
206 | unsigned long deliver_bitmask; | 206 | DECLARE_BITMAP(deliver_bitmask, KVM_MAX_VCPUS); |
207 | struct kvm_vcpu *vcpu; | 207 | struct kvm_vcpu *vcpu; |
208 | int vcpu_id, r = -1; | 208 | int vcpu_id, r = -1; |
209 | 209 | ||
@@ -213,22 +213,24 @@ static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq) | |||
213 | entry.fields.delivery_mode, entry.fields.vector, | 213 | entry.fields.delivery_mode, entry.fields.vector, |
214 | entry.fields.trig_mode); | 214 | entry.fields.trig_mode); |
215 | 215 | ||
216 | kvm_get_intr_delivery_bitmask(ioapic, &entry, &deliver_bitmask); | 216 | bitmap_zero(deliver_bitmask, KVM_MAX_VCPUS); |
217 | if (!deliver_bitmask) { | ||
218 | ioapic_debug("no target on destination\n"); | ||
219 | return 0; | ||
220 | } | ||
221 | 217 | ||
222 | /* Always delivery PIT interrupt to vcpu 0 */ | 218 | /* Always delivery PIT interrupt to vcpu 0 */ |
223 | #ifdef CONFIG_X86 | 219 | #ifdef CONFIG_X86 |
224 | if (irq == 0) | 220 | if (irq == 0) |
225 | deliver_bitmask = 1; | 221 | __set_bit(0, deliver_bitmask); |
222 | else | ||
226 | #endif | 223 | #endif |
224 | kvm_get_intr_delivery_bitmask(ioapic, &entry, deliver_bitmask); | ||
225 | |||
226 | if (find_first_bit(deliver_bitmask, KVM_MAX_VCPUS) >= KVM_MAX_VCPUS) { | ||
227 | ioapic_debug("no target on destination\n"); | ||
228 | return 0; | ||
229 | } | ||
227 | 230 | ||
228 | for (vcpu_id = 0; deliver_bitmask != 0; vcpu_id++) { | 231 | while ((vcpu_id = find_first_bit(deliver_bitmask, KVM_MAX_VCPUS)) |
229 | if (!(deliver_bitmask & (1 << vcpu_id))) | 232 | < KVM_MAX_VCPUS) { |
230 | continue; | 233 | __clear_bit(vcpu_id, deliver_bitmask); |
231 | deliver_bitmask &= ~(1 << vcpu_id); | ||
232 | vcpu = ioapic->kvm->vcpus[vcpu_id]; | 234 | vcpu = ioapic->kvm->vcpus[vcpu_id]; |
233 | if (vcpu) { | 235 | if (vcpu) { |
234 | if (entry.fields.delivery_mode == | 236 | if (entry.fields.delivery_mode == |