vfio_platform_irq.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * VFIO platform devices interrupt handling
  4. *
  5. * Copyright (C) 2013 - Virtual Open Systems
  6. * Author: Antonios Motakis <a.motakis@virtualopensystems.com>
  7. */
  8. #include <linux/eventfd.h>
  9. #include <linux/interrupt.h>
  10. #include <linux/slab.h>
  11. #include <linux/types.h>
  12. #include <linux/vfio.h>
  13. #include <linux/irq.h>
  14. #include "vfio_platform_private.h"
  15. static void vfio_platform_mask(struct vfio_platform_irq *irq_ctx)
  16. {
  17. unsigned long flags;
  18. spin_lock_irqsave(&irq_ctx->lock, flags);
  19. if (!irq_ctx->masked) {
  20. disable_irq_nosync(irq_ctx->hwirq);
  21. irq_ctx->masked = true;
  22. }
  23. spin_unlock_irqrestore(&irq_ctx->lock, flags);
  24. }
  25. static int vfio_platform_mask_handler(void *opaque, void *unused)
  26. {
  27. struct vfio_platform_irq *irq_ctx = opaque;
  28. vfio_platform_mask(irq_ctx);
  29. return 0;
  30. }
  31. static int vfio_platform_set_irq_mask(struct vfio_platform_device *vdev,
  32. unsigned index, unsigned start,
  33. unsigned count, uint32_t flags,
  34. void *data)
  35. {
  36. if (start != 0 || count != 1)
  37. return -EINVAL;
  38. if (!(vdev->irqs[index].flags & VFIO_IRQ_INFO_MASKABLE))
  39. return -EINVAL;
  40. if (flags & VFIO_IRQ_SET_DATA_EVENTFD) {
  41. int32_t fd = *(int32_t *)data;
  42. if (fd >= 0)
  43. return vfio_virqfd_enable((void *) &vdev->irqs[index],
  44. vfio_platform_mask_handler,
  45. NULL, NULL,
  46. &vdev->irqs[index].mask, fd);
  47. vfio_virqfd_disable(&vdev->irqs[index].mask);
  48. return 0;
  49. }
  50. if (flags & VFIO_IRQ_SET_DATA_NONE) {
  51. vfio_platform_mask(&vdev->irqs[index]);
  52. } else if (flags & VFIO_IRQ_SET_DATA_BOOL) {
  53. uint8_t mask = *(uint8_t *)data;
  54. if (mask)
  55. vfio_platform_mask(&vdev->irqs[index]);
  56. }
  57. return 0;
  58. }
  59. static void vfio_platform_unmask(struct vfio_platform_irq *irq_ctx)
  60. {
  61. unsigned long flags;
  62. spin_lock_irqsave(&irq_ctx->lock, flags);
  63. if (irq_ctx->masked) {
  64. enable_irq(irq_ctx->hwirq);
  65. irq_ctx->masked = false;
  66. }
  67. spin_unlock_irqrestore(&irq_ctx->lock, flags);
  68. }
  69. static int vfio_platform_unmask_handler(void *opaque, void *unused)
  70. {
  71. struct vfio_platform_irq *irq_ctx = opaque;
  72. vfio_platform_unmask(irq_ctx);
  73. return 0;
  74. }
  75. static int vfio_platform_set_irq_unmask(struct vfio_platform_device *vdev,
  76. unsigned index, unsigned start,
  77. unsigned count, uint32_t flags,
  78. void *data)
  79. {
  80. if (start != 0 || count != 1)
  81. return -EINVAL;
  82. if (!(vdev->irqs[index].flags & VFIO_IRQ_INFO_MASKABLE))
  83. return -EINVAL;
  84. if (flags & VFIO_IRQ_SET_DATA_EVENTFD) {
  85. int32_t fd = *(int32_t *)data;
  86. if (fd >= 0)
  87. return vfio_virqfd_enable((void *) &vdev->irqs[index],
  88. vfio_platform_unmask_handler,
  89. NULL, NULL,
  90. &vdev->irqs[index].unmask,
  91. fd);
  92. vfio_virqfd_disable(&vdev->irqs[index].unmask);
  93. return 0;
  94. }
  95. if (flags & VFIO_IRQ_SET_DATA_NONE) {
  96. vfio_platform_unmask(&vdev->irqs[index]);
  97. } else if (flags & VFIO_IRQ_SET_DATA_BOOL) {
  98. uint8_t unmask = *(uint8_t *)data;
  99. if (unmask)
  100. vfio_platform_unmask(&vdev->irqs[index]);
  101. }
  102. return 0;
  103. }
  104. /*
  105. * The trigger eventfd is guaranteed valid in the interrupt path
  106. * and protected by the igate mutex when triggered via ioctl.
  107. */
  108. static void vfio_send_eventfd(struct vfio_platform_irq *irq_ctx)
  109. {
  110. if (likely(irq_ctx->trigger))
  111. eventfd_signal(irq_ctx->trigger);
  112. }
  113. static irqreturn_t vfio_automasked_irq_handler(int irq, void *dev_id)
  114. {
  115. struct vfio_platform_irq *irq_ctx = dev_id;
  116. unsigned long flags;
  117. int ret = IRQ_NONE;
  118. spin_lock_irqsave(&irq_ctx->lock, flags);
  119. if (!irq_ctx->masked) {
  120. ret = IRQ_HANDLED;
  121. /* automask maskable interrupts */
  122. disable_irq_nosync(irq_ctx->hwirq);
  123. irq_ctx->masked = true;
  124. }
  125. spin_unlock_irqrestore(&irq_ctx->lock, flags);
  126. if (ret == IRQ_HANDLED)
  127. vfio_send_eventfd(irq_ctx);
  128. return ret;
  129. }
  130. static irqreturn_t vfio_irq_handler(int irq, void *dev_id)
  131. {
  132. struct vfio_platform_irq *irq_ctx = dev_id;
  133. vfio_send_eventfd(irq_ctx);
  134. return IRQ_HANDLED;
  135. }
  136. static int vfio_set_trigger(struct vfio_platform_device *vdev, int index,
  137. int fd)
  138. {
  139. struct vfio_platform_irq *irq = &vdev->irqs[index];
  140. struct eventfd_ctx *trigger;
  141. if (irq->trigger) {
  142. disable_irq(irq->hwirq);
  143. eventfd_ctx_put(irq->trigger);
  144. irq->trigger = NULL;
  145. }
  146. if (fd < 0) /* Disable only */
  147. return 0;
  148. trigger = eventfd_ctx_fdget(fd);
  149. if (IS_ERR(trigger))
  150. return PTR_ERR(trigger);
  151. irq->trigger = trigger;
  152. /*
  153. * irq->masked effectively provides nested disables within the overall
  154. * enable relative to trigger. Specifically request_irq() is called
  155. * with NO_AUTOEN, therefore the IRQ is initially disabled. The user
  156. * may only further disable the IRQ with a MASK operations because
  157. * irq->masked is initially false.
  158. */
  159. enable_irq(irq->hwirq);
  160. return 0;
  161. }
  162. static int vfio_platform_set_irq_trigger(struct vfio_platform_device *vdev,
  163. unsigned index, unsigned start,
  164. unsigned count, uint32_t flags,
  165. void *data)
  166. {
  167. struct vfio_platform_irq *irq = &vdev->irqs[index];
  168. irq_handler_t handler;
  169. if (vdev->irqs[index].flags & VFIO_IRQ_INFO_AUTOMASKED)
  170. handler = vfio_automasked_irq_handler;
  171. else
  172. handler = vfio_irq_handler;
  173. if (!count && (flags & VFIO_IRQ_SET_DATA_NONE))
  174. return vfio_set_trigger(vdev, index, -1);
  175. if (start != 0 || count != 1)
  176. return -EINVAL;
  177. if (flags & VFIO_IRQ_SET_DATA_EVENTFD) {
  178. int32_t fd = *(int32_t *)data;
  179. return vfio_set_trigger(vdev, index, fd);
  180. }
  181. if (flags & VFIO_IRQ_SET_DATA_NONE) {
  182. handler(irq->hwirq, irq);
  183. } else if (flags & VFIO_IRQ_SET_DATA_BOOL) {
  184. uint8_t trigger = *(uint8_t *)data;
  185. if (trigger)
  186. handler(irq->hwirq, irq);
  187. }
  188. return 0;
  189. }
  190. int vfio_platform_set_irqs_ioctl(struct vfio_platform_device *vdev,
  191. uint32_t flags, unsigned index, unsigned start,
  192. unsigned count, void *data)
  193. {
  194. int (*func)(struct vfio_platform_device *vdev, unsigned index,
  195. unsigned start, unsigned count, uint32_t flags,
  196. void *data) = NULL;
  197. /*
  198. * For compatibility, errors from request_irq() are local to the
  199. * SET_IRQS path and reflected in the name pointer. This allows,
  200. * for example, polling mode fallback for an exclusive IRQ failure.
  201. */
  202. if (IS_ERR(vdev->irqs[index].name))
  203. return PTR_ERR(vdev->irqs[index].name);
  204. switch (flags & VFIO_IRQ_SET_ACTION_TYPE_MASK) {
  205. case VFIO_IRQ_SET_ACTION_MASK:
  206. func = vfio_platform_set_irq_mask;
  207. break;
  208. case VFIO_IRQ_SET_ACTION_UNMASK:
  209. func = vfio_platform_set_irq_unmask;
  210. break;
  211. case VFIO_IRQ_SET_ACTION_TRIGGER:
  212. func = vfio_platform_set_irq_trigger;
  213. break;
  214. }
  215. if (!func)
  216. return -ENOTTY;
  217. return func(vdev, index, start, count, flags, data);
  218. }
  219. int vfio_platform_irq_init(struct vfio_platform_device *vdev)
  220. {
  221. int cnt = 0, i, ret = 0;
  222. while (vdev->get_irq(vdev, cnt) >= 0)
  223. cnt++;
  224. vdev->irqs = kcalloc(cnt, sizeof(struct vfio_platform_irq),
  225. GFP_KERNEL_ACCOUNT);
  226. if (!vdev->irqs)
  227. return -ENOMEM;
  228. for (i = 0; i < cnt; i++) {
  229. int hwirq = vdev->get_irq(vdev, i);
  230. irq_handler_t handler = vfio_irq_handler;
  231. if (hwirq < 0) {
  232. ret = -EINVAL;
  233. goto err;
  234. }
  235. spin_lock_init(&vdev->irqs[i].lock);
  236. vdev->irqs[i].flags = VFIO_IRQ_INFO_EVENTFD;
  237. if (irq_get_trigger_type(hwirq) & IRQ_TYPE_LEVEL_MASK) {
  238. vdev->irqs[i].flags |= VFIO_IRQ_INFO_MASKABLE
  239. | VFIO_IRQ_INFO_AUTOMASKED;
  240. handler = vfio_automasked_irq_handler;
  241. }
  242. vdev->irqs[i].count = 1;
  243. vdev->irqs[i].hwirq = hwirq;
  244. vdev->irqs[i].masked = false;
  245. vdev->irqs[i].name = kasprintf(GFP_KERNEL_ACCOUNT,
  246. "vfio-irq[%d](%s)", hwirq,
  247. vdev->name);
  248. if (!vdev->irqs[i].name) {
  249. ret = -ENOMEM;
  250. goto err;
  251. }
  252. ret = request_irq(hwirq, handler, IRQF_NO_AUTOEN,
  253. vdev->irqs[i].name, &vdev->irqs[i]);
  254. if (ret) {
  255. kfree(vdev->irqs[i].name);
  256. vdev->irqs[i].name = ERR_PTR(ret);
  257. }
  258. }
  259. vdev->num_irqs = cnt;
  260. return 0;
  261. err:
  262. for (--i; i >= 0; i--) {
  263. if (!IS_ERR(vdev->irqs[i].name)) {
  264. free_irq(vdev->irqs[i].hwirq, &vdev->irqs[i]);
  265. kfree(vdev->irqs[i].name);
  266. }
  267. }
  268. kfree(vdev->irqs);
  269. return ret;
  270. }
  271. void vfio_platform_irq_cleanup(struct vfio_platform_device *vdev)
  272. {
  273. int i;
  274. for (i = 0; i < vdev->num_irqs; i++) {
  275. vfio_virqfd_disable(&vdev->irqs[i].mask);
  276. vfio_virqfd_disable(&vdev->irqs[i].unmask);
  277. if (!IS_ERR(vdev->irqs[i].name)) {
  278. free_irq(vdev->irqs[i].hwirq, &vdev->irqs[i]);
  279. if (vdev->irqs[i].trigger)
  280. eventfd_ctx_put(vdev->irqs[i].trigger);
  281. kfree(vdev->irqs[i].name);
  282. }
  283. }
  284. vdev->num_irqs = 0;
  285. kfree(vdev->irqs);
  286. }