diff options
author | Sheng Yang <sheng@linux.intel.com> | 2009-02-11 03:03:40 -0500 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2009-06-10 04:48:22 -0400 |
commit | bfd349d073b2838a6a031f057d25e266619b7093 (patch) | |
tree | b2b2f2f3f99a7e860fb7bb7c54ce322700055ebd | |
parent | 110c2faeba1f1994bcb1de55b9c31f4147dbfdb6 (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.c | 7 | ||||
-rw-r--r-- | virt/kvm/ioapic.c | 24 | ||||
-rw-r--r-- | virt/kvm/irq_comm.c | 17 |
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, | |||
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) |