core.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2023, Arm Limited
  4. */
  5. #include <linux/arm_ffa.h>
  6. #include <linux/err.h>
  7. #include <linux/errno.h>
  8. #include <linux/kernel.h>
  9. #include <linux/limits.h>
  10. #include <linux/mm.h>
  11. #include <linux/module.h>
  12. #include <linux/scatterlist.h>
  13. #include <linux/slab.h>
  14. #include <linux/tee_core.h>
  15. #include <linux/types.h>
  16. #include <linux/uuid.h>
  17. #include <linux/xarray.h>
  18. #include "tstee_private.h"
  19. #define FFA_DIRECT_REQ_ARG_NUM 5
  20. #define FFA_INVALID_MEM_HANDLE U64_MAX
  21. static void arg_list_to_ffa_data(const u32 *args,
  22. struct ffa_send_direct_data *data)
  23. {
  24. data->data0 = args[0];
  25. data->data1 = args[1];
  26. data->data2 = args[2];
  27. data->data3 = args[3];
  28. data->data4 = args[4];
  29. }
  30. static void arg_list_from_ffa_data(const struct ffa_send_direct_data *data,
  31. u32 *args)
  32. {
  33. args[0] = lower_32_bits(data->data0);
  34. args[1] = lower_32_bits(data->data1);
  35. args[2] = lower_32_bits(data->data2);
  36. args[3] = lower_32_bits(data->data3);
  37. args[4] = lower_32_bits(data->data4);
  38. }
  39. static void tstee_get_version(struct tee_device *teedev,
  40. struct tee_ioctl_version_data *vers)
  41. {
  42. struct tstee *tstee = tee_get_drvdata(teedev);
  43. struct tee_ioctl_version_data v = {
  44. .impl_id = TEE_IMPL_ID_TSTEE,
  45. /* FF-A endpoint ID only uses the lower 16 bits */
  46. .impl_caps = lower_16_bits(tstee->ffa_dev->vm_id),
  47. .gen_caps = 0,
  48. };
  49. *vers = v;
  50. }
  51. static int tstee_open(struct tee_context *ctx)
  52. {
  53. struct ts_context_data *ctxdata;
  54. ctxdata = kzalloc_obj(*ctxdata);
  55. if (!ctxdata)
  56. return -ENOMEM;
  57. xa_init_flags(&ctxdata->sess_list, XA_FLAGS_ALLOC);
  58. ctx->data = ctxdata;
  59. return 0;
  60. }
  61. static void tstee_release(struct tee_context *ctx)
  62. {
  63. struct ts_context_data *ctxdata = ctx->data;
  64. struct ts_session *sess;
  65. unsigned long idx;
  66. if (!ctxdata)
  67. return;
  68. xa_for_each(&ctxdata->sess_list, idx, sess) {
  69. xa_erase(&ctxdata->sess_list, idx);
  70. kfree(sess);
  71. }
  72. xa_destroy(&ctxdata->sess_list);
  73. kfree(ctxdata);
  74. ctx->data = NULL;
  75. }
  76. static int tstee_open_session(struct tee_context *ctx,
  77. struct tee_ioctl_open_session_arg *arg,
  78. struct tee_param *param __always_unused)
  79. {
  80. struct tstee *tstee = tee_get_drvdata(ctx->teedev);
  81. struct ffa_device *ffa_dev = tstee->ffa_dev;
  82. struct ts_context_data *ctxdata = ctx->data;
  83. struct ffa_send_direct_data ffa_data;
  84. struct ts_session *sess = NULL;
  85. u32 ffa_args[FFA_DIRECT_REQ_ARG_NUM] = {};
  86. u32 sess_id;
  87. int rc;
  88. ffa_args[TS_RPC_CTRL_REG] =
  89. TS_RPC_CTRL_PACK_IFACE_OPCODE(TS_RPC_MGMT_IFACE_ID,
  90. TS_RPC_OP_SERVICE_INFO);
  91. memcpy(ffa_args + TS_RPC_SERVICE_INFO_UUID0, arg->uuid, UUID_SIZE);
  92. arg_list_to_ffa_data(ffa_args, &ffa_data);
  93. rc = ffa_dev->ops->msg_ops->sync_send_receive(ffa_dev, &ffa_data);
  94. if (rc)
  95. return rc;
  96. arg_list_from_ffa_data(&ffa_data, ffa_args);
  97. if (ffa_args[TS_RPC_SERVICE_INFO_RPC_STATUS] != TS_RPC_OK)
  98. return -ENODEV;
  99. if (ffa_args[TS_RPC_SERVICE_INFO_IFACE] > U8_MAX)
  100. return -EINVAL;
  101. sess = kzalloc_obj(*sess);
  102. if (!sess)
  103. return -ENOMEM;
  104. sess->iface_id = ffa_args[TS_RPC_SERVICE_INFO_IFACE];
  105. rc = xa_alloc(&ctxdata->sess_list, &sess_id, sess, xa_limit_32b,
  106. GFP_KERNEL);
  107. if (rc) {
  108. kfree(sess);
  109. return rc;
  110. }
  111. arg->session = sess_id;
  112. arg->ret = 0;
  113. return 0;
  114. }
  115. static int tstee_close_session(struct tee_context *ctx, u32 session)
  116. {
  117. struct ts_context_data *ctxdata = ctx->data;
  118. struct ts_session *sess;
  119. /* Calls xa_lock() internally */
  120. sess = xa_erase(&ctxdata->sess_list, session);
  121. if (!sess)
  122. return -EINVAL;
  123. kfree(sess);
  124. return 0;
  125. }
  126. static int tstee_invoke_func(struct tee_context *ctx,
  127. struct tee_ioctl_invoke_arg *arg,
  128. struct tee_param *param)
  129. {
  130. struct tstee *tstee = tee_get_drvdata(ctx->teedev);
  131. struct ffa_device *ffa_dev = tstee->ffa_dev;
  132. struct ts_context_data *ctxdata = ctx->data;
  133. struct ffa_send_direct_data ffa_data;
  134. struct tee_shm *shm = NULL;
  135. struct ts_session *sess;
  136. u32 req_len, ffa_args[FFA_DIRECT_REQ_ARG_NUM] = {};
  137. int shm_id, rc;
  138. u8 iface_id;
  139. u64 handle;
  140. u16 opcode;
  141. xa_lock(&ctxdata->sess_list);
  142. sess = xa_load(&ctxdata->sess_list, arg->session);
  143. /*
  144. * Do this while holding the lock to make sure that the session wasn't
  145. * closed meanwhile
  146. */
  147. if (sess)
  148. iface_id = sess->iface_id;
  149. xa_unlock(&ctxdata->sess_list);
  150. if (!sess)
  151. return -EINVAL;
  152. opcode = lower_16_bits(arg->func);
  153. shm_id = lower_32_bits(param[0].u.value.a);
  154. req_len = lower_32_bits(param[0].u.value.b);
  155. if (shm_id != 0) {
  156. shm = tee_shm_get_from_id(ctx, shm_id);
  157. if (IS_ERR(shm))
  158. return PTR_ERR(shm);
  159. if (shm->size < req_len) {
  160. dev_err(&ffa_dev->dev,
  161. "request doesn't fit into shared memory buffer\n");
  162. rc = -EINVAL;
  163. goto out;
  164. }
  165. handle = shm->sec_world_id;
  166. } else {
  167. handle = FFA_INVALID_MEM_HANDLE;
  168. }
  169. ffa_args[TS_RPC_CTRL_REG] = TS_RPC_CTRL_PACK_IFACE_OPCODE(iface_id,
  170. opcode);
  171. ffa_args[TS_RPC_SERVICE_MEM_HANDLE_LSW] = lower_32_bits(handle);
  172. ffa_args[TS_RPC_SERVICE_MEM_HANDLE_MSW] = upper_32_bits(handle);
  173. ffa_args[TS_RPC_SERVICE_REQ_LEN] = req_len;
  174. ffa_args[TS_RPC_SERVICE_CLIENT_ID] = 0;
  175. arg_list_to_ffa_data(ffa_args, &ffa_data);
  176. rc = ffa_dev->ops->msg_ops->sync_send_receive(ffa_dev, &ffa_data);
  177. if (rc)
  178. goto out;
  179. arg_list_from_ffa_data(&ffa_data, ffa_args);
  180. if (ffa_args[TS_RPC_SERVICE_RPC_STATUS] != TS_RPC_OK) {
  181. dev_err(&ffa_dev->dev, "invoke_func rpc status: %d\n",
  182. ffa_args[TS_RPC_SERVICE_RPC_STATUS]);
  183. rc = -EINVAL;
  184. goto out;
  185. }
  186. arg->ret = ffa_args[TS_RPC_SERVICE_STATUS];
  187. if (shm && shm->size >= ffa_args[TS_RPC_SERVICE_RESP_LEN])
  188. param[0].u.value.a = ffa_args[TS_RPC_SERVICE_RESP_LEN];
  189. out:
  190. if (shm)
  191. tee_shm_put(shm);
  192. return rc;
  193. }
  194. static int tstee_shm_register(struct tee_context *ctx, struct tee_shm *shm,
  195. struct page **pages, size_t num_pages,
  196. unsigned long start __always_unused)
  197. {
  198. struct tstee *tstee = tee_get_drvdata(ctx->teedev);
  199. struct ffa_device *ffa_dev = tstee->ffa_dev;
  200. struct ffa_mem_region_attributes mem_attr = {
  201. .receiver = tstee->ffa_dev->vm_id,
  202. .attrs = FFA_MEM_RW,
  203. .flag = 0,
  204. };
  205. struct ffa_mem_ops_args mem_args = {
  206. .attrs = &mem_attr,
  207. .use_txbuf = true,
  208. .nattrs = 1,
  209. .flags = 0,
  210. };
  211. struct ffa_send_direct_data ffa_data;
  212. struct sg_table sgt;
  213. u32 ffa_args[FFA_DIRECT_REQ_ARG_NUM] = {};
  214. int rc;
  215. rc = sg_alloc_table_from_pages(&sgt, pages, num_pages, 0,
  216. num_pages * PAGE_SIZE, GFP_KERNEL);
  217. if (rc)
  218. return rc;
  219. mem_args.sg = sgt.sgl;
  220. rc = ffa_dev->ops->mem_ops->memory_share(&mem_args);
  221. sg_free_table(&sgt);
  222. if (rc)
  223. return rc;
  224. shm->sec_world_id = mem_args.g_handle;
  225. ffa_args[TS_RPC_CTRL_REG] =
  226. TS_RPC_CTRL_PACK_IFACE_OPCODE(TS_RPC_MGMT_IFACE_ID,
  227. TS_RPC_OP_RETRIEVE_MEM);
  228. ffa_args[TS_RPC_RETRIEVE_MEM_HANDLE_LSW] =
  229. lower_32_bits(shm->sec_world_id);
  230. ffa_args[TS_RPC_RETRIEVE_MEM_HANDLE_MSW] =
  231. upper_32_bits(shm->sec_world_id);
  232. ffa_args[TS_RPC_RETRIEVE_MEM_TAG_LSW] = 0;
  233. ffa_args[TS_RPC_RETRIEVE_MEM_TAG_MSW] = 0;
  234. arg_list_to_ffa_data(ffa_args, &ffa_data);
  235. rc = ffa_dev->ops->msg_ops->sync_send_receive(ffa_dev, &ffa_data);
  236. if (rc) {
  237. (void)ffa_dev->ops->mem_ops->memory_reclaim(shm->sec_world_id,
  238. 0);
  239. return rc;
  240. }
  241. arg_list_from_ffa_data(&ffa_data, ffa_args);
  242. if (ffa_args[TS_RPC_RETRIEVE_MEM_RPC_STATUS] != TS_RPC_OK) {
  243. dev_err(&ffa_dev->dev, "shm_register rpc status: %d\n",
  244. ffa_args[TS_RPC_RETRIEVE_MEM_RPC_STATUS]);
  245. ffa_dev->ops->mem_ops->memory_reclaim(shm->sec_world_id, 0);
  246. return -EINVAL;
  247. }
  248. return 0;
  249. }
  250. static int tstee_shm_unregister(struct tee_context *ctx, struct tee_shm *shm)
  251. {
  252. struct tstee *tstee = tee_get_drvdata(ctx->teedev);
  253. struct ffa_device *ffa_dev = tstee->ffa_dev;
  254. struct ffa_send_direct_data ffa_data;
  255. u32 ffa_args[FFA_DIRECT_REQ_ARG_NUM] = {};
  256. int rc;
  257. ffa_args[TS_RPC_CTRL_REG] =
  258. TS_RPC_CTRL_PACK_IFACE_OPCODE(TS_RPC_MGMT_IFACE_ID,
  259. TS_RPC_OP_RELINQ_MEM);
  260. ffa_args[TS_RPC_RELINQ_MEM_HANDLE_LSW] =
  261. lower_32_bits(shm->sec_world_id);
  262. ffa_args[TS_RPC_RELINQ_MEM_HANDLE_MSW] =
  263. upper_32_bits(shm->sec_world_id);
  264. arg_list_to_ffa_data(ffa_args, &ffa_data);
  265. rc = ffa_dev->ops->msg_ops->sync_send_receive(ffa_dev, &ffa_data);
  266. if (rc)
  267. return rc;
  268. arg_list_from_ffa_data(&ffa_data, ffa_args);
  269. if (ffa_args[TS_RPC_RELINQ_MEM_RPC_STATUS] != TS_RPC_OK) {
  270. dev_err(&ffa_dev->dev, "shm_unregister rpc status: %d\n",
  271. ffa_args[TS_RPC_RELINQ_MEM_RPC_STATUS]);
  272. return -EINVAL;
  273. }
  274. rc = ffa_dev->ops->mem_ops->memory_reclaim(shm->sec_world_id, 0);
  275. return rc;
  276. }
  277. static const struct tee_driver_ops tstee_ops = {
  278. .get_version = tstee_get_version,
  279. .open = tstee_open,
  280. .release = tstee_release,
  281. .open_session = tstee_open_session,
  282. .close_session = tstee_close_session,
  283. .invoke_func = tstee_invoke_func,
  284. };
  285. static const struct tee_desc tstee_desc = {
  286. .name = "tstee-clnt",
  287. .ops = &tstee_ops,
  288. .owner = THIS_MODULE,
  289. };
  290. static int pool_op_alloc(struct tee_shm_pool *pool, struct tee_shm *shm,
  291. size_t size, size_t align)
  292. {
  293. return tee_dyn_shm_alloc_helper(shm, size, align, tstee_shm_register);
  294. }
  295. static void pool_op_free(struct tee_shm_pool *pool, struct tee_shm *shm)
  296. {
  297. tee_dyn_shm_free_helper(shm, tstee_shm_unregister);
  298. }
  299. static void pool_op_destroy_pool(struct tee_shm_pool *pool)
  300. {
  301. kfree(pool);
  302. }
  303. static const struct tee_shm_pool_ops pool_ops = {
  304. .alloc = pool_op_alloc,
  305. .free = pool_op_free,
  306. .destroy_pool = pool_op_destroy_pool,
  307. };
  308. static struct tee_shm_pool *tstee_create_shm_pool(void)
  309. {
  310. struct tee_shm_pool *pool = kzalloc_obj(*pool);
  311. if (!pool)
  312. return ERR_PTR(-ENOMEM);
  313. pool->ops = &pool_ops;
  314. return pool;
  315. }
  316. static bool tstee_check_rpc_compatible(struct ffa_device *ffa_dev)
  317. {
  318. struct ffa_send_direct_data ffa_data;
  319. u32 ffa_args[FFA_DIRECT_REQ_ARG_NUM] = {};
  320. ffa_args[TS_RPC_CTRL_REG] =
  321. TS_RPC_CTRL_PACK_IFACE_OPCODE(TS_RPC_MGMT_IFACE_ID,
  322. TS_RPC_OP_GET_VERSION);
  323. arg_list_to_ffa_data(ffa_args, &ffa_data);
  324. if (ffa_dev->ops->msg_ops->sync_send_receive(ffa_dev, &ffa_data))
  325. return false;
  326. arg_list_from_ffa_data(&ffa_data, ffa_args);
  327. return ffa_args[TS_RPC_GET_VERSION_RESP] == TS_RPC_PROTOCOL_VERSION;
  328. }
  329. static int tstee_probe(struct ffa_device *ffa_dev)
  330. {
  331. struct tstee *tstee;
  332. int rc;
  333. ffa_dev->ops->msg_ops->mode_32bit_set(ffa_dev);
  334. if (!tstee_check_rpc_compatible(ffa_dev))
  335. return -EINVAL;
  336. tstee = kzalloc_obj(*tstee);
  337. if (!tstee)
  338. return -ENOMEM;
  339. tstee->ffa_dev = ffa_dev;
  340. tstee->pool = tstee_create_shm_pool();
  341. if (IS_ERR(tstee->pool)) {
  342. rc = PTR_ERR(tstee->pool);
  343. tstee->pool = NULL;
  344. goto err_free_tstee;
  345. }
  346. tstee->teedev = tee_device_alloc(&tstee_desc, NULL, tstee->pool, tstee);
  347. if (IS_ERR(tstee->teedev)) {
  348. rc = PTR_ERR(tstee->teedev);
  349. tstee->teedev = NULL;
  350. goto err_free_pool;
  351. }
  352. rc = tee_device_register(tstee->teedev);
  353. if (rc)
  354. goto err_unreg_teedev;
  355. ffa_dev_set_drvdata(ffa_dev, tstee);
  356. return 0;
  357. err_unreg_teedev:
  358. tee_device_unregister(tstee->teedev);
  359. err_free_pool:
  360. tee_shm_pool_free(tstee->pool);
  361. err_free_tstee:
  362. kfree(tstee);
  363. return rc;
  364. }
  365. static void tstee_remove(struct ffa_device *ffa_dev)
  366. {
  367. struct tstee *tstee = ffa_dev->dev.driver_data;
  368. tee_device_unregister(tstee->teedev);
  369. tee_shm_pool_free(tstee->pool);
  370. kfree(tstee);
  371. }
  372. static const struct ffa_device_id tstee_device_ids[] = {
  373. /* TS RPC protocol UUID: bdcd76d7-825e-4751-963b-86d4f84943ac */
  374. { TS_RPC_UUID },
  375. {}
  376. };
  377. static struct ffa_driver tstee_driver = {
  378. .name = "arm_tstee",
  379. .probe = tstee_probe,
  380. .remove = tstee_remove,
  381. .id_table = tstee_device_ids,
  382. };
  383. module_ffa_driver(tstee_driver);
  384. MODULE_AUTHOR("Balint Dobszay <balint.dobszay@arm.com>");
  385. MODULE_DESCRIPTION("Arm Trusted Services TEE driver");
  386. MODULE_LICENSE("GPL");