- kvm_ioapic_get_delivery_bitmask(ioapic, entry->fields.dest_id,
- entry->fields.dest_mode,
- deliver_bitmask);
+ bitmap_zero(deliver_bitmask, KVM_MAX_VCPUS);
+
+ if (entry->fields.dest_mode == 0) { /* Physical mode. */
+ if (entry->fields.dest_id == 0xFF) { /* Broadcast. */
+ for (i = 0; i < KVM_MAX_VCPUS; ++i)
+ if (kvm->vcpus[i] && kvm->vcpus[i]->arch.apic)
+ __set_bit(i, deliver_bitmask);
+ /* Lowest priority shouldn't combine with broadcast */
+ if (entry->fields.delivery_mode ==
+ IOAPIC_LOWEST_PRIORITY && printk_ratelimit())
+ printk(KERN_INFO "kvm: apic: phys broadcast "
+ "and lowest prio\n");
+ return;
+ }
+ for (i = 0; i < KVM_MAX_VCPUS; ++i) {
+ vcpu = kvm->vcpus[i];
+ if (!vcpu)
+ continue;
+ if (kvm_apic_match_physical_addr(vcpu->arch.apic,
+ entry->fields.dest_id)) {
+ if (vcpu->arch.apic)
+ __set_bit(i, deliver_bitmask);
+ break;
+ }
+ }
+ } else if (entry->fields.dest_id != 0) /* Logical mode, MDA non-zero. */
+ for (i = 0; i < KVM_MAX_VCPUS; ++i) {
+ vcpu = kvm->vcpus[i];
+ if (!vcpu)
+ continue;
+ if (vcpu->arch.apic &&
+ kvm_apic_match_logical_addr(vcpu->arch.apic,
+ entry->fields.dest_id))
+ __set_bit(i, deliver_bitmask);
+ }
+