aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSheng Yang <sheng@linux.intel.com>2009-02-11 03:03:40 -0500
committerAvi Kivity <avi@redhat.com>2009-06-10 04:48:22 -0400
commitbfd349d073b2838a6a031f057d25e266619b7093 (patch)
treeb2b2f2f3f99a7e860fb7bb7c54ce322700055ebd
parent110c2faeba1f1994bcb1de55b9c31f4147dbfdb6 (diff)
KVM: bit ops for deliver_bitmap
It's also convenient when we extend KVM supported vcpu number in the future. Signed-off-by: Sheng Yang <sheng@linux.intel.com> Signed-off-by: Avi Kivity <avi@redhat.com>
-rw-r--r--arch/x86/kvm/lapic.c7
-rw-r--r--virt/kvm/ioapic.c24
-rw-r--r--virt/kvm/irq_comm.c17
3 files changed, 26 insertions, 22 deletions
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 6aa8d20f9eeb..afc59b2e7e02 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -483,9 +483,10 @@ static void apic_send_ipi(struct kvm_lapic *apic)
483 483
484 struct kvm_vcpu *target; 484 struct kvm_vcpu *target;
485 struct kvm_vcpu *vcpu; 485 struct kvm_vcpu *vcpu;
486 unsigned long lpr_map = 0; 486 DECLARE_BITMAP(lpr_map, KVM_MAX_VCPUS);
487 int i; 487 int i;
488 488
489 bitmap_zero(lpr_map, KVM_MAX_VCPUS);
489 apic_debug("icr_high 0x%x, icr_low 0x%x, " 490 apic_debug("icr_high 0x%x, icr_low 0x%x, "
490 "short_hand 0x%x, dest 0x%x, trig_mode 0x%x, level 0x%x, " 491 "short_hand 0x%x, dest 0x%x, trig_mode 0x%x, level 0x%x, "
491 "dest_mode 0x%x, delivery_mode 0x%x, vector 0x%x\n", 492 "dest_mode 0x%x, delivery_mode 0x%x, vector 0x%x\n",
@@ -500,7 +501,7 @@ static void apic_send_ipi(struct kvm_lapic *apic)
500 if (vcpu->arch.apic && 501 if (vcpu->arch.apic &&
501 apic_match_dest(vcpu, apic, short_hand, dest, dest_mode)) { 502 apic_match_dest(vcpu, apic, short_hand, dest, dest_mode)) {
502 if (delivery_mode == APIC_DM_LOWEST) 503 if (delivery_mode == APIC_DM_LOWEST)
503 set_bit(vcpu->vcpu_id, &lpr_map); 504 __set_bit(vcpu->vcpu_id, lpr_map);
504 else 505 else
505 __apic_accept_irq(vcpu->arch.apic, delivery_mode, 506 __apic_accept_irq(vcpu->arch.apic, delivery_mode,
506 vector, level, trig_mode); 507 vector, level, trig_mode);
@@ -508,7 +509,7 @@ static void apic_send_ipi(struct kvm_lapic *apic)
508 } 509 }
509 510
510 if (delivery_mode == APIC_DM_LOWEST) { 511 if (delivery_mode == APIC_DM_LOWEST) {
511 target = kvm_get_lowest_prio_vcpu(vcpu->kvm, vector, &lpr_map); 512 target = kvm_get_lowest_prio_vcpu(vcpu->kvm, vector, lpr_map);
512 if (target != NULL) 513 if (target != NULL)
513 __apic_accept_irq(target->arch.apic, delivery_mode, 514 __apic_accept_irq(target->arch.apic, delivery_mode,
514 vector, level, trig_mode); 515 vector, level, trig_mode);
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)