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.c51
1 files changed, 40 insertions, 11 deletions
diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c
index ddc17f0e2f35..001663ff401a 100644
--- a/virt/kvm/irq_comm.c
+++ b/virt/kvm/irq_comm.c
@@ -20,6 +20,7 @@
20 */ 20 */
21 21
22#include <linux/kvm_host.h> 22#include <linux/kvm_host.h>
23#include <trace/events/kvm.h>
23 24
24#include <asm/msidef.h> 25#include <asm/msidef.h>
25#ifdef CONFIG_IA64 26#ifdef CONFIG_IA64
@@ -62,14 +63,14 @@ int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src,
62 int i, r = -1; 63 int i, r = -1;
63 struct kvm_vcpu *vcpu, *lowest = NULL; 64 struct kvm_vcpu *vcpu, *lowest = NULL;
64 65
66 WARN_ON(!mutex_is_locked(&kvm->irq_lock));
67
65 if (irq->dest_mode == 0 && irq->dest_id == 0xff && 68 if (irq->dest_mode == 0 && irq->dest_id == 0xff &&
66 kvm_is_dm_lowest_prio(irq)) 69 kvm_is_dm_lowest_prio(irq))
67 printk(KERN_INFO "kvm: apic: phys broadcast and lowest prio\n"); 70 printk(KERN_INFO "kvm: apic: phys broadcast and lowest prio\n");
68 71
69 for (i = 0; i < KVM_MAX_VCPUS; i++) { 72 kvm_for_each_vcpu(i, vcpu, kvm) {
70 vcpu = kvm->vcpus[i]; 73 if (!kvm_apic_present(vcpu))
71
72 if (!vcpu || !kvm_apic_present(vcpu))
73 continue; 74 continue;
74 75
75 if (!kvm_apic_match_dest(vcpu, src, irq->shorthand, 76 if (!kvm_apic_match_dest(vcpu, src, irq->shorthand,
@@ -99,6 +100,8 @@ static int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e,
99{ 100{
100 struct kvm_lapic_irq irq; 101 struct kvm_lapic_irq irq;
101 102
103 trace_kvm_msi_set_irq(e->msi.address_lo, e->msi.data);
104
102 irq.dest_id = (e->msi.address_lo & 105 irq.dest_id = (e->msi.address_lo &
103 MSI_ADDR_DEST_ID_MASK) >> MSI_ADDR_DEST_ID_SHIFT; 106 MSI_ADDR_DEST_ID_MASK) >> MSI_ADDR_DEST_ID_SHIFT;
104 irq.vector = (e->msi.data & 107 irq.vector = (e->msi.data &
@@ -113,7 +116,7 @@ static int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e,
113 return kvm_irq_delivery_to_apic(kvm, NULL, &irq); 116 return kvm_irq_delivery_to_apic(kvm, NULL, &irq);
114} 117}
115 118
116/* This should be called with the kvm->lock mutex held 119/* This should be called with the kvm->irq_lock mutex held
117 * Return value: 120 * Return value:
118 * < 0 Interrupt was ignored (masked or not delivered for other reasons) 121 * < 0 Interrupt was ignored (masked or not delivered for other reasons)
119 * = 0 Interrupt was coalesced (previous irq is still pending) 122 * = 0 Interrupt was coalesced (previous irq is still pending)
@@ -125,6 +128,10 @@ int kvm_set_irq(struct kvm *kvm, int irq_source_id, int irq, int level)
125 unsigned long *irq_state, sig_level; 128 unsigned long *irq_state, sig_level;
126 int ret = -1; 129 int ret = -1;
127 130
131 trace_kvm_set_irq(irq, level, irq_source_id);
132
133 WARN_ON(!mutex_is_locked(&kvm->irq_lock));
134
128 if (irq < KVM_IOAPIC_NUM_PINS) { 135 if (irq < KVM_IOAPIC_NUM_PINS) {
129 irq_state = (unsigned long *)&kvm->arch.irq_states[irq]; 136 irq_state = (unsigned long *)&kvm->arch.irq_states[irq];
130 137
@@ -134,7 +141,9 @@ int kvm_set_irq(struct kvm *kvm, int irq_source_id, int irq, int level)
134 else 141 else
135 clear_bit(irq_source_id, irq_state); 142 clear_bit(irq_source_id, irq_state);
136 sig_level = !!(*irq_state); 143 sig_level = !!(*irq_state);
137 } else /* Deal with MSI/MSI-X */ 144 } else if (!level)
145 return ret;
146 else /* Deal with MSI/MSI-X */
138 sig_level = 1; 147 sig_level = 1;
139 148
140 /* Not possible to detect if the guest uses the PIC or the 149 /* Not possible to detect if the guest uses the PIC or the
@@ -159,6 +168,8 @@ void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin)
159 struct hlist_node *n; 168 struct hlist_node *n;
160 unsigned gsi = pin; 169 unsigned gsi = pin;
161 170
171 trace_kvm_ack_irq(irqchip, pin);
172
162 list_for_each_entry(e, &kvm->irq_routing, link) 173 list_for_each_entry(e, &kvm->irq_routing, link)
163 if (e->type == KVM_IRQ_ROUTING_IRQCHIP && 174 if (e->type == KVM_IRQ_ROUTING_IRQCHIP &&
164 e->irqchip.irqchip == irqchip && 175 e->irqchip.irqchip == irqchip &&
@@ -175,19 +186,26 @@ void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin)
175void kvm_register_irq_ack_notifier(struct kvm *kvm, 186void kvm_register_irq_ack_notifier(struct kvm *kvm,
176 struct kvm_irq_ack_notifier *kian) 187 struct kvm_irq_ack_notifier *kian)
177{ 188{
189 mutex_lock(&kvm->irq_lock);
178 hlist_add_head(&kian->link, &kvm->arch.irq_ack_notifier_list); 190 hlist_add_head(&kian->link, &kvm->arch.irq_ack_notifier_list);
191 mutex_unlock(&kvm->irq_lock);
179} 192}
180 193
181void kvm_unregister_irq_ack_notifier(struct kvm_irq_ack_notifier *kian) 194void kvm_unregister_irq_ack_notifier(struct kvm *kvm,
195 struct kvm_irq_ack_notifier *kian)
182{ 196{
197 mutex_lock(&kvm->irq_lock);
183 hlist_del_init(&kian->link); 198 hlist_del_init(&kian->link);
199 mutex_unlock(&kvm->irq_lock);
184} 200}
185 201
186/* The caller must hold kvm->lock mutex */
187int kvm_request_irq_source_id(struct kvm *kvm) 202int kvm_request_irq_source_id(struct kvm *kvm)
188{ 203{
189 unsigned long *bitmap = &kvm->arch.irq_sources_bitmap; 204 unsigned long *bitmap = &kvm->arch.irq_sources_bitmap;
190 int irq_source_id = find_first_zero_bit(bitmap, 205 int irq_source_id;
206
207 mutex_lock(&kvm->irq_lock);
208 irq_source_id = find_first_zero_bit(bitmap,
191 sizeof(kvm->arch.irq_sources_bitmap)); 209 sizeof(kvm->arch.irq_sources_bitmap));
192 210
193 if (irq_source_id >= sizeof(kvm->arch.irq_sources_bitmap)) { 211 if (irq_source_id >= sizeof(kvm->arch.irq_sources_bitmap)) {
@@ -197,6 +215,7 @@ int kvm_request_irq_source_id(struct kvm *kvm)
197 215
198 ASSERT(irq_source_id != KVM_USERSPACE_IRQ_SOURCE_ID); 216 ASSERT(irq_source_id != KVM_USERSPACE_IRQ_SOURCE_ID);
199 set_bit(irq_source_id, bitmap); 217 set_bit(irq_source_id, bitmap);
218 mutex_unlock(&kvm->irq_lock);
200 219
201 return irq_source_id; 220 return irq_source_id;
202} 221}
@@ -207,6 +226,7 @@ void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id)
207 226
208 ASSERT(irq_source_id != KVM_USERSPACE_IRQ_SOURCE_ID); 227 ASSERT(irq_source_id != KVM_USERSPACE_IRQ_SOURCE_ID);
209 228
229 mutex_lock(&kvm->irq_lock);
210 if (irq_source_id < 0 || 230 if (irq_source_id < 0 ||
211 irq_source_id >= sizeof(kvm->arch.irq_sources_bitmap)) { 231 irq_source_id >= sizeof(kvm->arch.irq_sources_bitmap)) {
212 printk(KERN_ERR "kvm: IRQ source ID out of range!\n"); 232 printk(KERN_ERR "kvm: IRQ source ID out of range!\n");
@@ -215,19 +235,24 @@ void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id)
215 for (i = 0; i < KVM_IOAPIC_NUM_PINS; i++) 235 for (i = 0; i < KVM_IOAPIC_NUM_PINS; i++)
216 clear_bit(irq_source_id, &kvm->arch.irq_states[i]); 236 clear_bit(irq_source_id, &kvm->arch.irq_states[i]);
217 clear_bit(irq_source_id, &kvm->arch.irq_sources_bitmap); 237 clear_bit(irq_source_id, &kvm->arch.irq_sources_bitmap);
238 mutex_unlock(&kvm->irq_lock);
218} 239}
219 240
220void kvm_register_irq_mask_notifier(struct kvm *kvm, int irq, 241void kvm_register_irq_mask_notifier(struct kvm *kvm, int irq,
221 struct kvm_irq_mask_notifier *kimn) 242 struct kvm_irq_mask_notifier *kimn)
222{ 243{
244 mutex_lock(&kvm->irq_lock);
223 kimn->irq = irq; 245 kimn->irq = irq;
224 hlist_add_head(&kimn->link, &kvm->mask_notifier_list); 246 hlist_add_head(&kimn->link, &kvm->mask_notifier_list);
247 mutex_unlock(&kvm->irq_lock);
225} 248}
226 249
227void kvm_unregister_irq_mask_notifier(struct kvm *kvm, int irq, 250void kvm_unregister_irq_mask_notifier(struct kvm *kvm, int irq,
228 struct kvm_irq_mask_notifier *kimn) 251 struct kvm_irq_mask_notifier *kimn)
229{ 252{
253 mutex_lock(&kvm->irq_lock);
230 hlist_del(&kimn->link); 254 hlist_del(&kimn->link);
255 mutex_unlock(&kvm->irq_lock);
231} 256}
232 257
233void kvm_fire_mask_notifiers(struct kvm *kvm, int irq, bool mask) 258void kvm_fire_mask_notifiers(struct kvm *kvm, int irq, bool mask)
@@ -235,6 +260,8 @@ void kvm_fire_mask_notifiers(struct kvm *kvm, int irq, bool mask)
235 struct kvm_irq_mask_notifier *kimn; 260 struct kvm_irq_mask_notifier *kimn;
236 struct hlist_node *n; 261 struct hlist_node *n;
237 262
263 WARN_ON(!mutex_is_locked(&kvm->irq_lock));
264
238 hlist_for_each_entry(kimn, n, &kvm->mask_notifier_list, link) 265 hlist_for_each_entry(kimn, n, &kvm->mask_notifier_list, link)
239 if (kimn->irq == irq) 266 if (kimn->irq == irq)
240 kimn->func(kimn, mask); 267 kimn->func(kimn, mask);
@@ -250,7 +277,9 @@ static void __kvm_free_irq_routing(struct list_head *irq_routing)
250 277
251void kvm_free_irq_routing(struct kvm *kvm) 278void kvm_free_irq_routing(struct kvm *kvm)
252{ 279{
280 mutex_lock(&kvm->irq_lock);
253 __kvm_free_irq_routing(&kvm->irq_routing); 281 __kvm_free_irq_routing(&kvm->irq_routing);
282 mutex_unlock(&kvm->irq_lock);
254} 283}
255 284
256static int setup_routing_entry(struct kvm_kernel_irq_routing_entry *e, 285static int setup_routing_entry(struct kvm_kernel_irq_routing_entry *e,
@@ -325,13 +354,13 @@ int kvm_set_irq_routing(struct kvm *kvm,
325 e = NULL; 354 e = NULL;
326 } 355 }
327 356
328 mutex_lock(&kvm->lock); 357 mutex_lock(&kvm->irq_lock);
329 list_splice(&kvm->irq_routing, &tmp); 358 list_splice(&kvm->irq_routing, &tmp);
330 INIT_LIST_HEAD(&kvm->irq_routing); 359 INIT_LIST_HEAD(&kvm->irq_routing);
331 list_splice(&irq_list, &kvm->irq_routing); 360 list_splice(&irq_list, &kvm->irq_routing);
332 INIT_LIST_HEAD(&irq_list); 361 INIT_LIST_HEAD(&irq_list);
333 list_splice(&tmp, &irq_list); 362 list_splice(&tmp, &irq_list);
334 mutex_unlock(&kvm->lock); 363 mutex_unlock(&kvm->irq_lock);
335 364
336 r = 0; 365 r = 0;
337 366