vfio_ccw_drv.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * VFIO based Physical Subchannel device driver
  4. *
  5. * Copyright IBM Corp. 2017
  6. *
  7. * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
  8. * Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
  9. */
  10. #include <linux/module.h>
  11. #include <linux/init.h>
  12. #include <linux/device.h>
  13. #include <linux/slab.h>
  14. #include <linux/uuid.h>
  15. #include <linux/mdev.h>
  16. #include <asm/isc.h>
  17. #include "ioasm.h"
  18. #include "css.h"
  19. #include "vfio_ccw_private.h"
  20. struct workqueue_struct *vfio_ccw_work_q;
  21. static struct kmem_cache *vfio_ccw_io_region;
  22. /*
  23. * Helpers
  24. */
  25. int vfio_ccw_sch_quiesce(struct subchannel *sch)
  26. {
  27. struct vfio_ccw_private *private = dev_get_drvdata(&sch->dev);
  28. DECLARE_COMPLETION_ONSTACK(completion);
  29. int iretry, ret = 0;
  30. spin_lock_irq(sch->lock);
  31. if (!sch->schib.pmcw.ena)
  32. goto out_unlock;
  33. ret = cio_disable_subchannel(sch);
  34. if (ret != -EBUSY)
  35. goto out_unlock;
  36. do {
  37. iretry = 255;
  38. ret = cio_cancel_halt_clear(sch, &iretry);
  39. while (ret == -EBUSY) {
  40. /*
  41. * Flush all I/O and wait for
  42. * cancel/halt/clear completion.
  43. */
  44. private->completion = &completion;
  45. spin_unlock_irq(sch->lock);
  46. wait_for_completion_timeout(&completion, 3*HZ);
  47. spin_lock_irq(sch->lock);
  48. private->completion = NULL;
  49. flush_workqueue(vfio_ccw_work_q);
  50. ret = cio_cancel_halt_clear(sch, &iretry);
  51. };
  52. ret = cio_disable_subchannel(sch);
  53. } while (ret == -EBUSY);
  54. out_unlock:
  55. private->state = VFIO_CCW_STATE_NOT_OPER;
  56. spin_unlock_irq(sch->lock);
  57. return ret;
  58. }
  59. static void vfio_ccw_sch_io_todo(struct work_struct *work)
  60. {
  61. struct vfio_ccw_private *private;
  62. struct irb *irb;
  63. private = container_of(work, struct vfio_ccw_private, io_work);
  64. irb = &private->irb;
  65. if (scsw_is_solicited(&irb->scsw)) {
  66. cp_update_scsw(&private->cp, &irb->scsw);
  67. cp_free(&private->cp);
  68. }
  69. memcpy(private->io_region->irb_area, irb, sizeof(*irb));
  70. if (private->io_trigger)
  71. eventfd_signal(private->io_trigger, 1);
  72. if (private->mdev)
  73. private->state = VFIO_CCW_STATE_IDLE;
  74. }
  75. /*
  76. * Css driver callbacks
  77. */
  78. static void vfio_ccw_sch_irq(struct subchannel *sch)
  79. {
  80. struct vfio_ccw_private *private = dev_get_drvdata(&sch->dev);
  81. inc_irq_stat(IRQIO_CIO);
  82. vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_INTERRUPT);
  83. }
  84. static int vfio_ccw_sch_probe(struct subchannel *sch)
  85. {
  86. struct pmcw *pmcw = &sch->schib.pmcw;
  87. struct vfio_ccw_private *private;
  88. int ret;
  89. if (pmcw->qf) {
  90. dev_warn(&sch->dev, "vfio: ccw: does not support QDIO: %s\n",
  91. dev_name(&sch->dev));
  92. return -ENODEV;
  93. }
  94. private = kzalloc(sizeof(*private), GFP_KERNEL | GFP_DMA);
  95. if (!private)
  96. return -ENOMEM;
  97. private->io_region = kmem_cache_zalloc(vfio_ccw_io_region,
  98. GFP_KERNEL | GFP_DMA);
  99. if (!private->io_region) {
  100. kfree(private);
  101. return -ENOMEM;
  102. }
  103. private->sch = sch;
  104. dev_set_drvdata(&sch->dev, private);
  105. spin_lock_irq(sch->lock);
  106. private->state = VFIO_CCW_STATE_NOT_OPER;
  107. sch->isc = VFIO_CCW_ISC;
  108. ret = cio_enable_subchannel(sch, (u32)(unsigned long)sch);
  109. spin_unlock_irq(sch->lock);
  110. if (ret)
  111. goto out_free;
  112. INIT_WORK(&private->io_work, vfio_ccw_sch_io_todo);
  113. atomic_set(&private->avail, 1);
  114. private->state = VFIO_CCW_STATE_STANDBY;
  115. ret = vfio_ccw_mdev_reg(sch);
  116. if (ret)
  117. goto out_disable;
  118. return 0;
  119. out_disable:
  120. cio_disable_subchannel(sch);
  121. out_free:
  122. dev_set_drvdata(&sch->dev, NULL);
  123. kmem_cache_free(vfio_ccw_io_region, private->io_region);
  124. kfree(private);
  125. return ret;
  126. }
  127. static int vfio_ccw_sch_remove(struct subchannel *sch)
  128. {
  129. struct vfio_ccw_private *private = dev_get_drvdata(&sch->dev);
  130. vfio_ccw_sch_quiesce(sch);
  131. vfio_ccw_mdev_unreg(sch);
  132. dev_set_drvdata(&sch->dev, NULL);
  133. kmem_cache_free(vfio_ccw_io_region, private->io_region);
  134. kfree(private);
  135. return 0;
  136. }
  137. static void vfio_ccw_sch_shutdown(struct subchannel *sch)
  138. {
  139. vfio_ccw_sch_quiesce(sch);
  140. }
  141. /**
  142. * vfio_ccw_sch_event - process subchannel event
  143. * @sch: subchannel
  144. * @process: non-zero if function is called in process context
  145. *
  146. * An unspecified event occurred for this subchannel. Adjust data according
  147. * to the current operational state of the subchannel. Return zero when the
  148. * event has been handled sufficiently or -EAGAIN when this function should
  149. * be called again in process context.
  150. */
  151. static int vfio_ccw_sch_event(struct subchannel *sch, int process)
  152. {
  153. struct vfio_ccw_private *private = dev_get_drvdata(&sch->dev);
  154. unsigned long flags;
  155. int rc = -EAGAIN;
  156. spin_lock_irqsave(sch->lock, flags);
  157. if (!device_is_registered(&sch->dev))
  158. goto out_unlock;
  159. if (work_pending(&sch->todo_work))
  160. goto out_unlock;
  161. if (cio_update_schib(sch)) {
  162. vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_NOT_OPER);
  163. rc = 0;
  164. goto out_unlock;
  165. }
  166. private = dev_get_drvdata(&sch->dev);
  167. if (private->state == VFIO_CCW_STATE_NOT_OPER) {
  168. private->state = private->mdev ? VFIO_CCW_STATE_IDLE :
  169. VFIO_CCW_STATE_STANDBY;
  170. }
  171. rc = 0;
  172. out_unlock:
  173. spin_unlock_irqrestore(sch->lock, flags);
  174. return rc;
  175. }
  176. static struct css_device_id vfio_ccw_sch_ids[] = {
  177. { .match_flags = 0x1, .type = SUBCHANNEL_TYPE_IO, },
  178. { /* end of list */ },
  179. };
  180. MODULE_DEVICE_TABLE(css, vfio_ccw_sch_ids);
  181. static struct css_driver vfio_ccw_sch_driver = {
  182. .drv = {
  183. .name = "vfio_ccw",
  184. .owner = THIS_MODULE,
  185. },
  186. .subchannel_type = vfio_ccw_sch_ids,
  187. .irq = vfio_ccw_sch_irq,
  188. .probe = vfio_ccw_sch_probe,
  189. .remove = vfio_ccw_sch_remove,
  190. .shutdown = vfio_ccw_sch_shutdown,
  191. .sch_event = vfio_ccw_sch_event,
  192. };
  193. static int __init vfio_ccw_sch_init(void)
  194. {
  195. int ret;
  196. vfio_ccw_work_q = create_singlethread_workqueue("vfio-ccw");
  197. if (!vfio_ccw_work_q)
  198. return -ENOMEM;
  199. vfio_ccw_io_region = kmem_cache_create_usercopy("vfio_ccw_io_region",
  200. sizeof(struct ccw_io_region), 0,
  201. SLAB_ACCOUNT, 0,
  202. sizeof(struct ccw_io_region), NULL);
  203. if (!vfio_ccw_io_region) {
  204. destroy_workqueue(vfio_ccw_work_q);
  205. return -ENOMEM;
  206. }
  207. isc_register(VFIO_CCW_ISC);
  208. ret = css_driver_register(&vfio_ccw_sch_driver);
  209. if (ret) {
  210. isc_unregister(VFIO_CCW_ISC);
  211. kmem_cache_destroy(vfio_ccw_io_region);
  212. destroy_workqueue(vfio_ccw_work_q);
  213. }
  214. return ret;
  215. }
  216. static void __exit vfio_ccw_sch_exit(void)
  217. {
  218. css_driver_unregister(&vfio_ccw_sch_driver);
  219. isc_unregister(VFIO_CCW_ISC);
  220. kmem_cache_destroy(vfio_ccw_io_region);
  221. destroy_workqueue(vfio_ccw_work_q);
  222. }
  223. module_init(vfio_ccw_sch_init);
  224. module_exit(vfio_ccw_sch_exit);
  225. MODULE_LICENSE("GPL v2");