supp.c 9.1 KB

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