aboutsummaryrefslogtreecommitdiffstats
path: root/virt/kvm/irq_comm.c
diff options
context:
space:
mode:
authorAlexander Graf <agraf@suse.de>2013-04-15 17:23:21 -0400
committerAlexander Graf <agraf@suse.de>2013-04-26 14:27:18 -0400
commite8cde0939d8ebe9c8ebe5a4bdf71af51a0d56053 (patch)
tree94d17c8818957e916cba928103a6a8bcdb4d6d6d /virt/kvm/irq_comm.c
parent1c9f8520bda73c07fed9bcdb307854b45a3a60c4 (diff)
KVM: Move irq routing setup to irqchip.c
Setting up IRQ routes is nothing IOAPIC specific. Extract everything that really is generic code into irqchip.c and only leave the ioapic specific bits to irq_comm.c. Signed-off-by: Alexander Graf <agraf@suse.de> Acked-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'virt/kvm/irq_comm.c')
-rw-r--r--virt/kvm/irq_comm.c76
1 files changed, 3 insertions, 73 deletions
diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c
index d5008f4aade7..e2e6b4473a96 100644
--- a/virt/kvm/irq_comm.c
+++ b/virt/kvm/irq_comm.c
@@ -271,27 +271,14 @@ void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin,
271 rcu_read_unlock(); 271 rcu_read_unlock();
272} 272}
273 273
274static int setup_routing_entry(struct kvm_irq_routing_table *rt, 274int kvm_set_routing_entry(struct kvm_irq_routing_table *rt,
275 struct kvm_kernel_irq_routing_entry *e, 275 struct kvm_kernel_irq_routing_entry *e,
276 const struct kvm_irq_routing_entry *ue) 276 const struct kvm_irq_routing_entry *ue)
277{ 277{
278 int r = -EINVAL; 278 int r = -EINVAL;
279 int delta; 279 int delta;
280 unsigned max_pin; 280 unsigned max_pin;
281 struct kvm_kernel_irq_routing_entry *ei;
282 281
283 /*
284 * Do not allow GSI to be mapped to the same irqchip more than once.
285 * Allow only one to one mapping between GSI and MSI.
286 */
287 hlist_for_each_entry(ei, &rt->map[ue->gsi], link)
288 if (ei->type == KVM_IRQ_ROUTING_MSI ||
289 ue->type == KVM_IRQ_ROUTING_MSI ||
290 ue->u.irqchip.irqchip == ei->irqchip.irqchip)
291 return r;
292
293 e->gsi = ue->gsi;
294 e->type = ue->type;
295 switch (ue->type) { 282 switch (ue->type) {
296 case KVM_IRQ_ROUTING_IRQCHIP: 283 case KVM_IRQ_ROUTING_IRQCHIP:
297 delta = 0; 284 delta = 0;
@@ -328,68 +315,11 @@ static int setup_routing_entry(struct kvm_irq_routing_table *rt,
328 goto out; 315 goto out;
329 } 316 }
330 317
331 hlist_add_head(&e->link, &rt->map[e->gsi]);
332 r = 0; 318 r = 0;
333out: 319out:
334 return r; 320 return r;
335} 321}
336 322
337int kvm_set_irq_routing(struct kvm *kvm,
338 const struct kvm_irq_routing_entry *ue,
339 unsigned nr,
340 unsigned flags)
341{
342 struct kvm_irq_routing_table *new, *old;
343 u32 i, j, nr_rt_entries = 0;
344 int r;
345
346 for (i = 0; i < nr; ++i) {
347 if (ue[i].gsi >= KVM_MAX_IRQ_ROUTES)
348 return -EINVAL;
349 nr_rt_entries = max(nr_rt_entries, ue[i].gsi);
350 }
351
352 nr_rt_entries += 1;
353
354 new = kzalloc(sizeof(*new) + (nr_rt_entries * sizeof(struct hlist_head))
355 + (nr * sizeof(struct kvm_kernel_irq_routing_entry)),
356 GFP_KERNEL);
357
358 if (!new)
359 return -ENOMEM;
360
361 new->rt_entries = (void *)&new->map[nr_rt_entries];
362
363 new->nr_rt_entries = nr_rt_entries;
364 for (i = 0; i < 3; i++)
365 for (j = 0; j < KVM_IRQCHIP_NUM_PINS; j++)
366 new->chip[i][j] = -1;
367
368 for (i = 0; i < nr; ++i) {
369 r = -EINVAL;
370 if (ue->flags)
371 goto out;
372 r = setup_routing_entry(new, &new->rt_entries[i], ue);
373 if (r)
374 goto out;
375 ++ue;
376 }
377
378 mutex_lock(&kvm->irq_lock);
379 old = kvm->irq_routing;
380 kvm_irq_routing_update(kvm, new);
381 mutex_unlock(&kvm->irq_lock);
382
383 synchronize_rcu();
384
385 new = old;
386 r = 0;
387
388out:
389 kfree(new);
390 return r;
391}
392
393#define IOAPIC_ROUTING_ENTRY(irq) \ 323#define IOAPIC_ROUTING_ENTRY(irq) \
394 { .gsi = irq, .type = KVM_IRQ_ROUTING_IRQCHIP, \ 324 { .gsi = irq, .type = KVM_IRQ_ROUTING_IRQCHIP, \
395 .u.irqchip.irqchip = KVM_IRQCHIP_IOAPIC, .u.irqchip.pin = (irq) } 325 .u.irqchip.irqchip = KVM_IRQCHIP_IOAPIC, .u.irqchip.pin = (irq) }