virqfd.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * VFIO generic eventfd code for IRQFD support.
  4. * Derived from drivers/vfio/pci/vfio_pci_intrs.c
  5. *
  6. * Copyright (C) 2012 Red Hat, Inc. All rights reserved.
  7. * Author: Alex Williamson <[email protected]>
  8. */
  9. #include <linux/vfio.h>
  10. #include <linux/eventfd.h>
  11. #include <linux/file.h>
  12. #include <linux/module.h>
  13. #include <linux/slab.h>
  14. #define DRIVER_VERSION "0.1"
  15. #define DRIVER_AUTHOR "Alex Williamson <[email protected]>"
  16. #define DRIVER_DESC "IRQFD support for VFIO bus drivers"
  17. static struct workqueue_struct *vfio_irqfd_cleanup_wq;
  18. static DEFINE_SPINLOCK(virqfd_lock);
  19. static int __init vfio_virqfd_init(void)
  20. {
  21. vfio_irqfd_cleanup_wq =
  22. create_singlethread_workqueue("vfio-irqfd-cleanup");
  23. if (!vfio_irqfd_cleanup_wq)
  24. return -ENOMEM;
  25. return 0;
  26. }
  27. static void __exit vfio_virqfd_exit(void)
  28. {
  29. destroy_workqueue(vfio_irqfd_cleanup_wq);
  30. }
  31. static void virqfd_deactivate(struct virqfd *virqfd)
  32. {
  33. queue_work(vfio_irqfd_cleanup_wq, &virqfd->shutdown);
  34. }
  35. static int virqfd_wakeup(wait_queue_entry_t *wait, unsigned mode, int sync, void *key)
  36. {
  37. struct virqfd *virqfd = container_of(wait, struct virqfd, wait);
  38. __poll_t flags = key_to_poll(key);
  39. if (flags & EPOLLIN) {
  40. u64 cnt;
  41. eventfd_ctx_do_read(virqfd->eventfd, &cnt);
  42. /* An event has been signaled, call function */
  43. if ((!virqfd->handler ||
  44. virqfd->handler(virqfd->opaque, virqfd->data)) &&
  45. virqfd->thread)
  46. schedule_work(&virqfd->inject);
  47. }
  48. if (flags & EPOLLHUP) {
  49. unsigned long flags;
  50. spin_lock_irqsave(&virqfd_lock, flags);
  51. /*
  52. * The eventfd is closing, if the virqfd has not yet been
  53. * queued for release, as determined by testing whether the
  54. * virqfd pointer to it is still valid, queue it now. As
  55. * with kvm irqfds, we know we won't race against the virqfd
  56. * going away because we hold the lock to get here.
  57. */
  58. if (*(virqfd->pvirqfd) == virqfd) {
  59. *(virqfd->pvirqfd) = NULL;
  60. virqfd_deactivate(virqfd);
  61. }
  62. spin_unlock_irqrestore(&virqfd_lock, flags);
  63. }
  64. return 0;
  65. }
  66. static void virqfd_ptable_queue_proc(struct file *file,
  67. wait_queue_head_t *wqh, poll_table *pt)
  68. {
  69. struct virqfd *virqfd = container_of(pt, struct virqfd, pt);
  70. add_wait_queue(wqh, &virqfd->wait);
  71. }
  72. static void virqfd_shutdown(struct work_struct *work)
  73. {
  74. struct virqfd *virqfd = container_of(work, struct virqfd, shutdown);
  75. u64 cnt;
  76. eventfd_ctx_remove_wait_queue(virqfd->eventfd, &virqfd->wait, &cnt);
  77. flush_work(&virqfd->inject);
  78. eventfd_ctx_put(virqfd->eventfd);
  79. kfree(virqfd);
  80. }
  81. static void virqfd_inject(struct work_struct *work)
  82. {
  83. struct virqfd *virqfd = container_of(work, struct virqfd, inject);
  84. if (virqfd->thread)
  85. virqfd->thread(virqfd->opaque, virqfd->data);
  86. }
  87. int vfio_virqfd_enable(void *opaque,
  88. int (*handler)(void *, void *),
  89. void (*thread)(void *, void *),
  90. void *data, struct virqfd **pvirqfd, int fd)
  91. {
  92. struct fd irqfd;
  93. struct eventfd_ctx *ctx;
  94. struct virqfd *virqfd;
  95. int ret = 0;
  96. __poll_t events;
  97. virqfd = kzalloc(sizeof(*virqfd), GFP_KERNEL);
  98. if (!virqfd)
  99. return -ENOMEM;
  100. virqfd->pvirqfd = pvirqfd;
  101. virqfd->opaque = opaque;
  102. virqfd->handler = handler;
  103. virqfd->thread = thread;
  104. virqfd->data = data;
  105. INIT_WORK(&virqfd->shutdown, virqfd_shutdown);
  106. INIT_WORK(&virqfd->inject, virqfd_inject);
  107. irqfd = fdget(fd);
  108. if (!irqfd.file) {
  109. ret = -EBADF;
  110. goto err_fd;
  111. }
  112. ctx = eventfd_ctx_fileget(irqfd.file);
  113. if (IS_ERR(ctx)) {
  114. ret = PTR_ERR(ctx);
  115. goto err_ctx;
  116. }
  117. virqfd->eventfd = ctx;
  118. /*
  119. * virqfds can be released by closing the eventfd or directly
  120. * through ioctl. These are both done through a workqueue, so
  121. * we update the pointer to the virqfd under lock to avoid
  122. * pushing multiple jobs to release the same virqfd.
  123. */
  124. spin_lock_irq(&virqfd_lock);
  125. if (*pvirqfd) {
  126. spin_unlock_irq(&virqfd_lock);
  127. ret = -EBUSY;
  128. goto err_busy;
  129. }
  130. *pvirqfd = virqfd;
  131. spin_unlock_irq(&virqfd_lock);
  132. /*
  133. * Install our own custom wake-up handling so we are notified via
  134. * a callback whenever someone signals the underlying eventfd.
  135. */
  136. init_waitqueue_func_entry(&virqfd->wait, virqfd_wakeup);
  137. init_poll_funcptr(&virqfd->pt, virqfd_ptable_queue_proc);
  138. events = vfs_poll(irqfd.file, &virqfd->pt);
  139. /*
  140. * Check if there was an event already pending on the eventfd
  141. * before we registered and trigger it as if we didn't miss it.
  142. */
  143. if (events & EPOLLIN) {
  144. if ((!handler || handler(opaque, data)) && thread)
  145. schedule_work(&virqfd->inject);
  146. }
  147. /*
  148. * Do not drop the file until the irqfd is fully initialized,
  149. * otherwise we might race against the EPOLLHUP.
  150. */
  151. fdput(irqfd);
  152. return 0;
  153. err_busy:
  154. eventfd_ctx_put(ctx);
  155. err_ctx:
  156. fdput(irqfd);
  157. err_fd:
  158. kfree(virqfd);
  159. return ret;
  160. }
  161. EXPORT_SYMBOL_GPL(vfio_virqfd_enable);
  162. void vfio_virqfd_disable(struct virqfd **pvirqfd)
  163. {
  164. unsigned long flags;
  165. spin_lock_irqsave(&virqfd_lock, flags);
  166. if (*pvirqfd) {
  167. virqfd_deactivate(*pvirqfd);
  168. *pvirqfd = NULL;
  169. }
  170. spin_unlock_irqrestore(&virqfd_lock, flags);
  171. /*
  172. * Block until we know all outstanding shutdown jobs have completed.
  173. * Even if we don't queue the job, flush the wq to be sure it's
  174. * been released.
  175. */
  176. flush_workqueue(vfio_irqfd_cleanup_wq);
  177. }
  178. EXPORT_SYMBOL_GPL(vfio_virqfd_disable);
  179. module_init(vfio_virqfd_init);
  180. module_exit(vfio_virqfd_exit);
  181. MODULE_VERSION(DRIVER_VERSION);
  182. MODULE_LICENSE("GPL v2");
  183. MODULE_AUTHOR(DRIVER_AUTHOR);
  184. MODULE_DESCRIPTION(DRIVER_DESC);