- int i;
- struct kvm *kvm = ioapic->kvm;
- struct kvm_vcpu *vcpu;
-
- 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);
- }
-
- switch (entry->fields.delivery_mode) {
- case IOAPIC_LOWEST_PRIORITY:
- /* Select one in deliver_bitmask */
- vcpu = kvm_get_lowest_prio_vcpu(ioapic->kvm,
- entry->fields.vector, deliver_bitmask);
- bitmap_zero(deliver_bitmask, KVM_MAX_VCPUS);
- if (!vcpu)
- return;
- __set_bit(vcpu->vcpu_id, deliver_bitmask);
- break;
- case IOAPIC_FIXED:
- case IOAPIC_NMI:
- break;
- default:
- if (printk_ratelimit())
- printk(KERN_INFO "kvm: unsupported delivery mode %d\n",
- entry->fields.delivery_mode);
- bitmap_zero(deliver_bitmask, KVM_MAX_VCPUS);
- }