vfio_ccw_ops.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Physical device callbacks for vfio_ccw
  4. *
  5. * Copyright IBM Corp. 2017
  6. * Copyright Red Hat, Inc. 2019
  7. *
  8. * Author(s): Dong Jia Shi <[email protected]>
  9. * Xiao Feng Ren <[email protected]>
  10. * Cornelia Huck <[email protected]>
  11. */
  12. #include <linux/vfio.h>
  13. #include <linux/nospec.h>
  14. #include <linux/slab.h>
  15. #include "vfio_ccw_private.h"
  16. static const struct vfio_device_ops vfio_ccw_dev_ops;
  17. static int vfio_ccw_mdev_reset(struct vfio_ccw_private *private)
  18. {
  19. /*
  20. * If the FSM state is seen as Not Operational after closing
  21. * and re-opening the mdev, return an error.
  22. */
  23. vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_CLOSE);
  24. vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_OPEN);
  25. if (private->state == VFIO_CCW_STATE_NOT_OPER)
  26. return -EINVAL;
  27. return 0;
  28. }
  29. static void vfio_ccw_dma_unmap(struct vfio_device *vdev, u64 iova, u64 length)
  30. {
  31. struct vfio_ccw_private *private =
  32. container_of(vdev, struct vfio_ccw_private, vdev);
  33. /* Drivers MUST unpin pages in response to an invalidation. */
  34. if (!cp_iova_pinned(&private->cp, iova, length))
  35. return;
  36. vfio_ccw_mdev_reset(private);
  37. }
  38. static int vfio_ccw_mdev_init_dev(struct vfio_device *vdev)
  39. {
  40. struct vfio_ccw_private *private =
  41. container_of(vdev, struct vfio_ccw_private, vdev);
  42. init_completion(&private->release_comp);
  43. return 0;
  44. }
  45. static int vfio_ccw_mdev_probe(struct mdev_device *mdev)
  46. {
  47. struct vfio_ccw_private *private = dev_get_drvdata(mdev->dev.parent);
  48. int ret;
  49. if (private->state == VFIO_CCW_STATE_NOT_OPER)
  50. return -ENODEV;
  51. ret = vfio_init_device(&private->vdev, &mdev->dev, &vfio_ccw_dev_ops);
  52. if (ret)
  53. return ret;
  54. VFIO_CCW_MSG_EVENT(2, "sch %x.%x.%04x: create\n",
  55. private->sch->schid.cssid,
  56. private->sch->schid.ssid,
  57. private->sch->schid.sch_no);
  58. ret = vfio_register_emulated_iommu_dev(&private->vdev);
  59. if (ret)
  60. goto err_put_vdev;
  61. dev_set_drvdata(&mdev->dev, private);
  62. return 0;
  63. err_put_vdev:
  64. vfio_put_device(&private->vdev);
  65. return ret;
  66. }
  67. static void vfio_ccw_mdev_release_dev(struct vfio_device *vdev)
  68. {
  69. struct vfio_ccw_private *private =
  70. container_of(vdev, struct vfio_ccw_private, vdev);
  71. /*
  72. * We cannot free vfio_ccw_private here because it includes
  73. * parent info which must be free'ed by css driver.
  74. *
  75. * Use a workaround by memset'ing the core device part and
  76. * then notifying the remove path that all active references
  77. * to this device have been released.
  78. */
  79. memset(vdev, 0, sizeof(*vdev));
  80. complete(&private->release_comp);
  81. }
  82. static void vfio_ccw_mdev_remove(struct mdev_device *mdev)
  83. {
  84. struct vfio_ccw_private *private = dev_get_drvdata(mdev->dev.parent);
  85. VFIO_CCW_MSG_EVENT(2, "sch %x.%x.%04x: remove\n",
  86. private->sch->schid.cssid,
  87. private->sch->schid.ssid,
  88. private->sch->schid.sch_no);
  89. vfio_unregister_group_dev(&private->vdev);
  90. vfio_put_device(&private->vdev);
  91. /*
  92. * Wait for all active references on mdev are released so it
  93. * is safe to defer kfree() to a later point.
  94. *
  95. * TODO: the clean fix is to split parent/mdev info from ccw
  96. * private structure so each can be managed in its own life
  97. * cycle.
  98. */
  99. wait_for_completion(&private->release_comp);
  100. }
  101. static int vfio_ccw_mdev_open_device(struct vfio_device *vdev)
  102. {
  103. struct vfio_ccw_private *private =
  104. container_of(vdev, struct vfio_ccw_private, vdev);
  105. int ret;
  106. /* Device cannot simply be opened again from this state */
  107. if (private->state == VFIO_CCW_STATE_NOT_OPER)
  108. return -EINVAL;
  109. ret = vfio_ccw_register_async_dev_regions(private);
  110. if (ret)
  111. return ret;
  112. ret = vfio_ccw_register_schib_dev_regions(private);
  113. if (ret)
  114. goto out_unregister;
  115. ret = vfio_ccw_register_crw_dev_regions(private);
  116. if (ret)
  117. goto out_unregister;
  118. vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_OPEN);
  119. if (private->state == VFIO_CCW_STATE_NOT_OPER) {
  120. ret = -EINVAL;
  121. goto out_unregister;
  122. }
  123. return ret;
  124. out_unregister:
  125. vfio_ccw_unregister_dev_regions(private);
  126. return ret;
  127. }
  128. static void vfio_ccw_mdev_close_device(struct vfio_device *vdev)
  129. {
  130. struct vfio_ccw_private *private =
  131. container_of(vdev, struct vfio_ccw_private, vdev);
  132. vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_CLOSE);
  133. vfio_ccw_unregister_dev_regions(private);
  134. }
  135. static ssize_t vfio_ccw_mdev_read_io_region(struct vfio_ccw_private *private,
  136. char __user *buf, size_t count,
  137. loff_t *ppos)
  138. {
  139. loff_t pos = *ppos & VFIO_CCW_OFFSET_MASK;
  140. struct ccw_io_region *region;
  141. int ret;
  142. if (pos + count > sizeof(*region))
  143. return -EINVAL;
  144. mutex_lock(&private->io_mutex);
  145. region = private->io_region;
  146. if (copy_to_user(buf, (void *)region + pos, count))
  147. ret = -EFAULT;
  148. else
  149. ret = count;
  150. mutex_unlock(&private->io_mutex);
  151. return ret;
  152. }
  153. static ssize_t vfio_ccw_mdev_read(struct vfio_device *vdev,
  154. char __user *buf,
  155. size_t count,
  156. loff_t *ppos)
  157. {
  158. struct vfio_ccw_private *private =
  159. container_of(vdev, struct vfio_ccw_private, vdev);
  160. unsigned int index = VFIO_CCW_OFFSET_TO_INDEX(*ppos);
  161. if (index >= VFIO_CCW_NUM_REGIONS + private->num_regions)
  162. return -EINVAL;
  163. switch (index) {
  164. case VFIO_CCW_CONFIG_REGION_INDEX:
  165. return vfio_ccw_mdev_read_io_region(private, buf, count, ppos);
  166. default:
  167. index -= VFIO_CCW_NUM_REGIONS;
  168. return private->region[index].ops->read(private, buf, count,
  169. ppos);
  170. }
  171. return -EINVAL;
  172. }
  173. static ssize_t vfio_ccw_mdev_write_io_region(struct vfio_ccw_private *private,
  174. const char __user *buf,
  175. size_t count, loff_t *ppos)
  176. {
  177. loff_t pos = *ppos & VFIO_CCW_OFFSET_MASK;
  178. struct ccw_io_region *region;
  179. int ret;
  180. if (pos + count > sizeof(*region))
  181. return -EINVAL;
  182. if (!mutex_trylock(&private->io_mutex))
  183. return -EAGAIN;
  184. region = private->io_region;
  185. if (copy_from_user((void *)region + pos, buf, count)) {
  186. ret = -EFAULT;
  187. goto out_unlock;
  188. }
  189. vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_IO_REQ);
  190. ret = (region->ret_code != 0) ? region->ret_code : count;
  191. out_unlock:
  192. mutex_unlock(&private->io_mutex);
  193. return ret;
  194. }
  195. static ssize_t vfio_ccw_mdev_write(struct vfio_device *vdev,
  196. const char __user *buf,
  197. size_t count,
  198. loff_t *ppos)
  199. {
  200. struct vfio_ccw_private *private =
  201. container_of(vdev, struct vfio_ccw_private, vdev);
  202. unsigned int index = VFIO_CCW_OFFSET_TO_INDEX(*ppos);
  203. if (index >= VFIO_CCW_NUM_REGIONS + private->num_regions)
  204. return -EINVAL;
  205. switch (index) {
  206. case VFIO_CCW_CONFIG_REGION_INDEX:
  207. return vfio_ccw_mdev_write_io_region(private, buf, count, ppos);
  208. default:
  209. index -= VFIO_CCW_NUM_REGIONS;
  210. return private->region[index].ops->write(private, buf, count,
  211. ppos);
  212. }
  213. return -EINVAL;
  214. }
  215. static int vfio_ccw_mdev_get_device_info(struct vfio_ccw_private *private,
  216. struct vfio_device_info *info)
  217. {
  218. info->flags = VFIO_DEVICE_FLAGS_CCW | VFIO_DEVICE_FLAGS_RESET;
  219. info->num_regions = VFIO_CCW_NUM_REGIONS + private->num_regions;
  220. info->num_irqs = VFIO_CCW_NUM_IRQS;
  221. return 0;
  222. }
  223. static int vfio_ccw_mdev_get_region_info(struct vfio_ccw_private *private,
  224. struct vfio_region_info *info,
  225. unsigned long arg)
  226. {
  227. int i;
  228. switch (info->index) {
  229. case VFIO_CCW_CONFIG_REGION_INDEX:
  230. info->offset = 0;
  231. info->size = sizeof(struct ccw_io_region);
  232. info->flags = VFIO_REGION_INFO_FLAG_READ
  233. | VFIO_REGION_INFO_FLAG_WRITE;
  234. return 0;
  235. default: /* all other regions are handled via capability chain */
  236. {
  237. struct vfio_info_cap caps = { .buf = NULL, .size = 0 };
  238. struct vfio_region_info_cap_type cap_type = {
  239. .header.id = VFIO_REGION_INFO_CAP_TYPE,
  240. .header.version = 1 };
  241. int ret;
  242. if (info->index >=
  243. VFIO_CCW_NUM_REGIONS + private->num_regions)
  244. return -EINVAL;
  245. info->index = array_index_nospec(info->index,
  246. VFIO_CCW_NUM_REGIONS +
  247. private->num_regions);
  248. i = info->index - VFIO_CCW_NUM_REGIONS;
  249. info->offset = VFIO_CCW_INDEX_TO_OFFSET(info->index);
  250. info->size = private->region[i].size;
  251. info->flags = private->region[i].flags;
  252. cap_type.type = private->region[i].type;
  253. cap_type.subtype = private->region[i].subtype;
  254. ret = vfio_info_add_capability(&caps, &cap_type.header,
  255. sizeof(cap_type));
  256. if (ret)
  257. return ret;
  258. info->flags |= VFIO_REGION_INFO_FLAG_CAPS;
  259. if (info->argsz < sizeof(*info) + caps.size) {
  260. info->argsz = sizeof(*info) + caps.size;
  261. info->cap_offset = 0;
  262. } else {
  263. vfio_info_cap_shift(&caps, sizeof(*info));
  264. if (copy_to_user((void __user *)arg + sizeof(*info),
  265. caps.buf, caps.size)) {
  266. kfree(caps.buf);
  267. return -EFAULT;
  268. }
  269. info->cap_offset = sizeof(*info);
  270. }
  271. kfree(caps.buf);
  272. }
  273. }
  274. return 0;
  275. }
  276. static int vfio_ccw_mdev_get_irq_info(struct vfio_irq_info *info)
  277. {
  278. switch (info->index) {
  279. case VFIO_CCW_IO_IRQ_INDEX:
  280. case VFIO_CCW_CRW_IRQ_INDEX:
  281. case VFIO_CCW_REQ_IRQ_INDEX:
  282. info->count = 1;
  283. info->flags = VFIO_IRQ_INFO_EVENTFD;
  284. break;
  285. default:
  286. return -EINVAL;
  287. }
  288. return 0;
  289. }
  290. static int vfio_ccw_mdev_set_irqs(struct vfio_ccw_private *private,
  291. uint32_t flags,
  292. uint32_t index,
  293. void __user *data)
  294. {
  295. struct eventfd_ctx **ctx;
  296. if (!(flags & VFIO_IRQ_SET_ACTION_TRIGGER))
  297. return -EINVAL;
  298. switch (index) {
  299. case VFIO_CCW_IO_IRQ_INDEX:
  300. ctx = &private->io_trigger;
  301. break;
  302. case VFIO_CCW_CRW_IRQ_INDEX:
  303. ctx = &private->crw_trigger;
  304. break;
  305. case VFIO_CCW_REQ_IRQ_INDEX:
  306. ctx = &private->req_trigger;
  307. break;
  308. default:
  309. return -EINVAL;
  310. }
  311. switch (flags & VFIO_IRQ_SET_DATA_TYPE_MASK) {
  312. case VFIO_IRQ_SET_DATA_NONE:
  313. {
  314. if (*ctx)
  315. eventfd_signal(*ctx, 1);
  316. return 0;
  317. }
  318. case VFIO_IRQ_SET_DATA_BOOL:
  319. {
  320. uint8_t trigger;
  321. if (get_user(trigger, (uint8_t __user *)data))
  322. return -EFAULT;
  323. if (trigger && *ctx)
  324. eventfd_signal(*ctx, 1);
  325. return 0;
  326. }
  327. case VFIO_IRQ_SET_DATA_EVENTFD:
  328. {
  329. int32_t fd;
  330. if (get_user(fd, (int32_t __user *)data))
  331. return -EFAULT;
  332. if (fd == -1) {
  333. if (*ctx)
  334. eventfd_ctx_put(*ctx);
  335. *ctx = NULL;
  336. } else if (fd >= 0) {
  337. struct eventfd_ctx *efdctx;
  338. efdctx = eventfd_ctx_fdget(fd);
  339. if (IS_ERR(efdctx))
  340. return PTR_ERR(efdctx);
  341. if (*ctx)
  342. eventfd_ctx_put(*ctx);
  343. *ctx = efdctx;
  344. } else
  345. return -EINVAL;
  346. return 0;
  347. }
  348. default:
  349. return -EINVAL;
  350. }
  351. }
  352. int vfio_ccw_register_dev_region(struct vfio_ccw_private *private,
  353. unsigned int subtype,
  354. const struct vfio_ccw_regops *ops,
  355. size_t size, u32 flags, void *data)
  356. {
  357. struct vfio_ccw_region *region;
  358. region = krealloc(private->region,
  359. (private->num_regions + 1) * sizeof(*region),
  360. GFP_KERNEL);
  361. if (!region)
  362. return -ENOMEM;
  363. private->region = region;
  364. private->region[private->num_regions].type = VFIO_REGION_TYPE_CCW;
  365. private->region[private->num_regions].subtype = subtype;
  366. private->region[private->num_regions].ops = ops;
  367. private->region[private->num_regions].size = size;
  368. private->region[private->num_regions].flags = flags;
  369. private->region[private->num_regions].data = data;
  370. private->num_regions++;
  371. return 0;
  372. }
  373. void vfio_ccw_unregister_dev_regions(struct vfio_ccw_private *private)
  374. {
  375. int i;
  376. for (i = 0; i < private->num_regions; i++)
  377. private->region[i].ops->release(private, &private->region[i]);
  378. private->num_regions = 0;
  379. kfree(private->region);
  380. private->region = NULL;
  381. }
  382. static ssize_t vfio_ccw_mdev_ioctl(struct vfio_device *vdev,
  383. unsigned int cmd,
  384. unsigned long arg)
  385. {
  386. struct vfio_ccw_private *private =
  387. container_of(vdev, struct vfio_ccw_private, vdev);
  388. int ret = 0;
  389. unsigned long minsz;
  390. switch (cmd) {
  391. case VFIO_DEVICE_GET_INFO:
  392. {
  393. struct vfio_device_info info;
  394. minsz = offsetofend(struct vfio_device_info, num_irqs);
  395. if (copy_from_user(&info, (void __user *)arg, minsz))
  396. return -EFAULT;
  397. if (info.argsz < minsz)
  398. return -EINVAL;
  399. ret = vfio_ccw_mdev_get_device_info(private, &info);
  400. if (ret)
  401. return ret;
  402. return copy_to_user((void __user *)arg, &info, minsz) ? -EFAULT : 0;
  403. }
  404. case VFIO_DEVICE_GET_REGION_INFO:
  405. {
  406. struct vfio_region_info info;
  407. minsz = offsetofend(struct vfio_region_info, offset);
  408. if (copy_from_user(&info, (void __user *)arg, minsz))
  409. return -EFAULT;
  410. if (info.argsz < minsz)
  411. return -EINVAL;
  412. ret = vfio_ccw_mdev_get_region_info(private, &info, arg);
  413. if (ret)
  414. return ret;
  415. return copy_to_user((void __user *)arg, &info, minsz) ? -EFAULT : 0;
  416. }
  417. case VFIO_DEVICE_GET_IRQ_INFO:
  418. {
  419. struct vfio_irq_info info;
  420. minsz = offsetofend(struct vfio_irq_info, count);
  421. if (copy_from_user(&info, (void __user *)arg, minsz))
  422. return -EFAULT;
  423. if (info.argsz < minsz || info.index >= VFIO_CCW_NUM_IRQS)
  424. return -EINVAL;
  425. ret = vfio_ccw_mdev_get_irq_info(&info);
  426. if (ret)
  427. return ret;
  428. if (info.count == -1)
  429. return -EINVAL;
  430. return copy_to_user((void __user *)arg, &info, minsz) ? -EFAULT : 0;
  431. }
  432. case VFIO_DEVICE_SET_IRQS:
  433. {
  434. struct vfio_irq_set hdr;
  435. size_t data_size;
  436. void __user *data;
  437. minsz = offsetofend(struct vfio_irq_set, count);
  438. if (copy_from_user(&hdr, (void __user *)arg, minsz))
  439. return -EFAULT;
  440. ret = vfio_set_irqs_validate_and_prepare(&hdr, 1,
  441. VFIO_CCW_NUM_IRQS,
  442. &data_size);
  443. if (ret)
  444. return ret;
  445. data = (void __user *)(arg + minsz);
  446. return vfio_ccw_mdev_set_irqs(private, hdr.flags, hdr.index,
  447. data);
  448. }
  449. case VFIO_DEVICE_RESET:
  450. return vfio_ccw_mdev_reset(private);
  451. default:
  452. return -ENOTTY;
  453. }
  454. }
  455. /* Request removal of the device*/
  456. static void vfio_ccw_mdev_request(struct vfio_device *vdev, unsigned int count)
  457. {
  458. struct vfio_ccw_private *private =
  459. container_of(vdev, struct vfio_ccw_private, vdev);
  460. struct device *dev = vdev->dev;
  461. if (private->req_trigger) {
  462. if (!(count % 10))
  463. dev_notice_ratelimited(dev,
  464. "Relaying device request to user (#%u)\n",
  465. count);
  466. eventfd_signal(private->req_trigger, 1);
  467. } else if (count == 0) {
  468. dev_notice(dev,
  469. "No device request channel registered, blocked until released by user\n");
  470. }
  471. }
  472. static const struct vfio_device_ops vfio_ccw_dev_ops = {
  473. .init = vfio_ccw_mdev_init_dev,
  474. .release = vfio_ccw_mdev_release_dev,
  475. .open_device = vfio_ccw_mdev_open_device,
  476. .close_device = vfio_ccw_mdev_close_device,
  477. .read = vfio_ccw_mdev_read,
  478. .write = vfio_ccw_mdev_write,
  479. .ioctl = vfio_ccw_mdev_ioctl,
  480. .request = vfio_ccw_mdev_request,
  481. .dma_unmap = vfio_ccw_dma_unmap,
  482. };
  483. struct mdev_driver vfio_ccw_mdev_driver = {
  484. .device_api = VFIO_DEVICE_API_CCW_STRING,
  485. .max_instances = 1,
  486. .driver = {
  487. .name = "vfio_ccw_mdev",
  488. .owner = THIS_MODULE,
  489. .mod_name = KBUILD_MODNAME,
  490. },
  491. .probe = vfio_ccw_mdev_probe,
  492. .remove = vfio_ccw_mdev_remove,
  493. };