KVM: Split up MSI-X assigned device IRQ handler
[deliverable/linux.git] / virt / kvm / assigned-dev.c
CommitLineData
bfd99ff5
AK
1/*
2 * Kernel-based Virtual Machine - device assignment support
3 *
221d059d 4 * Copyright (C) 2010 Red Hat, Inc. and/or its affiliates.
bfd99ff5
AK
5 *
6 * This work is licensed under the terms of the GNU GPL, version 2. See
7 * the COPYING file in the top-level directory.
8 *
9 */
10
11#include <linux/kvm_host.h>
12#include <linux/kvm.h>
13#include <linux/uaccess.h>
14#include <linux/vmalloc.h>
15#include <linux/errno.h>
16#include <linux/spinlock.h>
17#include <linux/pci.h>
18#include <linux/interrupt.h>
5a0e3ad6 19#include <linux/slab.h>
bfd99ff5
AK
20#include "irq.h"
21
22static struct kvm_assigned_dev_kernel *kvm_find_assigned_dev(struct list_head *head,
23 int assigned_dev_id)
24{
25 struct list_head *ptr;
26 struct kvm_assigned_dev_kernel *match;
27
28 list_for_each(ptr, head) {
29 match = list_entry(ptr, struct kvm_assigned_dev_kernel, list);
30 if (match->assigned_dev_id == assigned_dev_id)
31 return match;
32 }
33 return NULL;
34}
35
36static int find_index_from_host_irq(struct kvm_assigned_dev_kernel
37 *assigned_dev, int irq)
38{
39 int i, index;
40 struct msix_entry *host_msix_entries;
41
42 host_msix_entries = assigned_dev->host_msix_entries;
43
44 index = -1;
45 for (i = 0; i < assigned_dev->entries_nr; i++)
46 if (irq == host_msix_entries[i].vector) {
47 index = i;
48 break;
49 }
50 if (index < 0) {
51 printk(KERN_WARNING "Fail to find correlated MSI-X entry!\n");
52 return 0;
53 }
54
55 return index;
56}
57
0645211c 58static irqreturn_t kvm_assigned_dev_thread(int irq, void *dev_id)
bfd99ff5 59{
0645211c 60 struct kvm_assigned_dev_kernel *assigned_dev = dev_id;
bfd99ff5 61
0645211c
JK
62 if (assigned_dev->irq_requested_type & KVM_DEV_IRQ_HOST_INTX) {
63 spin_lock(&assigned_dev->intx_lock);
64 disable_irq_nosync(irq);
65 assigned_dev->host_irq_disabled = true;
66 spin_unlock(&assigned_dev->intx_lock);
67 }
bfd99ff5 68
cc079396
JK
69 kvm_set_irq(assigned_dev->kvm, assigned_dev->irq_source_id,
70 assigned_dev->guest_irq, 1);
71
72 return IRQ_HANDLED;
73}
74
75#ifdef __KVM_HAVE_MSIX
76static irqreturn_t kvm_assigned_dev_thread_msix(int irq, void *dev_id)
77{
78 struct kvm_assigned_dev_kernel *assigned_dev = dev_id;
79 int index = find_index_from_host_irq(assigned_dev, irq);
80 u32 vector;
81
82 if (index >= 0) {
83 vector = assigned_dev->guest_msix_entries[index].vector;
bfd99ff5 84 kvm_set_irq(assigned_dev->kvm, assigned_dev->irq_source_id,
cc079396
JK
85 vector, 1);
86 }
bfd99ff5 87
bfd99ff5
AK
88 return IRQ_HANDLED;
89}
cc079396 90#endif
bfd99ff5
AK
91
92/* Ack the irq line for an assigned device */
93static void kvm_assigned_dev_ack_irq(struct kvm_irq_ack_notifier *kian)
94{
c61fa9d6
JK
95 struct kvm_assigned_dev_kernel *dev =
96 container_of(kian, struct kvm_assigned_dev_kernel,
97 ack_notifier);
bfd99ff5
AK
98
99 kvm_set_irq(dev->kvm, dev->irq_source_id, dev->guest_irq, 0);
100
101 /* The guest irq may be shared so this ack may be
102 * from another device.
103 */
0645211c 104 spin_lock(&dev->intx_lock);
bfd99ff5
AK
105 if (dev->host_irq_disabled) {
106 enable_irq(dev->host_irq);
107 dev->host_irq_disabled = false;
108 }
0645211c 109 spin_unlock(&dev->intx_lock);
bfd99ff5
AK
110}
111
112static void deassign_guest_irq(struct kvm *kvm,
113 struct kvm_assigned_dev_kernel *assigned_dev)
114{
c61fa9d6
JK
115 if (assigned_dev->ack_notifier.gsi != -1)
116 kvm_unregister_irq_ack_notifier(kvm,
117 &assigned_dev->ack_notifier);
bfd99ff5 118
0c106b5a
JK
119 kvm_set_irq(assigned_dev->kvm, assigned_dev->irq_source_id,
120 assigned_dev->guest_irq, 0);
121
bfd99ff5
AK
122 if (assigned_dev->irq_source_id != -1)
123 kvm_free_irq_source_id(kvm, assigned_dev->irq_source_id);
124 assigned_dev->irq_source_id = -1;
125 assigned_dev->irq_requested_type &= ~(KVM_DEV_IRQ_GUEST_MASK);
126}
127
128/* The function implicit hold kvm->lock mutex due to cancel_work_sync() */
129static void deassign_host_irq(struct kvm *kvm,
130 struct kvm_assigned_dev_kernel *assigned_dev)
131{
132 /*
0645211c 133 * We disable irq here to prevent further events.
bfd99ff5
AK
134 *
135 * Notice this maybe result in nested disable if the interrupt type is
136 * INTx, but it's OK for we are going to free it.
137 *
138 * If this function is a part of VM destroy, please ensure that till
139 * now, the kvm state is still legal for probably we also have to wait
0645211c 140 * on a currently running IRQ handler.
bfd99ff5
AK
141 */
142 if (assigned_dev->irq_requested_type & KVM_DEV_IRQ_HOST_MSIX) {
143 int i;
144 for (i = 0; i < assigned_dev->entries_nr; i++)
0645211c 145 disable_irq(assigned_dev->host_msix_entries[i].vector);
bfd99ff5
AK
146
147 for (i = 0; i < assigned_dev->entries_nr; i++)
148 free_irq(assigned_dev->host_msix_entries[i].vector,
9f9f6b78 149 assigned_dev);
bfd99ff5
AK
150
151 assigned_dev->entries_nr = 0;
152 kfree(assigned_dev->host_msix_entries);
153 kfree(assigned_dev->guest_msix_entries);
154 pci_disable_msix(assigned_dev->dev);
155 } else {
156 /* Deal with MSI and INTx */
0645211c 157 disable_irq(assigned_dev->host_irq);
bfd99ff5 158
9f9f6b78 159 free_irq(assigned_dev->host_irq, assigned_dev);
bfd99ff5
AK
160
161 if (assigned_dev->irq_requested_type & KVM_DEV_IRQ_HOST_MSI)
162 pci_disable_msi(assigned_dev->dev);
163 }
164
165 assigned_dev->irq_requested_type &= ~(KVM_DEV_IRQ_HOST_MASK);
166}
167
168static int kvm_deassign_irq(struct kvm *kvm,
169 struct kvm_assigned_dev_kernel *assigned_dev,
170 unsigned long irq_requested_type)
171{
172 unsigned long guest_irq_type, host_irq_type;
173
174 if (!irqchip_in_kernel(kvm))
175 return -EINVAL;
176 /* no irq assignment to deassign */
177 if (!assigned_dev->irq_requested_type)
178 return -ENXIO;
179
180 host_irq_type = irq_requested_type & KVM_DEV_IRQ_HOST_MASK;
181 guest_irq_type = irq_requested_type & KVM_DEV_IRQ_GUEST_MASK;
182
183 if (host_irq_type)
184 deassign_host_irq(kvm, assigned_dev);
185 if (guest_irq_type)
186 deassign_guest_irq(kvm, assigned_dev);
187
188 return 0;
189}
190
191static void kvm_free_assigned_irq(struct kvm *kvm,
192 struct kvm_assigned_dev_kernel *assigned_dev)
193{
194 kvm_deassign_irq(kvm, assigned_dev, assigned_dev->irq_requested_type);
195}
196
197static void kvm_free_assigned_device(struct kvm *kvm,
198 struct kvm_assigned_dev_kernel
199 *assigned_dev)
200{
201 kvm_free_assigned_irq(kvm, assigned_dev);
202
f8fcfd77
AW
203 pci_reset_function(assigned_dev->dev);
204 if (pci_load_and_free_saved_state(assigned_dev->dev,
205 &assigned_dev->pci_saved_state))
206 printk(KERN_INFO "%s: Couldn't reload %s saved state\n",
207 __func__, dev_name(&assigned_dev->dev->dev));
208 else
209 pci_restore_state(assigned_dev->dev);
bfd99ff5
AK
210
211 pci_release_regions(assigned_dev->dev);
212 pci_disable_device(assigned_dev->dev);
213 pci_dev_put(assigned_dev->dev);
214
215 list_del(&assigned_dev->list);
216 kfree(assigned_dev);
217}
218
219void kvm_free_all_assigned_devices(struct kvm *kvm)
220{
221 struct list_head *ptr, *ptr2;
222 struct kvm_assigned_dev_kernel *assigned_dev;
223
224 list_for_each_safe(ptr, ptr2, &kvm->arch.assigned_dev_head) {
225 assigned_dev = list_entry(ptr,
226 struct kvm_assigned_dev_kernel,
227 list);
228
229 kvm_free_assigned_device(kvm, assigned_dev);
230 }
231}
232
233static int assigned_device_enable_host_intx(struct kvm *kvm,
234 struct kvm_assigned_dev_kernel *dev)
235{
236 dev->host_irq = dev->dev->irq;
237 /* Even though this is PCI, we don't want to use shared
238 * interrupts. Sharing host devices with guest-assigned devices
239 * on the same interrupt line is not a happy situation: there
240 * are going to be long delays in accepting, acking, etc.
241 */
0645211c 242 if (request_threaded_irq(dev->host_irq, NULL, kvm_assigned_dev_thread,
9f9f6b78 243 IRQF_ONESHOT, dev->irq_name, dev))
bfd99ff5
AK
244 return -EIO;
245 return 0;
246}
247
248#ifdef __KVM_HAVE_MSI
249static int assigned_device_enable_host_msi(struct kvm *kvm,
250 struct kvm_assigned_dev_kernel *dev)
251{
252 int r;
253
254 if (!dev->dev->msi_enabled) {
255 r = pci_enable_msi(dev->dev);
256 if (r)
257 return r;
258 }
259
260 dev->host_irq = dev->dev->irq;
0645211c 261 if (request_threaded_irq(dev->host_irq, NULL, kvm_assigned_dev_thread,
9f9f6b78 262 0, dev->irq_name, dev)) {
bfd99ff5
AK
263 pci_disable_msi(dev->dev);
264 return -EIO;
265 }
266
267 return 0;
268}
269#endif
270
271#ifdef __KVM_HAVE_MSIX
272static int assigned_device_enable_host_msix(struct kvm *kvm,
273 struct kvm_assigned_dev_kernel *dev)
274{
275 int i, r = -EINVAL;
276
277 /* host_msix_entries and guest_msix_entries should have been
278 * initialized */
279 if (dev->entries_nr == 0)
280 return r;
281
282 r = pci_enable_msix(dev->dev, dev->host_msix_entries, dev->entries_nr);
283 if (r)
284 return r;
285
286 for (i = 0; i < dev->entries_nr; i++) {
0645211c 287 r = request_threaded_irq(dev->host_msix_entries[i].vector,
cc079396 288 NULL, kvm_assigned_dev_thread_msix,
9f9f6b78 289 0, dev->irq_name, dev);
bfd99ff5 290 if (r)
d57e2c07 291 goto err;
bfd99ff5
AK
292 }
293
294 return 0;
d57e2c07 295err:
296 for (i -= 1; i >= 0; i--)
9f9f6b78 297 free_irq(dev->host_msix_entries[i].vector, dev);
d57e2c07 298 pci_disable_msix(dev->dev);
299 return r;
bfd99ff5
AK
300}
301
302#endif
303
304static int assigned_device_enable_guest_intx(struct kvm *kvm,
305 struct kvm_assigned_dev_kernel *dev,
306 struct kvm_assigned_irq *irq)
307{
308 dev->guest_irq = irq->guest_irq;
309 dev->ack_notifier.gsi = irq->guest_irq;
310 return 0;
311}
312
313#ifdef __KVM_HAVE_MSI
314static int assigned_device_enable_guest_msi(struct kvm *kvm,
315 struct kvm_assigned_dev_kernel *dev,
316 struct kvm_assigned_irq *irq)
317{
318 dev->guest_irq = irq->guest_irq;
319 dev->ack_notifier.gsi = -1;
320 dev->host_irq_disabled = false;
321 return 0;
322}
323#endif
324
325#ifdef __KVM_HAVE_MSIX
326static int assigned_device_enable_guest_msix(struct kvm *kvm,
327 struct kvm_assigned_dev_kernel *dev,
328 struct kvm_assigned_irq *irq)
329{
330 dev->guest_irq = irq->guest_irq;
331 dev->ack_notifier.gsi = -1;
332 dev->host_irq_disabled = false;
333 return 0;
334}
335#endif
336
337static int assign_host_irq(struct kvm *kvm,
338 struct kvm_assigned_dev_kernel *dev,
339 __u32 host_irq_type)
340{
341 int r = -EEXIST;
342
343 if (dev->irq_requested_type & KVM_DEV_IRQ_HOST_MASK)
344 return r;
345
1e001d49
JK
346 snprintf(dev->irq_name, sizeof(dev->irq_name), "kvm:%s",
347 pci_name(dev->dev));
348
bfd99ff5
AK
349 switch (host_irq_type) {
350 case KVM_DEV_IRQ_HOST_INTX:
351 r = assigned_device_enable_host_intx(kvm, dev);
352 break;
353#ifdef __KVM_HAVE_MSI
354 case KVM_DEV_IRQ_HOST_MSI:
355 r = assigned_device_enable_host_msi(kvm, dev);
356 break;
357#endif
358#ifdef __KVM_HAVE_MSIX
359 case KVM_DEV_IRQ_HOST_MSIX:
360 r = assigned_device_enable_host_msix(kvm, dev);
361 break;
362#endif
363 default:
364 r = -EINVAL;
365 }
366
367 if (!r)
368 dev->irq_requested_type |= host_irq_type;
369
370 return r;
371}
372
373static int assign_guest_irq(struct kvm *kvm,
374 struct kvm_assigned_dev_kernel *dev,
375 struct kvm_assigned_irq *irq,
376 unsigned long guest_irq_type)
377{
378 int id;
379 int r = -EEXIST;
380
381 if (dev->irq_requested_type & KVM_DEV_IRQ_GUEST_MASK)
382 return r;
383
384 id = kvm_request_irq_source_id(kvm);
385 if (id < 0)
386 return id;
387
388 dev->irq_source_id = id;
389
390 switch (guest_irq_type) {
391 case KVM_DEV_IRQ_GUEST_INTX:
392 r = assigned_device_enable_guest_intx(kvm, dev, irq);
393 break;
394#ifdef __KVM_HAVE_MSI
395 case KVM_DEV_IRQ_GUEST_MSI:
396 r = assigned_device_enable_guest_msi(kvm, dev, irq);
397 break;
398#endif
399#ifdef __KVM_HAVE_MSIX
400 case KVM_DEV_IRQ_GUEST_MSIX:
401 r = assigned_device_enable_guest_msix(kvm, dev, irq);
402 break;
403#endif
404 default:
405 r = -EINVAL;
406 }
407
408 if (!r) {
409 dev->irq_requested_type |= guest_irq_type;
c61fa9d6
JK
410 if (dev->ack_notifier.gsi != -1)
411 kvm_register_irq_ack_notifier(kvm, &dev->ack_notifier);
bfd99ff5
AK
412 } else
413 kvm_free_irq_source_id(kvm, dev->irq_source_id);
414
415 return r;
416}
417
418/* TODO Deal with KVM_DEV_IRQ_ASSIGNED_MASK_MSIX */
419static int kvm_vm_ioctl_assign_irq(struct kvm *kvm,
420 struct kvm_assigned_irq *assigned_irq)
421{
422 int r = -EINVAL;
423 struct kvm_assigned_dev_kernel *match;
424 unsigned long host_irq_type, guest_irq_type;
425
bfd99ff5
AK
426 if (!irqchip_in_kernel(kvm))
427 return r;
428
429 mutex_lock(&kvm->lock);
430 r = -ENODEV;
431 match = kvm_find_assigned_dev(&kvm->arch.assigned_dev_head,
432 assigned_irq->assigned_dev_id);
433 if (!match)
434 goto out;
435
436 host_irq_type = (assigned_irq->flags & KVM_DEV_IRQ_HOST_MASK);
437 guest_irq_type = (assigned_irq->flags & KVM_DEV_IRQ_GUEST_MASK);
438
439 r = -EINVAL;
440 /* can only assign one type at a time */
441 if (hweight_long(host_irq_type) > 1)
442 goto out;
443 if (hweight_long(guest_irq_type) > 1)
444 goto out;
445 if (host_irq_type == 0 && guest_irq_type == 0)
446 goto out;
447
448 r = 0;
449 if (host_irq_type)
450 r = assign_host_irq(kvm, match, host_irq_type);
451 if (r)
452 goto out;
453
454 if (guest_irq_type)
455 r = assign_guest_irq(kvm, match, assigned_irq, guest_irq_type);
456out:
457 mutex_unlock(&kvm->lock);
458 return r;
459}
460
461static int kvm_vm_ioctl_deassign_dev_irq(struct kvm *kvm,
462 struct kvm_assigned_irq
463 *assigned_irq)
464{
465 int r = -ENODEV;
466 struct kvm_assigned_dev_kernel *match;
467
468 mutex_lock(&kvm->lock);
469
470 match = kvm_find_assigned_dev(&kvm->arch.assigned_dev_head,
471 assigned_irq->assigned_dev_id);
472 if (!match)
473 goto out;
474
475 r = kvm_deassign_irq(kvm, match, assigned_irq->flags);
476out:
477 mutex_unlock(&kvm->lock);
478 return r;
479}
480
481static int kvm_vm_ioctl_assign_device(struct kvm *kvm,
482 struct kvm_assigned_pci_dev *assigned_dev)
483{
bc6678a3 484 int r = 0, idx;
bfd99ff5
AK
485 struct kvm_assigned_dev_kernel *match;
486 struct pci_dev *dev;
487
bfd99ff5 488 mutex_lock(&kvm->lock);
bc6678a3 489 idx = srcu_read_lock(&kvm->srcu);
bfd99ff5
AK
490
491 match = kvm_find_assigned_dev(&kvm->arch.assigned_dev_head,
492 assigned_dev->assigned_dev_id);
493 if (match) {
494 /* device already assigned */
495 r = -EEXIST;
496 goto out;
497 }
498
499 match = kzalloc(sizeof(struct kvm_assigned_dev_kernel), GFP_KERNEL);
500 if (match == NULL) {
501 printk(KERN_INFO "%s: Couldn't allocate memory\n",
502 __func__);
503 r = -ENOMEM;
504 goto out;
505 }
ab9f4ecb
ZE
506 dev = pci_get_domain_bus_and_slot(assigned_dev->segnr,
507 assigned_dev->busnr,
bfd99ff5
AK
508 assigned_dev->devfn);
509 if (!dev) {
510 printk(KERN_INFO "%s: host device not found\n", __func__);
511 r = -EINVAL;
512 goto out_free;
513 }
514 if (pci_enable_device(dev)) {
515 printk(KERN_INFO "%s: Could not enable PCI device\n", __func__);
516 r = -EBUSY;
517 goto out_put;
518 }
519 r = pci_request_regions(dev, "kvm_assigned_device");
520 if (r) {
521 printk(KERN_INFO "%s: Could not get access to device regions\n",
522 __func__);
523 goto out_disable;
524 }
525
526 pci_reset_function(dev);
ed78661f 527 pci_save_state(dev);
f8fcfd77
AW
528 match->pci_saved_state = pci_store_saved_state(dev);
529 if (!match->pci_saved_state)
530 printk(KERN_DEBUG "%s: Couldn't store %s saved state\n",
531 __func__, dev_name(&dev->dev));
bfd99ff5 532 match->assigned_dev_id = assigned_dev->assigned_dev_id;
ab9f4ecb 533 match->host_segnr = assigned_dev->segnr;
bfd99ff5
AK
534 match->host_busnr = assigned_dev->busnr;
535 match->host_devfn = assigned_dev->devfn;
536 match->flags = assigned_dev->flags;
537 match->dev = dev;
0645211c 538 spin_lock_init(&match->intx_lock);
bfd99ff5
AK
539 match->irq_source_id = -1;
540 match->kvm = kvm;
541 match->ack_notifier.irq_acked = kvm_assigned_dev_ack_irq;
bfd99ff5
AK
542
543 list_add(&match->list, &kvm->arch.assigned_dev_head);
544
545 if (assigned_dev->flags & KVM_DEV_ASSIGN_ENABLE_IOMMU) {
546 if (!kvm->arch.iommu_domain) {
547 r = kvm_iommu_map_guest(kvm);
548 if (r)
549 goto out_list_del;
550 }
551 r = kvm_assign_device(kvm, match);
552 if (r)
553 goto out_list_del;
554 }
555
556out:
bc6678a3 557 srcu_read_unlock(&kvm->srcu, idx);
fae3a353 558 mutex_unlock(&kvm->lock);
bfd99ff5
AK
559 return r;
560out_list_del:
f8fcfd77
AW
561 if (pci_load_and_free_saved_state(dev, &match->pci_saved_state))
562 printk(KERN_INFO "%s: Couldn't reload %s saved state\n",
563 __func__, dev_name(&dev->dev));
bfd99ff5
AK
564 list_del(&match->list);
565 pci_release_regions(dev);
566out_disable:
567 pci_disable_device(dev);
568out_put:
569 pci_dev_put(dev);
570out_free:
571 kfree(match);
bc6678a3 572 srcu_read_unlock(&kvm->srcu, idx);
fae3a353 573 mutex_unlock(&kvm->lock);
bfd99ff5
AK
574 return r;
575}
576
577static int kvm_vm_ioctl_deassign_device(struct kvm *kvm,
578 struct kvm_assigned_pci_dev *assigned_dev)
579{
580 int r = 0;
581 struct kvm_assigned_dev_kernel *match;
582
583 mutex_lock(&kvm->lock);
584
585 match = kvm_find_assigned_dev(&kvm->arch.assigned_dev_head,
586 assigned_dev->assigned_dev_id);
587 if (!match) {
588 printk(KERN_INFO "%s: device hasn't been assigned before, "
589 "so cannot be deassigned\n", __func__);
590 r = -EINVAL;
591 goto out;
592 }
593
594 if (match->flags & KVM_DEV_ASSIGN_ENABLE_IOMMU)
595 kvm_deassign_device(kvm, match);
596
597 kvm_free_assigned_device(kvm, match);
598
599out:
600 mutex_unlock(&kvm->lock);
601 return r;
602}
603
604
605#ifdef __KVM_HAVE_MSIX
606static int kvm_vm_ioctl_set_msix_nr(struct kvm *kvm,
607 struct kvm_assigned_msix_nr *entry_nr)
608{
609 int r = 0;
610 struct kvm_assigned_dev_kernel *adev;
611
612 mutex_lock(&kvm->lock);
613
614 adev = kvm_find_assigned_dev(&kvm->arch.assigned_dev_head,
615 entry_nr->assigned_dev_id);
616 if (!adev) {
617 r = -EINVAL;
618 goto msix_nr_out;
619 }
620
621 if (adev->entries_nr == 0) {
622 adev->entries_nr = entry_nr->entry_nr;
623 if (adev->entries_nr == 0 ||
9f3191ae 624 adev->entries_nr > KVM_MAX_MSIX_PER_DEV) {
bfd99ff5
AK
625 r = -EINVAL;
626 goto msix_nr_out;
627 }
628
629 adev->host_msix_entries = kzalloc(sizeof(struct msix_entry) *
630 entry_nr->entry_nr,
631 GFP_KERNEL);
632 if (!adev->host_msix_entries) {
633 r = -ENOMEM;
634 goto msix_nr_out;
635 }
0645211c
JK
636 adev->guest_msix_entries =
637 kzalloc(sizeof(struct msix_entry) * entry_nr->entry_nr,
638 GFP_KERNEL);
bfd99ff5
AK
639 if (!adev->guest_msix_entries) {
640 kfree(adev->host_msix_entries);
641 r = -ENOMEM;
642 goto msix_nr_out;
643 }
644 } else /* Not allowed set MSI-X number twice */
645 r = -EINVAL;
646msix_nr_out:
647 mutex_unlock(&kvm->lock);
648 return r;
649}
650
651static int kvm_vm_ioctl_set_msix_entry(struct kvm *kvm,
652 struct kvm_assigned_msix_entry *entry)
653{
654 int r = 0, i;
655 struct kvm_assigned_dev_kernel *adev;
656
657 mutex_lock(&kvm->lock);
658
659 adev = kvm_find_assigned_dev(&kvm->arch.assigned_dev_head,
660 entry->assigned_dev_id);
661
662 if (!adev) {
663 r = -EINVAL;
664 goto msix_entry_out;
665 }
666
667 for (i = 0; i < adev->entries_nr; i++)
668 if (adev->guest_msix_entries[i].vector == 0 ||
669 adev->guest_msix_entries[i].entry == entry->entry) {
670 adev->guest_msix_entries[i].entry = entry->entry;
671 adev->guest_msix_entries[i].vector = entry->gsi;
672 adev->host_msix_entries[i].entry = entry->entry;
673 break;
674 }
675 if (i == adev->entries_nr) {
676 r = -ENOSPC;
677 goto msix_entry_out;
678 }
679
680msix_entry_out:
681 mutex_unlock(&kvm->lock);
682
683 return r;
684}
685#endif
686
687long kvm_vm_ioctl_assigned_device(struct kvm *kvm, unsigned ioctl,
688 unsigned long arg)
689{
690 void __user *argp = (void __user *)arg;
51de271d 691 int r;
bfd99ff5
AK
692
693 switch (ioctl) {
694 case KVM_ASSIGN_PCI_DEVICE: {
695 struct kvm_assigned_pci_dev assigned_dev;
696
697 r = -EFAULT;
698 if (copy_from_user(&assigned_dev, argp, sizeof assigned_dev))
699 goto out;
700 r = kvm_vm_ioctl_assign_device(kvm, &assigned_dev);
701 if (r)
702 goto out;
703 break;
704 }
705 case KVM_ASSIGN_IRQ: {
706 r = -EOPNOTSUPP;
707 break;
708 }
bfd99ff5
AK
709 case KVM_ASSIGN_DEV_IRQ: {
710 struct kvm_assigned_irq assigned_irq;
711
712 r = -EFAULT;
713 if (copy_from_user(&assigned_irq, argp, sizeof assigned_irq))
714 goto out;
715 r = kvm_vm_ioctl_assign_irq(kvm, &assigned_irq);
716 if (r)
717 goto out;
718 break;
719 }
720 case KVM_DEASSIGN_DEV_IRQ: {
721 struct kvm_assigned_irq assigned_irq;
722
723 r = -EFAULT;
724 if (copy_from_user(&assigned_irq, argp, sizeof assigned_irq))
725 goto out;
726 r = kvm_vm_ioctl_deassign_dev_irq(kvm, &assigned_irq);
727 if (r)
728 goto out;
729 break;
730 }
bfd99ff5
AK
731 case KVM_DEASSIGN_PCI_DEVICE: {
732 struct kvm_assigned_pci_dev assigned_dev;
733
734 r = -EFAULT;
735 if (copy_from_user(&assigned_dev, argp, sizeof assigned_dev))
736 goto out;
737 r = kvm_vm_ioctl_deassign_device(kvm, &assigned_dev);
738 if (r)
739 goto out;
740 break;
741 }
bfd99ff5
AK
742#ifdef KVM_CAP_IRQ_ROUTING
743 case KVM_SET_GSI_ROUTING: {
744 struct kvm_irq_routing routing;
745 struct kvm_irq_routing __user *urouting;
746 struct kvm_irq_routing_entry *entries;
747
748 r = -EFAULT;
749 if (copy_from_user(&routing, argp, sizeof(routing)))
750 goto out;
751 r = -EINVAL;
752 if (routing.nr >= KVM_MAX_IRQ_ROUTES)
753 goto out;
754 if (routing.flags)
755 goto out;
756 r = -ENOMEM;
757 entries = vmalloc(routing.nr * sizeof(*entries));
758 if (!entries)
759 goto out;
760 r = -EFAULT;
761 urouting = argp;
762 if (copy_from_user(entries, urouting->entries,
763 routing.nr * sizeof(*entries)))
764 goto out_free_irq_routing;
765 r = kvm_set_irq_routing(kvm, entries, routing.nr,
766 routing.flags);
767 out_free_irq_routing:
768 vfree(entries);
769 break;
770 }
771#endif /* KVM_CAP_IRQ_ROUTING */
772#ifdef __KVM_HAVE_MSIX
773 case KVM_ASSIGN_SET_MSIX_NR: {
774 struct kvm_assigned_msix_nr entry_nr;
775 r = -EFAULT;
776 if (copy_from_user(&entry_nr, argp, sizeof entry_nr))
777 goto out;
778 r = kvm_vm_ioctl_set_msix_nr(kvm, &entry_nr);
779 if (r)
780 goto out;
781 break;
782 }
783 case KVM_ASSIGN_SET_MSIX_ENTRY: {
784 struct kvm_assigned_msix_entry entry;
785 r = -EFAULT;
786 if (copy_from_user(&entry, argp, sizeof entry))
787 goto out;
788 r = kvm_vm_ioctl_set_msix_entry(kvm, &entry);
789 if (r)
790 goto out;
791 break;
792 }
793#endif
51de271d
JK
794 default:
795 r = -ENOTTY;
796 break;
bfd99ff5
AK
797 }
798out:
799 return r;
800}
801
This page took 0.150195 seconds and 5 git commands to generate.