aboutsummaryrefslogtreecommitdiffstats
path: root/virt
diff options
context:
space:
mode:
Diffstat (limited to 'virt')
-rw-r--r--virt/kvm/ioapic.c24
-rw-r--r--virt/kvm/irq_comm.c17
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,
203static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq) 203static 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)