vfio_ccw_drv.c 6.4 KB

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