aboutsummaryrefslogtreecommitdiffstats
path: root/virt/kvm/irq_comm.c
diff options
context:
space:
mode:
Diffstat (limited to 'virt/kvm/irq_comm.c')
-rw-r--r--virt/kvm/irq_comm.c74
1 files changed, 21 insertions, 53 deletions
diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c
index 35397a569b2..e43701c0a5c 100644
--- a/virt/kvm/irq_comm.c
+++ b/virt/kvm/irq_comm.c
@@ -43,67 +43,35 @@ static int kvm_set_ioapic_irq(struct kvm_kernel_irq_routing_entry *e,
43 return kvm_ioapic_set_irq(kvm->arch.vioapic, e->irqchip.pin, level); 43 return kvm_ioapic_set_irq(kvm->arch.vioapic, e->irqchip.pin, level);
44} 44}
45 45
46void kvm_get_intr_delivery_bitmask(struct kvm *kvm, 46void kvm_get_intr_delivery_bitmask(struct kvm *kvm, struct kvm_lapic *src,
47 union kvm_ioapic_redirect_entry *entry, 47 int dest_id, int dest_mode, bool low_prio, int short_hand,
48 unsigned long *deliver_bitmask) 48 unsigned long *deliver_bitmask)
49{ 49{
50 int i; 50 int i;
51 struct kvm_vcpu *vcpu; 51 struct kvm_vcpu *vcpu;
52 52
53 if (dest_mode == 0 && dest_id == 0xff && low_prio)
54 printk(KERN_INFO "kvm: apic: phys broadcast and lowest prio\n");
55
53 bitmap_zero(deliver_bitmask, KVM_MAX_VCPUS); 56 bitmap_zero(deliver_bitmask, KVM_MAX_VCPUS);
57 for (i = 0; i < KVM_MAX_VCPUS; i++) {
58 vcpu = kvm->vcpus[i];
54 59
55 if (entry->fields.dest_mode == 0) { /* Physical mode. */ 60 if (!vcpu || !kvm_apic_present(vcpu))
56 if (entry->fields.dest_id == 0xFF) { /* Broadcast. */ 61 continue;
57 for (i = 0; i < KVM_MAX_VCPUS; ++i)
58 if (kvm->vcpus[i] && kvm->vcpus[i]->arch.apic)
59 __set_bit(i, deliver_bitmask);
60 /* Lowest priority shouldn't combine with broadcast */
61 if (entry->fields.delivery_mode ==
62 IOAPIC_LOWEST_PRIORITY && printk_ratelimit())
63 printk(KERN_INFO "kvm: apic: phys broadcast "
64 "and lowest prio\n");
65 return;
66 }
67 for (i = 0; i < KVM_MAX_VCPUS; ++i) {
68 vcpu = kvm->vcpus[i];
69 if (!vcpu)
70 continue;
71 if (kvm_apic_match_physical_addr(vcpu->arch.apic,
72 entry->fields.dest_id)) {
73 if (vcpu->arch.apic)
74 __set_bit(i, deliver_bitmask);
75 break;
76 }
77 }
78 } else if (entry->fields.dest_id != 0) /* Logical mode, MDA non-zero. */
79 for (i = 0; i < KVM_MAX_VCPUS; ++i) {
80 vcpu = kvm->vcpus[i];
81 if (!vcpu)
82 continue;
83 if (vcpu->arch.apic &&
84 kvm_apic_match_logical_addr(vcpu->arch.apic,
85 entry->fields.dest_id))
86 __set_bit(i, deliver_bitmask);
87 }
88 62
89 switch (entry->fields.delivery_mode) { 63 if (!kvm_apic_match_dest(vcpu, src, short_hand, dest_id,
90 case IOAPIC_LOWEST_PRIORITY: 64 dest_mode))
91 /* Select one in deliver_bitmask */ 65 continue;
92 vcpu = kvm_get_lowest_prio_vcpu(kvm, 66
93 entry->fields.vector, deliver_bitmask); 67 __set_bit(i, deliver_bitmask);
94 bitmap_zero(deliver_bitmask, KVM_MAX_VCPUS); 68 }
95 if (!vcpu) 69
96 return; 70 if (low_prio) {
97 __set_bit(vcpu->vcpu_id, deliver_bitmask); 71 vcpu = kvm_get_lowest_prio_vcpu(kvm, 0, deliver_bitmask);
98 break;
99 case IOAPIC_FIXED:
100 case IOAPIC_NMI:
101 break;
102 default:
103 if (printk_ratelimit())
104 printk(KERN_INFO "kvm: unsupported delivery mode %d\n",
105 entry->fields.delivery_mode);
106 bitmap_zero(deliver_bitmask, KVM_MAX_VCPUS); 72 bitmap_zero(deliver_bitmask, KVM_MAX_VCPUS);
73 if (vcpu)
74 __set_bit(vcpu->vcpu_id, deliver_bitmask);
107 } 75 }
108} 76}
109 77