Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
vfio_pci_intrs.c
Go to the documentation of this file.
1 /*
2  * VFIO PCI interrupt handling
3  *
4  * Copyright (C) 2012 Red Hat, Inc. All rights reserved.
5  * Author: Alex Williamson <[email protected]>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  *
11  * Derived from original vfio:
12  * Copyright 2010 Cisco Systems, Inc. All rights reserved.
13  * Author: Tom Lyon, [email protected]
14  */
15 
16 #include <linux/device.h>
17 #include <linux/interrupt.h>
18 #include <linux/eventfd.h>
19 #include <linux/pci.h>
20 #include <linux/file.h>
21 #include <linux/poll.h>
22 #include <linux/vfio.h>
23 #include <linux/wait.h>
24 #include <linux/workqueue.h>
25 
26 #include "vfio_pci_private.h"
27 
28 /*
29  * IRQfd - generic
30  */
31 struct virqfd {
34  int (*handler)(struct vfio_pci_device *, void *);
35  void (*thread)(struct vfio_pci_device *, void *);
36  void *data;
41  struct virqfd **pvirqfd;
42 };
43 
44 static struct workqueue_struct *vfio_irqfd_cleanup_wq;
45 
47 {
48  vfio_irqfd_cleanup_wq =
49  create_singlethread_workqueue("vfio-irqfd-cleanup");
50  if (!vfio_irqfd_cleanup_wq)
51  return -ENOMEM;
52 
53  return 0;
54 }
55 
57 {
58  destroy_workqueue(vfio_irqfd_cleanup_wq);
59 }
60 
61 static void virqfd_deactivate(struct virqfd *virqfd)
62 {
63  queue_work(vfio_irqfd_cleanup_wq, &virqfd->shutdown);
64 }
65 
66 static int virqfd_wakeup(wait_queue_t *wait, unsigned mode, int sync, void *key)
67 {
68  struct virqfd *virqfd = container_of(wait, struct virqfd, wait);
69  unsigned long flags = (unsigned long)key;
70 
71  if (flags & POLLIN) {
72  /* An event has been signaled, call function */
73  if ((!virqfd->handler ||
74  virqfd->handler(virqfd->vdev, virqfd->data)) &&
75  virqfd->thread)
76  schedule_work(&virqfd->inject);
77  }
78 
79  if (flags & POLLHUP) {
80  unsigned long flags;
81  spin_lock_irqsave(&virqfd->vdev->irqlock, flags);
82 
83  /*
84  * The eventfd is closing, if the virqfd has not yet been
85  * queued for release, as determined by testing whether the
86  * vdev pointer to it is still valid, queue it now. As
87  * with kvm irqfds, we know we won't race against the virqfd
88  * going away because we hold wqh->lock to get here.
89  */
90  if (*(virqfd->pvirqfd) == virqfd) {
91  *(virqfd->pvirqfd) = NULL;
92  virqfd_deactivate(virqfd);
93  }
94 
95  spin_unlock_irqrestore(&virqfd->vdev->irqlock, flags);
96  }
97 
98  return 0;
99 }
100 
101 static void virqfd_ptable_queue_proc(struct file *file,
103 {
104  struct virqfd *virqfd = container_of(pt, struct virqfd, pt);
105  add_wait_queue(wqh, &virqfd->wait);
106 }
107 
108 static void virqfd_shutdown(struct work_struct *work)
109 {
110  struct virqfd *virqfd = container_of(work, struct virqfd, shutdown);
111  u64 cnt;
112 
113  eventfd_ctx_remove_wait_queue(virqfd->eventfd, &virqfd->wait, &cnt);
114  flush_work(&virqfd->inject);
115  eventfd_ctx_put(virqfd->eventfd);
116 
117  kfree(virqfd);
118 }
119 
120 static void virqfd_inject(struct work_struct *work)
121 {
122  struct virqfd *virqfd = container_of(work, struct virqfd, inject);
123  if (virqfd->thread)
124  virqfd->thread(virqfd->vdev, virqfd->data);
125 }
126 
127 static int virqfd_enable(struct vfio_pci_device *vdev,
128  int (*handler)(struct vfio_pci_device *, void *),
129  void (*thread)(struct vfio_pci_device *, void *),
130  void *data, struct virqfd **pvirqfd, int fd)
131 {
132  struct file *file = NULL;
133  struct eventfd_ctx *ctx = NULL;
134  struct virqfd *virqfd;
135  int ret = 0;
136  unsigned int events;
137 
138  virqfd = kzalloc(sizeof(*virqfd), GFP_KERNEL);
139  if (!virqfd)
140  return -ENOMEM;
141 
142  virqfd->pvirqfd = pvirqfd;
143  virqfd->vdev = vdev;
144  virqfd->handler = handler;
145  virqfd->thread = thread;
146  virqfd->data = data;
147 
148  INIT_WORK(&virqfd->shutdown, virqfd_shutdown);
149  INIT_WORK(&virqfd->inject, virqfd_inject);
150 
151  file = eventfd_fget(fd);
152  if (IS_ERR(file)) {
153  ret = PTR_ERR(file);
154  goto fail;
155  }
156 
157  ctx = eventfd_ctx_fileget(file);
158  if (IS_ERR(ctx)) {
159  ret = PTR_ERR(ctx);
160  goto fail;
161  }
162 
163  virqfd->eventfd = ctx;
164 
165  /*
166  * virqfds can be released by closing the eventfd or directly
167  * through ioctl. These are both done through a workqueue, so
168  * we update the pointer to the virqfd under lock to avoid
169  * pushing multiple jobs to release the same virqfd.
170  */
171  spin_lock_irq(&vdev->irqlock);
172 
173  if (*pvirqfd) {
174  spin_unlock_irq(&vdev->irqlock);
175  ret = -EBUSY;
176  goto fail;
177  }
178  *pvirqfd = virqfd;
179 
180  spin_unlock_irq(&vdev->irqlock);
181 
182  /*
183  * Install our own custom wake-up handling so we are notified via
184  * a callback whenever someone signals the underlying eventfd.
185  */
186  init_waitqueue_func_entry(&virqfd->wait, virqfd_wakeup);
187  init_poll_funcptr(&virqfd->pt, virqfd_ptable_queue_proc);
188 
189  events = file->f_op->poll(file, &virqfd->pt);
190 
191  /*
192  * Check if there was an event already pending on the eventfd
193  * before we registered and trigger it as if we didn't miss it.
194  */
195  if (events & POLLIN) {
196  if ((!handler || handler(vdev, data)) && thread)
197  schedule_work(&virqfd->inject);
198  }
199 
200  /*
201  * Do not drop the file until the irqfd is fully initialized,
202  * otherwise we might race against the POLLHUP.
203  */
204  fput(file);
205 
206  return 0;
207 
208 fail:
209  if (ctx && !IS_ERR(ctx))
210  eventfd_ctx_put(ctx);
211 
212  if (file && !IS_ERR(file))
213  fput(file);
214 
215  kfree(virqfd);
216 
217  return ret;
218 }
219 
220 static void virqfd_disable(struct vfio_pci_device *vdev,
221  struct virqfd **pvirqfd)
222 {
223  unsigned long flags;
224 
225  spin_lock_irqsave(&vdev->irqlock, flags);
226 
227  if (*pvirqfd) {
228  virqfd_deactivate(*pvirqfd);
229  *pvirqfd = NULL;
230  }
231 
232  spin_unlock_irqrestore(&vdev->irqlock, flags);
233 
234  /*
235  * Block until we know all outstanding shutdown jobs have completed.
236  * Even if we don't queue the job, flush the wq to be sure it's
237  * been released.
238  */
239  flush_workqueue(vfio_irqfd_cleanup_wq);
240 }
241 
242 /*
243  * INTx
244  */
245 static void vfio_send_intx_eventfd(struct vfio_pci_device *vdev, void *unused)
246 {
247  if (likely(is_intx(vdev) && !vdev->virq_disabled))
248  eventfd_signal(vdev->ctx[0].trigger, 1);
249 }
250 
252 {
253  struct pci_dev *pdev = vdev->pdev;
254  unsigned long flags;
255 
256  spin_lock_irqsave(&vdev->irqlock, flags);
257 
258  /*
259  * Masking can come from interrupt, ioctl, or config space
260  * via INTx disable. The latter means this can get called
261  * even when not using intx delivery. In this case, just
262  * try to have the physical bit follow the virtual bit.
263  */
264  if (unlikely(!is_intx(vdev))) {
265  if (vdev->pci_2_3)
266  pci_intx(pdev, 0);
267  } else if (!vdev->ctx[0].masked) {
268  /*
269  * Can't use check_and_mask here because we always want to
270  * mask, not just when something is pending.
271  */
272  if (vdev->pci_2_3)
273  pci_intx(pdev, 0);
274  else
275  disable_irq_nosync(pdev->irq);
276 
277  vdev->ctx[0].masked = true;
278  }
279 
280  spin_unlock_irqrestore(&vdev->irqlock, flags);
281 }
282 
283 /*
284  * If this is triggered by an eventfd, we can't call eventfd_signal
285  * or else we'll deadlock on the eventfd wait queue. Return >0 when
286  * a signal is necessary, which can then be handled via a work queue
287  * or directly depending on the caller.
288  */
289 int vfio_pci_intx_unmask_handler(struct vfio_pci_device *vdev, void *unused)
290 {
291  struct pci_dev *pdev = vdev->pdev;
292  unsigned long flags;
293  int ret = 0;
294 
295  spin_lock_irqsave(&vdev->irqlock, flags);
296 
297  /*
298  * Unmasking comes from ioctl or config, so again, have the
299  * physical bit follow the virtual even when not using INTx.
300  */
301  if (unlikely(!is_intx(vdev))) {
302  if (vdev->pci_2_3)
303  pci_intx(pdev, 1);
304  } else if (vdev->ctx[0].masked && !vdev->virq_disabled) {
305  /*
306  * A pending interrupt here would immediately trigger,
307  * but we can avoid that overhead by just re-sending
308  * the interrupt to the user.
309  */
310  if (vdev->pci_2_3) {
311  if (!pci_check_and_unmask_intx(pdev))
312  ret = 1;
313  } else
314  enable_irq(pdev->irq);
315 
316  vdev->ctx[0].masked = (ret > 0);
317  }
318 
319  spin_unlock_irqrestore(&vdev->irqlock, flags);
320 
321  return ret;
322 }
323 
325 {
326  if (vfio_pci_intx_unmask_handler(vdev, NULL) > 0)
327  vfio_send_intx_eventfd(vdev, NULL);
328 }
329 
330 static irqreturn_t vfio_intx_handler(int irq, void *dev_id)
331 {
332  struct vfio_pci_device *vdev = dev_id;
333  unsigned long flags;
334  int ret = IRQ_NONE;
335 
336  spin_lock_irqsave(&vdev->irqlock, flags);
337 
338  if (!vdev->pci_2_3) {
339  disable_irq_nosync(vdev->pdev->irq);
340  vdev->ctx[0].masked = true;
341  ret = IRQ_HANDLED;
342  } else if (!vdev->ctx[0].masked && /* may be shared */
343  pci_check_and_mask_intx(vdev->pdev)) {
344  vdev->ctx[0].masked = true;
345  ret = IRQ_HANDLED;
346  }
347 
348  spin_unlock_irqrestore(&vdev->irqlock, flags);
349 
350  if (ret == IRQ_HANDLED)
351  vfio_send_intx_eventfd(vdev, NULL);
352 
353  return ret;
354 }
355 
356 static int vfio_intx_enable(struct vfio_pci_device *vdev)
357 {
358  if (!is_irq_none(vdev))
359  return -EINVAL;
360 
361  if (!vdev->pdev->irq)
362  return -ENODEV;
363 
364  vdev->ctx = kzalloc(sizeof(struct vfio_pci_irq_ctx), GFP_KERNEL);
365  if (!vdev->ctx)
366  return -ENOMEM;
367 
368  vdev->num_ctx = 1;
369 
370  /*
371  * If the virtual interrupt is masked, restore it. Devices
372  * supporting DisINTx can be masked at the hardware level
373  * here, non-PCI-2.3 devices will have to wait until the
374  * interrupt is enabled.
375  */
376  vdev->ctx[0].masked = vdev->virq_disabled;
377  if (vdev->pci_2_3)
378  pci_intx(vdev->pdev, !vdev->ctx[0].masked);
379 
381 
382  return 0;
383 }
384 
385 static int vfio_intx_set_signal(struct vfio_pci_device *vdev, int fd)
386 {
387  struct pci_dev *pdev = vdev->pdev;
388  unsigned long irqflags = IRQF_SHARED;
389  struct eventfd_ctx *trigger;
390  unsigned long flags;
391  int ret;
392 
393  if (vdev->ctx[0].trigger) {
394  free_irq(pdev->irq, vdev);
395  kfree(vdev->ctx[0].name);
396  eventfd_ctx_put(vdev->ctx[0].trigger);
397  vdev->ctx[0].trigger = NULL;
398  }
399 
400  if (fd < 0) /* Disable only */
401  return 0;
402 
403  vdev->ctx[0].name = kasprintf(GFP_KERNEL, "vfio-intx(%s)",
404  pci_name(pdev));
405  if (!vdev->ctx[0].name)
406  return -ENOMEM;
407 
408  trigger = eventfd_ctx_fdget(fd);
409  if (IS_ERR(trigger)) {
410  kfree(vdev->ctx[0].name);
411  return PTR_ERR(trigger);
412  }
413 
414  vdev->ctx[0].trigger = trigger;
415 
416  if (!vdev->pci_2_3)
417  irqflags = 0;
418 
419  ret = request_irq(pdev->irq, vfio_intx_handler,
420  irqflags, vdev->ctx[0].name, vdev);
421  if (ret) {
422  vdev->ctx[0].trigger = NULL;
423  kfree(vdev->ctx[0].name);
424  eventfd_ctx_put(trigger);
425  return ret;
426  }
427 
428  /*
429  * INTx disable will stick across the new irq setup,
430  * disable_irq won't.
431  */
432  spin_lock_irqsave(&vdev->irqlock, flags);
433  if (!vdev->pci_2_3 && vdev->ctx[0].masked)
434  disable_irq_nosync(pdev->irq);
435  spin_unlock_irqrestore(&vdev->irqlock, flags);
436 
437  return 0;
438 }
439 
440 static void vfio_intx_disable(struct vfio_pci_device *vdev)
441 {
442  vfio_intx_set_signal(vdev, -1);
443  virqfd_disable(vdev, &vdev->ctx[0].unmask);
444  virqfd_disable(vdev, &vdev->ctx[0].mask);
445  vdev->irq_type = VFIO_PCI_NUM_IRQS;
446  vdev->num_ctx = 0;
447  kfree(vdev->ctx);
448 }
449 
450 /*
451  * MSI/MSI-X
452  */
453 static irqreturn_t vfio_msihandler(int irq, void *arg)
454 {
455  struct eventfd_ctx *trigger = arg;
456 
457  eventfd_signal(trigger, 1);
458  return IRQ_HANDLED;
459 }
460 
461 static int vfio_msi_enable(struct vfio_pci_device *vdev, int nvec, bool msix)
462 {
463  struct pci_dev *pdev = vdev->pdev;
464  int ret;
465 
466  if (!is_irq_none(vdev))
467  return -EINVAL;
468 
469  vdev->ctx = kzalloc(nvec * sizeof(struct vfio_pci_irq_ctx), GFP_KERNEL);
470  if (!vdev->ctx)
471  return -ENOMEM;
472 
473  if (msix) {
474  int i;
475 
476  vdev->msix = kzalloc(nvec * sizeof(struct msix_entry),
477  GFP_KERNEL);
478  if (!vdev->msix) {
479  kfree(vdev->ctx);
480  return -ENOMEM;
481  }
482 
483  for (i = 0; i < nvec; i++)
484  vdev->msix[i].entry = i;
485 
486  ret = pci_enable_msix(pdev, vdev->msix, nvec);
487  if (ret) {
488  kfree(vdev->msix);
489  kfree(vdev->ctx);
490  return ret;
491  }
492  } else {
493  ret = pci_enable_msi_block(pdev, nvec);
494  if (ret) {
495  kfree(vdev->ctx);
496  return ret;
497  }
498  }
499 
500  vdev->num_ctx = nvec;
501  vdev->irq_type = msix ? VFIO_PCI_MSIX_IRQ_INDEX :
503 
504  if (!msix) {
505  /*
506  * Compute the virtual hardware field for max msi vectors -
507  * it is the log base 2 of the number of vectors.
508  */
509  vdev->msi_qmax = fls(nvec * 2 - 1) - 1;
510  }
511 
512  return 0;
513 }
514 
515 static int vfio_msi_set_vector_signal(struct vfio_pci_device *vdev,
516  int vector, int fd, bool msix)
517 {
518  struct pci_dev *pdev = vdev->pdev;
519  int irq = msix ? vdev->msix[vector].vector : pdev->irq + vector;
520  char *name = msix ? "vfio-msix" : "vfio-msi";
521  struct eventfd_ctx *trigger;
522  int ret;
523 
524  if (vector >= vdev->num_ctx)
525  return -EINVAL;
526 
527  if (vdev->ctx[vector].trigger) {
528  free_irq(irq, vdev->ctx[vector].trigger);
529  kfree(vdev->ctx[vector].name);
530  eventfd_ctx_put(vdev->ctx[vector].trigger);
531  vdev->ctx[vector].trigger = NULL;
532  }
533 
534  if (fd < 0)
535  return 0;
536 
537  vdev->ctx[vector].name = kasprintf(GFP_KERNEL, "%s[%d](%s)",
538  name, vector, pci_name(pdev));
539  if (!vdev->ctx[vector].name)
540  return -ENOMEM;
541 
542  trigger = eventfd_ctx_fdget(fd);
543  if (IS_ERR(trigger)) {
544  kfree(vdev->ctx[vector].name);
545  return PTR_ERR(trigger);
546  }
547 
548  ret = request_irq(irq, vfio_msihandler, 0,
549  vdev->ctx[vector].name, trigger);
550  if (ret) {
551  kfree(vdev->ctx[vector].name);
552  eventfd_ctx_put(trigger);
553  return ret;
554  }
555 
556  vdev->ctx[vector].trigger = trigger;
557 
558  return 0;
559 }
560 
561 static int vfio_msi_set_block(struct vfio_pci_device *vdev, unsigned start,
562  unsigned count, int32_t *fds, bool msix)
563 {
564  int i, j, ret = 0;
565 
566  if (start + count > vdev->num_ctx)
567  return -EINVAL;
568 
569  for (i = 0, j = start; i < count && !ret; i++, j++) {
570  int fd = fds ? fds[i] : -1;
571  ret = vfio_msi_set_vector_signal(vdev, j, fd, msix);
572  }
573 
574  if (ret) {
575  for (--j; j >= start; j--)
576  vfio_msi_set_vector_signal(vdev, j, -1, msix);
577  }
578 
579  return ret;
580 }
581 
582 static void vfio_msi_disable(struct vfio_pci_device *vdev, bool msix)
583 {
584  struct pci_dev *pdev = vdev->pdev;
585  int i;
586 
587  vfio_msi_set_block(vdev, 0, vdev->num_ctx, NULL, msix);
588 
589  for (i = 0; i < vdev->num_ctx; i++) {
590  virqfd_disable(vdev, &vdev->ctx[i].unmask);
591  virqfd_disable(vdev, &vdev->ctx[i].mask);
592  }
593 
594  if (msix) {
595  pci_disable_msix(vdev->pdev);
596  kfree(vdev->msix);
597  } else
598  pci_disable_msi(pdev);
599 
600  vdev->irq_type = VFIO_PCI_NUM_IRQS;
601  vdev->num_ctx = 0;
602  kfree(vdev->ctx);
603 }
604 
605 /*
606  * IOCTL support
607  */
608 static int vfio_pci_set_intx_unmask(struct vfio_pci_device *vdev,
609  unsigned index, unsigned start,
610  unsigned count, uint32_t flags, void *data)
611 {
612  if (!is_intx(vdev) || start != 0 || count != 1)
613  return -EINVAL;
614 
615  if (flags & VFIO_IRQ_SET_DATA_NONE) {
616  vfio_pci_intx_unmask(vdev);
617  } else if (flags & VFIO_IRQ_SET_DATA_BOOL) {
618  uint8_t unmask = *(uint8_t *)data;
619  if (unmask)
620  vfio_pci_intx_unmask(vdev);
621  } else if (flags & VFIO_IRQ_SET_DATA_EVENTFD) {
622  int32_t fd = *(int32_t *)data;
623  if (fd >= 0)
624  return virqfd_enable(vdev, vfio_pci_intx_unmask_handler,
625  vfio_send_intx_eventfd, NULL,
626  &vdev->ctx[0].unmask, fd);
627 
628  virqfd_disable(vdev, &vdev->ctx[0].unmask);
629  }
630 
631  return 0;
632 }
633 
634 static int vfio_pci_set_intx_mask(struct vfio_pci_device *vdev,
635  unsigned index, unsigned start,
636  unsigned count, uint32_t flags, void *data)
637 {
638  if (!is_intx(vdev) || start != 0 || count != 1)
639  return -EINVAL;
640 
641  if (flags & VFIO_IRQ_SET_DATA_NONE) {
642  vfio_pci_intx_mask(vdev);
643  } else if (flags & VFIO_IRQ_SET_DATA_BOOL) {
644  uint8_t mask = *(uint8_t *)data;
645  if (mask)
646  vfio_pci_intx_mask(vdev);
647  } else if (flags & VFIO_IRQ_SET_DATA_EVENTFD) {
648  return -ENOTTY; /* XXX implement me */
649  }
650 
651  return 0;
652 }
653 
654 static int vfio_pci_set_intx_trigger(struct vfio_pci_device *vdev,
655  unsigned index, unsigned start,
656  unsigned count, uint32_t flags, void *data)
657 {
658  if (is_intx(vdev) && !count && (flags & VFIO_IRQ_SET_DATA_NONE)) {
659  vfio_intx_disable(vdev);
660  return 0;
661  }
662 
663  if (!(is_intx(vdev) || is_irq_none(vdev)) || start != 0 || count != 1)
664  return -EINVAL;
665 
666  if (flags & VFIO_IRQ_SET_DATA_EVENTFD) {
667  int32_t fd = *(int32_t *)data;
668  int ret;
669 
670  if (is_intx(vdev))
671  return vfio_intx_set_signal(vdev, fd);
672 
673  ret = vfio_intx_enable(vdev);
674  if (ret)
675  return ret;
676 
677  ret = vfio_intx_set_signal(vdev, fd);
678  if (ret)
679  vfio_intx_disable(vdev);
680 
681  return ret;
682  }
683 
684  if (!is_intx(vdev))
685  return -EINVAL;
686 
687  if (flags & VFIO_IRQ_SET_DATA_NONE) {
688  vfio_send_intx_eventfd(vdev, NULL);
689  } else if (flags & VFIO_IRQ_SET_DATA_BOOL) {
690  uint8_t trigger = *(uint8_t *)data;
691  if (trigger)
692  vfio_send_intx_eventfd(vdev, NULL);
693  }
694  return 0;
695 }
696 
697 static int vfio_pci_set_msi_trigger(struct vfio_pci_device *vdev,
698  unsigned index, unsigned start,
699  unsigned count, uint32_t flags, void *data)
700 {
701  int i;
702  bool msix = (index == VFIO_PCI_MSIX_IRQ_INDEX) ? true : false;
703 
704  if (irq_is(vdev, index) && !count && (flags & VFIO_IRQ_SET_DATA_NONE)) {
705  vfio_msi_disable(vdev, msix);
706  return 0;
707  }
708 
709  if (!(irq_is(vdev, index) || is_irq_none(vdev)))
710  return -EINVAL;
711 
712  if (flags & VFIO_IRQ_SET_DATA_EVENTFD) {
713  int32_t *fds = data;
714  int ret;
715 
716  if (vdev->irq_type == index)
717  return vfio_msi_set_block(vdev, start, count,
718  fds, msix);
719 
720  ret = vfio_msi_enable(vdev, start + count, msix);
721  if (ret)
722  return ret;
723 
724  ret = vfio_msi_set_block(vdev, start, count, fds, msix);
725  if (ret)
726  vfio_msi_disable(vdev, msix);
727 
728  return ret;
729  }
730 
731  if (!irq_is(vdev, index) || start + count > vdev->num_ctx)
732  return -EINVAL;
733 
734  for (i = start; i < start + count; i++) {
735  if (!vdev->ctx[i].trigger)
736  continue;
737  if (flags & VFIO_IRQ_SET_DATA_NONE) {
738  eventfd_signal(vdev->ctx[i].trigger, 1);
739  } else if (flags & VFIO_IRQ_SET_DATA_BOOL) {
740  uint8_t *bools = data;
741  if (bools[i - start])
742  eventfd_signal(vdev->ctx[i].trigger, 1);
743  }
744  }
745  return 0;
746 }
747 
749  unsigned index, unsigned start, unsigned count,
750  void *data)
751 {
752  int (*func)(struct vfio_pci_device *vdev, unsigned index,
753  unsigned start, unsigned count, uint32_t flags,
754  void *data) = NULL;
755 
756  switch (index) {
758  switch (flags & VFIO_IRQ_SET_ACTION_TYPE_MASK) {
760  func = vfio_pci_set_intx_mask;
761  break;
763  func = vfio_pci_set_intx_unmask;
764  break;
766  func = vfio_pci_set_intx_trigger;
767  break;
768  }
769  break;
772  switch (flags & VFIO_IRQ_SET_ACTION_TYPE_MASK) {
775  /* XXX Need masking support exported */
776  break;
778  func = vfio_pci_set_msi_trigger;
779  break;
780  }
781  break;
782  }
783 
784  if (!func)
785  return -ENOTTY;
786 
787  return func(vdev, index, start, count, flags, data);
788 }