diff options
Diffstat (limited to 'virt')
-rw-r--r-- | virt/kvm/ioapic.c | 24 | ||||
-rw-r--r-- | virt/kvm/irq_comm.c | 17 |
2 files changed, 22 insertions, 19 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 == |
diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c index d4421cd6d663..d165e056f79b 100644 --- a/virt/kvm/irq_comm.c +++ b/virt/kvm/irq_comm.c | |||
@@ -56,7 +56,7 @@ void kvm_get_intr_delivery_bitmask(struct kvm_ioapic *ioapic, | |||
56 | case IOAPIC_LOWEST_PRIORITY: | 56 | case IOAPIC_LOWEST_PRIORITY: |
57 | vcpu = kvm_get_lowest_prio_vcpu(ioapic->kvm, | 57 | vcpu = kvm_get_lowest_prio_vcpu(ioapic->kvm, |
58 | entry->fields.vector, deliver_bitmask); | 58 | entry->fields.vector, deliver_bitmask); |
59 | *deliver_bitmask = 1 << vcpu->vcpu_id; | 59 | __set_bit(vcpu->vcpu_id, deliver_bitmask); |
60 | break; | 60 | break; |
61 | case IOAPIC_FIXED: | 61 | case IOAPIC_FIXED: |
62 | case IOAPIC_NMI: | 62 | case IOAPIC_NMI: |
@@ -76,10 +76,12 @@ static int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e, | |||
76 | struct kvm_vcpu *vcpu; | 76 | struct kvm_vcpu *vcpu; |
77 | struct kvm_ioapic *ioapic = ioapic_irqchip(kvm); | 77 | struct kvm_ioapic *ioapic = ioapic_irqchip(kvm); |
78 | union kvm_ioapic_redirect_entry entry; | 78 | union kvm_ioapic_redirect_entry entry; |
79 | unsigned long deliver_bitmask; | 79 | DECLARE_BITMAP(deliver_bitmask, KVM_MAX_VCPUS); |
80 | 80 | ||
81 | BUG_ON(!ioapic); | 81 | BUG_ON(!ioapic); |
82 | 82 | ||
83 | bitmap_zero(deliver_bitmask, KVM_MAX_VCPUS); | ||
84 | |||
83 | entry.bits = 0; | 85 | entry.bits = 0; |
84 | entry.fields.dest_id = (e->msi.address_lo & | 86 | entry.fields.dest_id = (e->msi.address_lo & |
85 | MSI_ADDR_DEST_ID_MASK) >> MSI_ADDR_DEST_ID_SHIFT; | 87 | MSI_ADDR_DEST_ID_MASK) >> MSI_ADDR_DEST_ID_SHIFT; |
@@ -95,16 +97,15 @@ static int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e, | |||
95 | 97 | ||
96 | /* TODO Deal with RH bit of MSI message address */ | 98 | /* TODO Deal with RH bit of MSI message address */ |
97 | 99 | ||
98 | kvm_get_intr_delivery_bitmask(ioapic, &entry, &deliver_bitmask); | 100 | kvm_get_intr_delivery_bitmask(ioapic, &entry, deliver_bitmask); |
99 | 101 | ||
100 | if (!deliver_bitmask) { | 102 | if (find_first_bit(deliver_bitmask, KVM_MAX_VCPUS) >= KVM_MAX_VCPUS) { |
101 | printk(KERN_WARNING "kvm: no destination for MSI delivery!"); | 103 | printk(KERN_WARNING "kvm: no destination for MSI delivery!"); |
102 | return -1; | 104 | return -1; |
103 | } | 105 | } |
104 | for (vcpu_id = 0; deliver_bitmask != 0; vcpu_id++) { | 106 | while ((vcpu_id = find_first_bit(deliver_bitmask, |
105 | if (!(deliver_bitmask & (1 << vcpu_id))) | 107 | KVM_MAX_VCPUS)) < KVM_MAX_VCPUS) { |
106 | continue; | 108 | __clear_bit(vcpu_id, deliver_bitmask); |
107 | deliver_bitmask &= ~(1 << vcpu_id); | ||
108 | vcpu = ioapic->kvm->vcpus[vcpu_id]; | 109 | vcpu = ioapic->kvm->vcpus[vcpu_id]; |
109 | if (vcpu) { | 110 | if (vcpu) { |
110 | if (r < 0) | 111 | if (r < 0) |