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 /virt | |
| 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>
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) |
