diff options
author | Sheng Yang <sheng@linux.intel.com> | 2009-03-04 00:33:02 -0500 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2009-06-10 04:48:26 -0400 |
commit | 74a3a8f152053394a016518cc2f2fee216897fa4 (patch) | |
tree | 96e2d2a9a8583836280063fde54323715ff8d90a /virt/kvm/irq_comm.c | |
parent | 3f5e06f8799adca3e7e1bbafe1cd780a3e69f604 (diff) |
KVM: Merge kvm_ioapic_get_delivery_bitmask into kvm_get_intr_delivery_bitmask
Gleb fixed bitmap ops usage in kvm_ioapic_get_delivery_bitmask.
Sheng merged two functions, as well as fixed several issues in
kvm_get_intr_delivery_bitmask
1. deliver_bitmask is a bitmap rather than a unsigned long intereger.
2. Lowest priority target bitmap wrong calculated by mistake.
3. Prevent potential NULL reference.
4. Declaration in include/kvm_host.h caused powerpc compilation warning.
5. Add warning for guest broadcast interrupt with lowest priority delivery mode.
6. Removed duplicate bitmap clean up in caller of kvm_get_intr_delivery_bitmask.
Signed-off-by: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Sheng Yang <sheng@linux.intel.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'virt/kvm/irq_comm.c')
-rw-r--r-- | virt/kvm/irq_comm.c | 49 |
1 files changed, 43 insertions, 6 deletions
diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c index d165e056f79b..1c6ff6d1b842 100644 --- a/virt/kvm/irq_comm.c +++ b/virt/kvm/irq_comm.c | |||
@@ -47,15 +47,54 @@ void kvm_get_intr_delivery_bitmask(struct kvm_ioapic *ioapic, | |||
47 | union kvm_ioapic_redirect_entry *entry, | 47 | union kvm_ioapic_redirect_entry *entry, |
48 | unsigned long *deliver_bitmask) | 48 | unsigned long *deliver_bitmask) |
49 | { | 49 | { |
50 | int i; | ||
51 | struct kvm *kvm = ioapic->kvm; | ||
50 | struct kvm_vcpu *vcpu; | 52 | struct kvm_vcpu *vcpu; |
51 | 53 | ||
52 | kvm_ioapic_get_delivery_bitmask(ioapic, entry->fields.dest_id, | 54 | bitmap_zero(deliver_bitmask, KVM_MAX_VCPUS); |
53 | entry->fields.dest_mode, | 55 | |
54 | deliver_bitmask); | 56 | if (entry->fields.dest_mode == 0) { /* Physical mode. */ |
57 | if (entry->fields.dest_id == 0xFF) { /* Broadcast. */ | ||
58 | for (i = 0; i < KVM_MAX_VCPUS; ++i) | ||
59 | if (kvm->vcpus[i] && kvm->vcpus[i]->arch.apic) | ||
60 | __set_bit(i, deliver_bitmask); | ||
61 | /* Lowest priority shouldn't combine with broadcast */ | ||
62 | if (entry->fields.delivery_mode == | ||
63 | IOAPIC_LOWEST_PRIORITY && printk_ratelimit()) | ||
64 | printk(KERN_INFO "kvm: apic: phys broadcast " | ||
65 | "and lowest prio\n"); | ||
66 | return; | ||
67 | } | ||
68 | for (i = 0; i < KVM_MAX_VCPUS; ++i) { | ||
69 | vcpu = kvm->vcpus[i]; | ||
70 | if (!vcpu) | ||
71 | continue; | ||
72 | if (kvm_apic_match_physical_addr(vcpu->arch.apic, | ||
73 | entry->fields.dest_id)) { | ||
74 | if (vcpu->arch.apic) | ||
75 | __set_bit(i, deliver_bitmask); | ||
76 | break; | ||
77 | } | ||
78 | } | ||
79 | } else if (entry->fields.dest_id != 0) /* Logical mode, MDA non-zero. */ | ||
80 | for (i = 0; i < KVM_MAX_VCPUS; ++i) { | ||
81 | vcpu = kvm->vcpus[i]; | ||
82 | if (!vcpu) | ||
83 | continue; | ||
84 | if (vcpu->arch.apic && | ||
85 | kvm_apic_match_logical_addr(vcpu->arch.apic, | ||
86 | entry->fields.dest_id)) | ||
87 | __set_bit(i, deliver_bitmask); | ||
88 | } | ||
89 | |||
55 | switch (entry->fields.delivery_mode) { | 90 | switch (entry->fields.delivery_mode) { |
56 | case IOAPIC_LOWEST_PRIORITY: | 91 | case IOAPIC_LOWEST_PRIORITY: |
92 | /* Select one in deliver_bitmask */ | ||
57 | vcpu = kvm_get_lowest_prio_vcpu(ioapic->kvm, | 93 | vcpu = kvm_get_lowest_prio_vcpu(ioapic->kvm, |
58 | entry->fields.vector, deliver_bitmask); | 94 | entry->fields.vector, deliver_bitmask); |
95 | bitmap_zero(deliver_bitmask, KVM_MAX_VCPUS); | ||
96 | if (!vcpu) | ||
97 | return; | ||
59 | __set_bit(vcpu->vcpu_id, deliver_bitmask); | 98 | __set_bit(vcpu->vcpu_id, deliver_bitmask); |
60 | break; | 99 | break; |
61 | case IOAPIC_FIXED: | 100 | case IOAPIC_FIXED: |
@@ -65,7 +104,7 @@ void kvm_get_intr_delivery_bitmask(struct kvm_ioapic *ioapic, | |||
65 | if (printk_ratelimit()) | 104 | if (printk_ratelimit()) |
66 | printk(KERN_INFO "kvm: unsupported delivery mode %d\n", | 105 | printk(KERN_INFO "kvm: unsupported delivery mode %d\n", |
67 | entry->fields.delivery_mode); | 106 | entry->fields.delivery_mode); |
68 | *deliver_bitmask = 0; | 107 | bitmap_zero(deliver_bitmask, KVM_MAX_VCPUS); |
69 | } | 108 | } |
70 | } | 109 | } |
71 | 110 | ||
@@ -80,8 +119,6 @@ static int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e, | |||
80 | 119 | ||
81 | BUG_ON(!ioapic); | 120 | BUG_ON(!ioapic); |
82 | 121 | ||
83 | bitmap_zero(deliver_bitmask, KVM_MAX_VCPUS); | ||
84 | |||
85 | entry.bits = 0; | 122 | entry.bits = 0; |
86 | entry.fields.dest_id = (e->msi.address_lo & | 123 | entry.fields.dest_id = (e->msi.address_lo & |
87 | MSI_ADDR_DEST_ID_MASK) >> MSI_ADDR_DEST_ID_SHIFT; | 124 | MSI_ADDR_DEST_ID_MASK) >> MSI_ADDR_DEST_ID_SHIFT; |