supp.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2015, Linaro Limited
  4. */
  5. #include <linux/device.h>
  6. #include <linux/slab.h>
  7. #include <linux/uaccess.h>
  8. #include "optee_private.h"
  9. struct optee_supp_req {
  10. struct list_head link;
  11. bool in_queue;
  12. u32 func;
  13. u32 ret;
  14. size_t num_params;
  15. struct tee_param *param;
  16. struct completion c;
  17. };
  18. void optee_supp_init(struct optee_supp *supp)
  19. {
  20. memset(supp, 0, sizeof(*supp));
  21. mutex_init(&supp->mutex);
  22. init_completion(&supp->reqs_c);
  23. idr_init(&supp->idr);
  24. INIT_LIST_HEAD(&supp->reqs);
  25. supp->req_id = -1;
  26. }
  27. void optee_supp_uninit(struct optee_supp *supp)
  28. {
  29. mutex_destroy(&supp->mutex);
  30. idr_destroy(&supp->idr);
  31. }
  32. void optee_supp_release(struct optee_supp *supp)
  33. {
  34. int id;
  35. struct optee_supp_req *req;
  36. struct optee_supp_req *req_tmp;
  37. mutex_lock(&supp->mutex);
  38. /* Abort all request retrieved by supplicant */
  39. idr_for_each_entry(&supp->idr, req, id) {
  40. idr_remove(&supp->idr, id);
  41. req->ret = TEEC_ERROR_COMMUNICATION;
  42. complete(&req->c);
  43. }
  44. /* Abort all queued requests */
  45. list_for_each_entry_safe(req, req_tmp, &supp->reqs, link) {
  46. list_del(&req->link);
  47. req->in_queue = false;
  48. req->ret = TEEC_ERROR_COMMUNICATION;
  49. complete(&req->c);
  50. }
  51. supp->ctx = NULL;
  52. supp->req_id = -1;
  53. mutex_unlock(&supp->mutex);
  54. }
  55. /**
  56. * optee_supp_thrd_req() - request service from supplicant
  57. * @ctx: context doing the request
  58. * @func: function requested
  59. * @num_params: number of elements in @param array
  60. * @param: parameters for function
  61. *
  62. * Returns result of operation to be passed to secure world
  63. */
  64. u32 optee_supp_thrd_req(struct tee_context *ctx, u32 func, size_t num_params,
  65. struct tee_param *param)
  66. {
  67. struct optee *optee = tee_get_drvdata(ctx->teedev);
  68. struct optee_supp *supp = &optee->supp;
  69. struct optee_supp_req *req;
  70. u32 ret;
  71. /*
  72. * Return in case there is no supplicant available and
  73. * non-blocking request.
  74. */
  75. if (!supp->ctx && ctx->supp_nowait)
  76. return TEEC_ERROR_COMMUNICATION;
  77. req = kzalloc_obj(*req);
  78. if (!req)
  79. return TEEC_ERROR_OUT_OF_MEMORY;
  80. init_completion(&req->c);
  81. req->func = func;
  82. req->num_params = num_params;
  83. req->param = param;
  84. /* Insert the request in the request list */
  85. mutex_lock(&supp->mutex);
  86. list_add_tail(&req->link, &supp->reqs);
  87. req->in_queue = true;
  88. mutex_unlock(&supp->mutex);
  89. /* Tell an eventual waiter there's a new request */
  90. complete(&supp->reqs_c);
  91. /*
  92. * Wait for supplicant to process and return result, once we've
  93. * returned from wait_for_completion(&req->c) successfully we have
  94. * exclusive access again. Allow the wait to be killable such that
  95. * the wait doesn't turn into an indefinite state if the supplicant
  96. * gets hung for some reason.
  97. */
  98. if (wait_for_completion_killable(&req->c)) {
  99. mutex_lock(&supp->mutex);
  100. if (req->in_queue) {
  101. list_del(&req->link);
  102. req->in_queue = false;
  103. }
  104. mutex_unlock(&supp->mutex);
  105. req->ret = TEEC_ERROR_COMMUNICATION;
  106. }
  107. ret = req->ret;
  108. kfree(req);
  109. return ret;
  110. }
  111. static struct optee_supp_req *supp_pop_entry(struct optee_supp *supp,
  112. int num_params, int *id)
  113. {
  114. struct optee_supp_req *req;
  115. if (supp->req_id != -1) {
  116. /*
  117. * Supplicant should not mix synchronous and asnynchronous
  118. * requests.
  119. */
  120. return ERR_PTR(-EINVAL);
  121. }
  122. if (list_empty(&supp->reqs))
  123. return NULL;
  124. req = list_first_entry(&supp->reqs, struct optee_supp_req, link);
  125. if (num_params < req->num_params) {
  126. /* Not enough room for parameters */
  127. return ERR_PTR(-EINVAL);
  128. }
  129. *id = idr_alloc(&supp->idr, req, 1, 0, GFP_KERNEL);
  130. if (*id < 0)
  131. return ERR_PTR(-ENOMEM);
  132. list_del(&req->link);
  133. req->in_queue = false;
  134. return req;
  135. }
  136. static int supp_check_recv_params(size_t num_params, struct tee_param *params,
  137. size_t *num_meta)
  138. {
  139. size_t n;
  140. if (!num_params)
  141. return -EINVAL;
  142. /*
  143. * If there's memrefs we need to decrease those as they where
  144. * increased earlier and we'll even refuse to accept any below.
  145. */
  146. for (n = 0; n < num_params; n++)
  147. if (tee_param_is_memref(params + n) && params[n].u.memref.shm)
  148. tee_shm_put(params[n].u.memref.shm);
  149. /*
  150. * We only expect parameters as TEE_IOCTL_PARAM_ATTR_TYPE_NONE with
  151. * or without the TEE_IOCTL_PARAM_ATTR_META bit set.
  152. */
  153. for (n = 0; n < num_params; n++)
  154. if (params[n].attr &&
  155. params[n].attr != TEE_IOCTL_PARAM_ATTR_META)
  156. return -EINVAL;
  157. /* At most we'll need one meta parameter so no need to check for more */
  158. if (params->attr == TEE_IOCTL_PARAM_ATTR_META)
  159. *num_meta = 1;
  160. else
  161. *num_meta = 0;
  162. return 0;
  163. }
  164. /**
  165. * optee_supp_recv() - receive request for supplicant
  166. * @ctx: context receiving the request
  167. * @func: requested function in supplicant
  168. * @num_params: number of elements allocated in @param, updated with number
  169. * used elements
  170. * @param: space for parameters for @func
  171. *
  172. * Returns 0 on success or <0 on failure
  173. */
  174. int optee_supp_recv(struct tee_context *ctx, u32 *func, u32 *num_params,
  175. struct tee_param *param)
  176. {
  177. struct tee_device *teedev = ctx->teedev;
  178. struct optee *optee = tee_get_drvdata(teedev);
  179. struct optee_supp *supp = &optee->supp;
  180. struct optee_supp_req *req = NULL;
  181. int id;
  182. size_t num_meta;
  183. int rc;
  184. rc = supp_check_recv_params(*num_params, param, &num_meta);
  185. if (rc)
  186. return rc;
  187. while (true) {
  188. mutex_lock(&supp->mutex);
  189. req = supp_pop_entry(supp, *num_params - num_meta, &id);
  190. mutex_unlock(&supp->mutex);
  191. if (req) {
  192. if (IS_ERR(req))
  193. return PTR_ERR(req);
  194. break;
  195. }
  196. /*
  197. * If we didn't get a request we'll block in
  198. * wait_for_completion() to avoid needless spinning.
  199. *
  200. * This is where supplicant will be hanging most of
  201. * the time, let's make this interruptable so we
  202. * can easily restart supplicant if needed.
  203. */
  204. if (wait_for_completion_interruptible(&supp->reqs_c))
  205. return -ERESTARTSYS;
  206. }
  207. if (num_meta) {
  208. /*
  209. * tee-supplicant support meta parameters -> requsts can be
  210. * processed asynchronously.
  211. */
  212. param->attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT |
  213. TEE_IOCTL_PARAM_ATTR_META;
  214. param->u.value.a = id;
  215. param->u.value.b = 0;
  216. param->u.value.c = 0;
  217. } else {
  218. mutex_lock(&supp->mutex);
  219. supp->req_id = id;
  220. mutex_unlock(&supp->mutex);
  221. }
  222. *func = req->func;
  223. *num_params = req->num_params + num_meta;
  224. memcpy(param + num_meta, req->param,
  225. sizeof(struct tee_param) * req->num_params);
  226. return 0;
  227. }
  228. static struct optee_supp_req *supp_pop_req(struct optee_supp *supp,
  229. size_t num_params,
  230. struct tee_param *param,
  231. size_t *num_meta)
  232. {
  233. struct optee_supp_req *req;
  234. int id;
  235. size_t nm;
  236. const u32 attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT |
  237. TEE_IOCTL_PARAM_ATTR_META;
  238. if (!num_params)
  239. return ERR_PTR(-EINVAL);
  240. if (supp->req_id == -1) {
  241. if (param->attr != attr)
  242. return ERR_PTR(-EINVAL);
  243. id = param->u.value.a;
  244. nm = 1;
  245. } else {
  246. id = supp->req_id;
  247. nm = 0;
  248. }
  249. req = idr_find(&supp->idr, id);
  250. if (!req)
  251. return ERR_PTR(-ENOENT);
  252. if ((num_params - nm) != req->num_params)
  253. return ERR_PTR(-EINVAL);
  254. idr_remove(&supp->idr, id);
  255. supp->req_id = -1;
  256. *num_meta = nm;
  257. return req;
  258. }
  259. /**
  260. * optee_supp_send() - send result of request from supplicant
  261. * @ctx: context sending result
  262. * @ret: return value of request
  263. * @num_params: number of parameters returned
  264. * @param: returned parameters
  265. *
  266. * Returns 0 on success or <0 on failure.
  267. */
  268. int optee_supp_send(struct tee_context *ctx, u32 ret, u32 num_params,
  269. struct tee_param *param)
  270. {
  271. struct tee_device *teedev = ctx->teedev;
  272. struct optee *optee = tee_get_drvdata(teedev);
  273. struct optee_supp *supp = &optee->supp;
  274. struct optee_supp_req *req;
  275. size_t n;
  276. size_t num_meta;
  277. mutex_lock(&supp->mutex);
  278. req = supp_pop_req(supp, num_params, param, &num_meta);
  279. mutex_unlock(&supp->mutex);
  280. if (IS_ERR(req)) {
  281. /* Something is wrong, let supplicant restart. */
  282. return PTR_ERR(req);
  283. }
  284. /* Update out and in/out parameters */
  285. for (n = 0; n < req->num_params; n++) {
  286. struct tee_param *p = req->param + n;
  287. switch (p->attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) {
  288. case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT:
  289. case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
  290. p->u.value.a = param[n + num_meta].u.value.a;
  291. p->u.value.b = param[n + num_meta].u.value.b;
  292. p->u.value.c = param[n + num_meta].u.value.c;
  293. break;
  294. case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
  295. case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
  296. p->u.memref.size = param[n + num_meta].u.memref.size;
  297. break;
  298. default:
  299. break;
  300. }
  301. }
  302. req->ret = ret;
  303. /* Let the requesting thread continue */
  304. complete(&req->c);
  305. return 0;
  306. }