trusty-virtio.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686
  1. /*
  2. * Trusty Virtio driver
  3. *
  4. * Copyright (C) 2015 Google, Inc.
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * version 2 as published by the Free Software Foundation.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. */
  15. #include <linux/device.h>
  16. #include <linux/err.h>
  17. #include <linux/kernel.h>
  18. #include <linux/module.h>
  19. #include <linux/mutex.h>
  20. #include <linux/notifier.h>
  21. #include <linux/workqueue.h>
  22. #include <linux/remoteproc.h>
  23. #include <linux/platform_device.h>
  24. #include <linux/trusty/smcall.h>
  25. #include <linux/trusty/trusty.h>
  26. #include <linux/virtio.h>
  27. #include <linux/virtio_config.h>
  28. #include <linux/virtio_ids.h>
  29. #include <linux/virtio_ring.h>
  30. #include <linux/atomic.h>
  31. #define RSC_DESCR_VER 1
  32. struct trusty_vdev;
  33. struct trusty_ctx {
  34. struct device *dev;
  35. void *shared_va;
  36. size_t shared_sz;
  37. struct work_struct check_vqs;
  38. struct work_struct kick_vqs;
  39. struct notifier_block call_notifier;
  40. struct list_head vdev_list;
  41. struct mutex mlock; /* protects vdev_list */
  42. };
  43. struct trusty_vring {
  44. void *vaddr;
  45. phys_addr_t paddr;
  46. size_t size;
  47. uint align;
  48. uint elem_num;
  49. u32 notifyid;
  50. atomic_t needs_kick;
  51. struct fw_rsc_vdev_vring *vr_descr;
  52. struct virtqueue *vq;
  53. struct trusty_vdev *tvdev;
  54. };
  55. struct trusty_vdev {
  56. struct list_head node;
  57. struct virtio_device vdev;
  58. struct trusty_ctx *tctx;
  59. u32 notifyid;
  60. uint config_len;
  61. void *config;
  62. struct fw_rsc_vdev *vdev_descr;
  63. uint vring_num;
  64. struct trusty_vring vrings[0];
  65. };
  66. #define vdev_to_tvdev(vd) container_of((vd), struct trusty_vdev, vdev)
  67. static void check_all_vqs(struct work_struct *work)
  68. {
  69. uint i;
  70. struct trusty_ctx *tctx = container_of(work, struct trusty_ctx,
  71. check_vqs);
  72. struct trusty_vdev *tvdev;
  73. list_for_each_entry(tvdev, &tctx->vdev_list, node) {
  74. for (i = 0; i < tvdev->vring_num; i++)
  75. vring_interrupt(0, tvdev->vrings[i].vq);
  76. }
  77. }
  78. static int trusty_call_notify(struct notifier_block *nb,
  79. unsigned long action, void *data)
  80. {
  81. struct trusty_ctx *tctx;
  82. if (action != TRUSTY_CALL_RETURNED)
  83. return NOTIFY_DONE;
  84. tctx = container_of(nb, struct trusty_ctx, call_notifier);
  85. schedule_work(&tctx->check_vqs);
  86. return NOTIFY_OK;
  87. }
  88. static void kick_vq(struct trusty_ctx *tctx,
  89. struct trusty_vdev *tvdev,
  90. struct trusty_vring *tvr)
  91. {
  92. int ret;
  93. dev_dbg(tctx->dev, "%s: vdev_id=%d: vq_id=%d\n",
  94. __func__, tvdev->notifyid, tvr->notifyid);
  95. ret = trusty_std_call32(tctx->dev->parent, SMC_SC_VDEV_KICK_VQ,
  96. tvdev->notifyid, tvr->notifyid, 0);
  97. if (ret) {
  98. dev_err(tctx->dev, "vq notify (%d, %d) returned %d\n",
  99. tvdev->notifyid, tvr->notifyid, ret);
  100. }
  101. }
  102. static void kick_vqs(struct work_struct *work)
  103. {
  104. uint i;
  105. struct trusty_vdev *tvdev;
  106. struct trusty_ctx *tctx = container_of(work, struct trusty_ctx,
  107. kick_vqs);
  108. mutex_lock(&tctx->mlock);
  109. list_for_each_entry(tvdev, &tctx->vdev_list, node) {
  110. for (i = 0; i < tvdev->vring_num; i++) {
  111. struct trusty_vring *tvr = &tvdev->vrings[i];
  112. if (atomic_xchg(&tvr->needs_kick, 0))
  113. kick_vq(tctx, tvdev, tvr);
  114. }
  115. }
  116. mutex_unlock(&tctx->mlock);
  117. }
  118. static bool trusty_virtio_notify(struct virtqueue *vq)
  119. {
  120. struct trusty_vring *tvr = vq->priv;
  121. struct trusty_vdev *tvdev = tvr->tvdev;
  122. struct trusty_ctx *tctx = tvdev->tctx;
  123. atomic_set(&tvr->needs_kick, 1);
  124. schedule_work(&tctx->kick_vqs);
  125. return true;
  126. }
  127. static int trusty_load_device_descr(struct trusty_ctx *tctx,
  128. void *va, size_t sz)
  129. {
  130. int ret;
  131. dev_dbg(tctx->dev, "%s: %zu bytes @ %p\n", __func__, sz, va);
  132. ret = trusty_call32_mem_buf(tctx->dev->parent,
  133. SMC_SC_VIRTIO_GET_DESCR,
  134. virt_to_page(va), sz, PAGE_KERNEL);
  135. if (ret < 0) {
  136. dev_err(tctx->dev, "%s: virtio get descr returned (%d)\n",
  137. __func__, ret);
  138. return -ENODEV;
  139. }
  140. return ret;
  141. }
  142. static void trusty_virtio_stop(struct trusty_ctx *tctx, void *va, size_t sz)
  143. {
  144. int ret;
  145. dev_dbg(tctx->dev, "%s: %zu bytes @ %p\n", __func__, sz, va);
  146. ret = trusty_call32_mem_buf(tctx->dev->parent, SMC_SC_VIRTIO_STOP,
  147. virt_to_page(va), sz, PAGE_KERNEL);
  148. if (ret) {
  149. dev_err(tctx->dev, "%s: virtio done returned (%d)\n",
  150. __func__, ret);
  151. return;
  152. }
  153. }
  154. static int trusty_virtio_start(struct trusty_ctx *tctx,
  155. void *va, size_t sz)
  156. {
  157. int ret;
  158. dev_dbg(tctx->dev, "%s: %zu bytes @ %p\n", __func__, sz, va);
  159. ret = trusty_call32_mem_buf(tctx->dev->parent, SMC_SC_VIRTIO_START,
  160. virt_to_page(va), sz, PAGE_KERNEL);
  161. if (ret) {
  162. dev_err(tctx->dev, "%s: virtio start returned (%d)\n",
  163. __func__, ret);
  164. return -ENODEV;
  165. }
  166. return 0;
  167. }
  168. static void trusty_virtio_reset(struct virtio_device *vdev)
  169. {
  170. struct trusty_vdev *tvdev = vdev_to_tvdev(vdev);
  171. struct trusty_ctx *tctx = tvdev->tctx;
  172. dev_dbg(&vdev->dev, "reset vdev_id=%d\n", tvdev->notifyid);
  173. trusty_std_call32(tctx->dev->parent, SMC_SC_VDEV_RESET,
  174. tvdev->notifyid, 0, 0);
  175. }
  176. static u32 trusty_virtio_get_features(struct virtio_device *vdev)
  177. {
  178. struct trusty_vdev *tvdev = vdev_to_tvdev(vdev);
  179. return tvdev->vdev_descr->dfeatures;
  180. }
  181. static void trusty_virtio_finalize_features(struct virtio_device *vdev)
  182. {
  183. struct trusty_vdev *tvdev = vdev_to_tvdev(vdev);
  184. tvdev->vdev_descr->gfeatures = vdev->features[0];
  185. }
  186. static void trusty_virtio_get_config(struct virtio_device *vdev,
  187. unsigned offset, void *buf,
  188. unsigned len)
  189. {
  190. struct trusty_vdev *tvdev = vdev_to_tvdev(vdev);
  191. dev_dbg(&vdev->dev, "%s: %d bytes @ offset %d\n",
  192. __func__, len, offset);
  193. if (tvdev->config) {
  194. if (offset + len <= tvdev->config_len)
  195. memcpy(buf, tvdev->config + offset, len);
  196. }
  197. }
  198. static void trusty_virtio_set_config(struct virtio_device *vdev,
  199. unsigned offset, const void *buf,
  200. unsigned len)
  201. {
  202. dev_dbg(&vdev->dev, "%s\n", __func__);
  203. }
  204. static u8 trusty_virtio_get_status(struct virtio_device *vdev)
  205. {
  206. struct trusty_vdev *tvdev = vdev_to_tvdev(vdev);
  207. return tvdev->vdev_descr->status;
  208. }
  209. static void trusty_virtio_set_status(struct virtio_device *vdev, u8 status)
  210. {
  211. struct trusty_vdev *tvdev = vdev_to_tvdev(vdev);
  212. tvdev->vdev_descr->status = status;
  213. }
  214. static void _del_vqs(struct virtio_device *vdev)
  215. {
  216. uint i;
  217. struct trusty_vdev *tvdev = vdev_to_tvdev(vdev);
  218. struct trusty_vring *tvr = &tvdev->vrings[0];
  219. for (i = 0; i < tvdev->vring_num; i++, tvr++) {
  220. /* delete vq */
  221. if (tvr->vq) {
  222. vring_del_virtqueue(tvr->vq);
  223. tvr->vq = NULL;
  224. }
  225. /* delete vring */
  226. if (tvr->vaddr) {
  227. free_pages_exact(tvr->vaddr, tvr->size);
  228. tvr->vaddr = NULL;
  229. }
  230. }
  231. }
  232. static void trusty_virtio_del_vqs(struct virtio_device *vdev)
  233. {
  234. dev_dbg(&vdev->dev, "%s\n", __func__);
  235. _del_vqs(vdev);
  236. }
  237. static struct virtqueue *_find_vq(struct virtio_device *vdev,
  238. unsigned id,
  239. void (*callback)(struct virtqueue *vq),
  240. const char *name)
  241. {
  242. struct trusty_vring *tvr;
  243. struct trusty_vdev *tvdev = vdev_to_tvdev(vdev);
  244. if (!name)
  245. return ERR_PTR(-EINVAL);
  246. if (id >= tvdev->vring_num)
  247. return ERR_PTR(-EINVAL);
  248. tvr = &tvdev->vrings[id];
  249. /* actual size of vring (in bytes) */
  250. tvr->size = PAGE_ALIGN(vring_size(tvr->elem_num, tvr->align));
  251. /* allocate memory for the vring. */
  252. tvr->vaddr = alloc_pages_exact(tvr->size, GFP_KERNEL | __GFP_ZERO);
  253. if (!tvr->vaddr) {
  254. dev_err(&vdev->dev, "vring alloc failed\n");
  255. return ERR_PTR(-ENOMEM);
  256. }
  257. /* save vring address to shared structure */
  258. tvr->vr_descr->da = (u32)virt_to_phys(tvr->vaddr);
  259. dev_info(&vdev->dev, "vring%d: va(pa) %p(%llx) qsz %d notifyid %d\n",
  260. id, tvr->vaddr, (u64)tvr->paddr, tvr->elem_num, tvr->notifyid);
  261. tvr->vq = vring_new_virtqueue(id, tvr->elem_num, tvr->align,
  262. vdev, true, tvr->vaddr,
  263. trusty_virtio_notify, callback, name);
  264. if (!tvr->vq) {
  265. dev_err(&vdev->dev, "vring_new_virtqueue %s failed\n",
  266. name);
  267. goto err_new_virtqueue;
  268. }
  269. tvr->vq->priv = tvr;
  270. return tvr->vq;
  271. err_new_virtqueue:
  272. free_pages_exact(tvr->vaddr, tvr->size);
  273. tvr->vaddr = NULL;
  274. return ERR_PTR(-ENOMEM);
  275. }
  276. static int trusty_virtio_find_vqs(struct virtio_device *vdev, unsigned nvqs,
  277. struct virtqueue *vqs[],
  278. vq_callback_t *callbacks[],
  279. const char *names[])
  280. {
  281. uint i;
  282. int ret;
  283. for (i = 0; i < nvqs; i++) {
  284. vqs[i] = _find_vq(vdev, i, callbacks[i], names[i]);
  285. if (IS_ERR(vqs[i])) {
  286. ret = PTR_ERR(vqs[i]);
  287. _del_vqs(vdev);
  288. return ret;
  289. }
  290. }
  291. return 0;
  292. }
  293. static const char *trusty_virtio_bus_name(struct virtio_device *vdev)
  294. {
  295. return "trusty-virtio";
  296. }
  297. /* The ops structure which hooks everything together. */
  298. static const struct virtio_config_ops trusty_virtio_config_ops = {
  299. .get_features = trusty_virtio_get_features,
  300. .finalize_features = trusty_virtio_finalize_features,
  301. .get = trusty_virtio_get_config,
  302. .set = trusty_virtio_set_config,
  303. .get_status = trusty_virtio_get_status,
  304. .set_status = trusty_virtio_set_status,
  305. .reset = trusty_virtio_reset,
  306. .find_vqs = trusty_virtio_find_vqs,
  307. .del_vqs = trusty_virtio_del_vqs,
  308. .bus_name = trusty_virtio_bus_name,
  309. };
  310. static int trusty_virtio_add_device(struct trusty_ctx *tctx,
  311. struct fw_rsc_vdev *vdev_descr,
  312. struct fw_rsc_vdev_vring *vr_descr,
  313. void *config)
  314. {
  315. int i, ret;
  316. struct trusty_vdev *tvdev;
  317. tvdev = kzalloc(sizeof(struct trusty_vdev) +
  318. vdev_descr->num_of_vrings * sizeof(struct trusty_vring),
  319. GFP_KERNEL);
  320. if (!tvdev) {
  321. dev_err(tctx->dev, "Failed to allocate VDEV\n");
  322. return -ENOMEM;
  323. }
  324. /* setup vdev */
  325. tvdev->tctx = tctx;
  326. tvdev->vdev.dev.parent = tctx->dev;
  327. tvdev->vdev.id.device = vdev_descr->id;
  328. tvdev->vdev.config = &trusty_virtio_config_ops;
  329. tvdev->vdev_descr = vdev_descr;
  330. tvdev->notifyid = vdev_descr->notifyid;
  331. /* setup config */
  332. tvdev->config = config;
  333. tvdev->config_len = vdev_descr->config_len;
  334. /* setup vrings and vdev resource */
  335. tvdev->vring_num = vdev_descr->num_of_vrings;
  336. for (i = 0; i < tvdev->vring_num; i++, vr_descr++) {
  337. struct trusty_vring *tvr = &tvdev->vrings[i];
  338. tvr->tvdev = tvdev;
  339. tvr->vr_descr = vr_descr;
  340. tvr->align = vr_descr->align;
  341. tvr->elem_num = vr_descr->num;
  342. tvr->notifyid = vr_descr->notifyid;
  343. }
  344. /* register device */
  345. ret = register_virtio_device(&tvdev->vdev);
  346. if (ret) {
  347. dev_err(tctx->dev,
  348. "Failed (%d) to register device dev type %u\n",
  349. ret, vdev_descr->id);
  350. goto err_register;
  351. }
  352. /* add it to tracking list */
  353. list_add_tail(&tvdev->node, &tctx->vdev_list);
  354. return 0;
  355. err_register:
  356. kfree(tvdev);
  357. return ret;
  358. }
  359. static int trusty_parse_device_descr(struct trusty_ctx *tctx,
  360. void *descr_va, size_t descr_sz)
  361. {
  362. u32 i;
  363. struct resource_table *descr = descr_va;
  364. if (descr_sz < sizeof(*descr)) {
  365. dev_err(tctx->dev, "descr table is too small (0x%x)\n",
  366. (int)descr_sz);
  367. return -ENODEV;
  368. }
  369. if (descr->ver != RSC_DESCR_VER) {
  370. dev_err(tctx->dev, "unexpected descr ver (0x%x)\n",
  371. (int)descr->ver);
  372. return -ENODEV;
  373. }
  374. if (descr_sz < (sizeof(*descr) + descr->num * sizeof(u32))) {
  375. dev_err(tctx->dev, "descr table is too small (0x%x)\n",
  376. (int)descr->ver);
  377. return -ENODEV;
  378. }
  379. for (i = 0; i < descr->num; i++) {
  380. struct fw_rsc_hdr *hdr;
  381. struct fw_rsc_vdev *vd;
  382. struct fw_rsc_vdev_vring *vr;
  383. void *cfg;
  384. size_t vd_sz;
  385. u32 offset = descr->offset[i];
  386. if (offset >= descr_sz) {
  387. dev_err(tctx->dev, "offset is out of bounds (%u)\n",
  388. (uint)offset);
  389. return -ENODEV;
  390. }
  391. /* check space for rsc header */
  392. if ((descr_sz - offset) < sizeof(struct fw_rsc_hdr)) {
  393. dev_err(tctx->dev, "no space for rsc header (%u)\n",
  394. (uint)offset);
  395. return -ENODEV;
  396. }
  397. hdr = (struct fw_rsc_hdr *)((u8 *)descr + offset);
  398. offset += sizeof(struct fw_rsc_hdr);
  399. /* check type */
  400. if (hdr->type != RSC_VDEV) {
  401. dev_err(tctx->dev, "unsupported rsc type (%u)\n",
  402. (uint)hdr->type);
  403. continue;
  404. }
  405. /* got vdev: check space for vdev */
  406. if ((descr_sz - offset) < sizeof(struct fw_rsc_vdev)) {
  407. dev_err(tctx->dev, "no space for vdev descr (%u)\n",
  408. (uint)offset);
  409. return -ENODEV;
  410. }
  411. vd = (struct fw_rsc_vdev *)((u8 *)descr + offset);
  412. /* check space for vrings and config area */
  413. vd_sz = sizeof(struct fw_rsc_vdev) +
  414. vd->num_of_vrings * sizeof(struct fw_rsc_vdev_vring) +
  415. vd->config_len;
  416. if ((descr_sz - offset) < vd_sz) {
  417. dev_err(tctx->dev, "no space for vdev (%u)\n",
  418. (uint)offset);
  419. return -ENODEV;
  420. }
  421. vr = (struct fw_rsc_vdev_vring *)vd->vring;
  422. cfg = (void *)(vr + vd->num_of_vrings);
  423. trusty_virtio_add_device(tctx, vd, vr, cfg);
  424. }
  425. return 0;
  426. }
  427. static void _remove_devices_locked(struct trusty_ctx *tctx)
  428. {
  429. struct trusty_vdev *tvdev, *next;
  430. list_for_each_entry_safe(tvdev, next, &tctx->vdev_list, node) {
  431. list_del(&tvdev->node);
  432. unregister_virtio_device(&tvdev->vdev);
  433. kfree(tvdev);
  434. }
  435. }
  436. static void trusty_virtio_remove_devices(struct trusty_ctx *tctx)
  437. {
  438. mutex_lock(&tctx->mlock);
  439. _remove_devices_locked(tctx);
  440. mutex_unlock(&tctx->mlock);
  441. }
  442. static int trusty_virtio_add_devices(struct trusty_ctx *tctx)
  443. {
  444. int ret;
  445. void *descr_va;
  446. size_t descr_sz;
  447. size_t descr_buf_sz;
  448. /* allocate buffer to load device descriptor into */
  449. descr_buf_sz = PAGE_SIZE;
  450. descr_va = alloc_pages_exact(descr_buf_sz, GFP_KERNEL | __GFP_ZERO);
  451. if (!descr_va) {
  452. dev_err(tctx->dev, "Failed to allocate shared area\n");
  453. return -ENOMEM;
  454. }
  455. /* load device descriptors */
  456. ret = trusty_load_device_descr(tctx, descr_va, descr_buf_sz);
  457. if (ret < 0) {
  458. dev_err(tctx->dev, "failed (%d) to load device descr\n", ret);
  459. goto err_load_descr;
  460. }
  461. descr_sz = (size_t)ret;
  462. mutex_lock(&tctx->mlock);
  463. /* parse device descriptor and add virtio devices */
  464. ret = trusty_parse_device_descr(tctx, descr_va, descr_sz);
  465. if (ret) {
  466. dev_err(tctx->dev, "failed (%d) to parse device descr\n", ret);
  467. goto err_parse_descr;
  468. }
  469. /* register call notifier */
  470. ret = trusty_call_notifier_register(tctx->dev->parent,
  471. &tctx->call_notifier);
  472. if (ret) {
  473. dev_err(tctx->dev, "%s: failed (%d) to register notifier\n",
  474. __func__, ret);
  475. goto err_register_notifier;
  476. }
  477. /* start virtio */
  478. ret = trusty_virtio_start(tctx, descr_va, descr_sz);
  479. if (ret) {
  480. dev_err(tctx->dev, "failed (%d) to start virtio\n", ret);
  481. goto err_start_virtio;
  482. }
  483. /* attach shared area */
  484. tctx->shared_va = descr_va;
  485. tctx->shared_sz = descr_buf_sz;
  486. mutex_unlock(&tctx->mlock);
  487. return 0;
  488. err_start_virtio:
  489. trusty_call_notifier_unregister(tctx->dev->parent,
  490. &tctx->call_notifier);
  491. cancel_work_sync(&tctx->check_vqs);
  492. err_register_notifier:
  493. err_parse_descr:
  494. _remove_devices_locked(tctx);
  495. mutex_unlock(&tctx->mlock);
  496. cancel_work_sync(&tctx->kick_vqs);
  497. trusty_virtio_stop(tctx, descr_va, descr_sz);
  498. err_load_descr:
  499. free_pages_exact(descr_va, descr_buf_sz);
  500. return ret;
  501. }
  502. static int trusty_virtio_probe(struct platform_device *pdev)
  503. {
  504. int ret;
  505. struct trusty_ctx *tctx;
  506. dev_info(&pdev->dev, "initializing\n");
  507. tctx = kzalloc(sizeof(*tctx), GFP_KERNEL);
  508. if (!tctx) {
  509. dev_err(&pdev->dev, "Failed to allocate context\n");
  510. return -ENOMEM;
  511. }
  512. tctx->dev = &pdev->dev;
  513. tctx->call_notifier.notifier_call = trusty_call_notify;
  514. mutex_init(&tctx->mlock);
  515. INIT_LIST_HEAD(&tctx->vdev_list);
  516. INIT_WORK(&tctx->check_vqs, check_all_vqs);
  517. INIT_WORK(&tctx->kick_vqs, kick_vqs);
  518. platform_set_drvdata(pdev, tctx);
  519. ret = trusty_virtio_add_devices(tctx);
  520. if (ret) {
  521. dev_err(&pdev->dev, "Failed to add virtio devices\n");
  522. goto err_add_devices;
  523. }
  524. dev_info(&pdev->dev, "initializing done\n");
  525. return 0;
  526. err_add_devices:
  527. kfree(tctx);
  528. return ret;
  529. }
  530. static int trusty_virtio_remove(struct platform_device *pdev)
  531. {
  532. struct trusty_ctx *tctx = platform_get_drvdata(pdev);
  533. dev_err(&pdev->dev, "removing\n");
  534. /* unregister call notifier and wait until workqueue is done */
  535. trusty_call_notifier_unregister(tctx->dev->parent,
  536. &tctx->call_notifier);
  537. cancel_work_sync(&tctx->check_vqs);
  538. /* remove virtio devices */
  539. trusty_virtio_remove_devices(tctx);
  540. cancel_work_sync(&tctx->kick_vqs);
  541. /* notify remote that shared area goes away */
  542. trusty_virtio_stop(tctx, tctx->shared_va, tctx->shared_sz);
  543. /* free shared area */
  544. free_pages_exact(tctx->shared_va, tctx->shared_sz);
  545. /* free context */
  546. kfree(tctx);
  547. return 0;
  548. }
  549. static const struct of_device_id trusty_of_match[] = {
  550. {
  551. .compatible = "android,trusty-virtio-v1",
  552. },
  553. };
  554. MODULE_DEVICE_TABLE(of, trusty_of_match);
  555. static struct platform_driver trusty_virtio_driver = {
  556. .probe = trusty_virtio_probe,
  557. .remove = trusty_virtio_remove,
  558. .driver = {
  559. .name = "trusty-virtio",
  560. .owner = THIS_MODULE,
  561. .of_match_table = trusty_of_match,
  562. },
  563. };
  564. module_platform_driver(trusty_virtio_driver);
  565. MODULE_LICENSE("GPL v2");
  566. MODULE_DESCRIPTION("Trusty virtio driver");