| From 5a2565d002084a4c6b80329a4a23cb6c98c4f344 Mon Sep 17 00:00:00 2001 |
| From: Jens Wiklander <jens.wiklander@linaro.org> |
| Date: Thu, 25 Mar 2021 15:08:46 +0100 |
| Subject: [PATCH 09/40] optee: simplify optee_release() |
| |
| Simplifies optee_release() with a new helper function, |
| optee_close_session_helper() which has been factored out from |
| optee_close_session(). |
| |
| A separate optee_release_supp() is added for the supplicant device. |
| |
| Reviewed-by: Sumit Garg <sumit.garg@linaro.org> |
| Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org> |
| Upstream-Status: Pending [Not submitted to upstream yet] |
| Signed-off-by: Rupinderjit Singh <rupinderjit.singh@arm.com> |
| --- |
| drivers/tee/optee/call.c | 31 ++++++++++------- |
| drivers/tee/optee/core.c | 56 +++++++++++-------------------- |
| drivers/tee/optee/optee_private.h | 1 + |
| 3 files changed, 39 insertions(+), 49 deletions(-) |
| |
| diff --git a/drivers/tee/optee/call.c b/drivers/tee/optee/call.c |
| index 945f03da0223..103976df2062 100644 |
| --- a/drivers/tee/optee/call.c |
| +++ b/drivers/tee/optee/call.c |
| @@ -288,12 +288,28 @@ int optee_open_session(struct tee_context *ctx, |
| return rc; |
| } |
| |
| -int optee_close_session(struct tee_context *ctx, u32 session) |
| +int optee_close_session_helper(struct tee_context *ctx, u32 session) |
| { |
| - struct optee_context_data *ctxdata = ctx->data; |
| struct tee_shm *shm; |
| struct optee_msg_arg *msg_arg; |
| phys_addr_t msg_parg; |
| + |
| + shm = get_msg_arg(ctx, 0, &msg_arg, &msg_parg); |
| + if (IS_ERR(shm)) |
| + return PTR_ERR(shm); |
| + |
| + msg_arg->cmd = OPTEE_MSG_CMD_CLOSE_SESSION; |
| + msg_arg->session = session; |
| + optee_do_call_with_arg(ctx, msg_parg); |
| + |
| + tee_shm_free(shm); |
| + |
| + return 0; |
| +} |
| + |
| +int optee_close_session(struct tee_context *ctx, u32 session) |
| +{ |
| + struct optee_context_data *ctxdata = ctx->data; |
| struct optee_session *sess; |
| |
| /* Check that the session is valid and remove it from the list */ |
| @@ -306,16 +322,7 @@ int optee_close_session(struct tee_context *ctx, u32 session) |
| return -EINVAL; |
| kfree(sess); |
| |
| - shm = get_msg_arg(ctx, 0, &msg_arg, &msg_parg); |
| - if (IS_ERR(shm)) |
| - return PTR_ERR(shm); |
| - |
| - msg_arg->cmd = OPTEE_MSG_CMD_CLOSE_SESSION; |
| - msg_arg->session = session; |
| - optee_do_call_with_arg(ctx, msg_parg); |
| - |
| - tee_shm_free(shm); |
| - return 0; |
| + return optee_close_session_helper(ctx, session); |
| } |
| |
| int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg, |
| diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c |
| index 5363ebebfc35..79f67a79e7b7 100644 |
| --- a/drivers/tee/optee/core.c |
| +++ b/drivers/tee/optee/core.c |
| @@ -264,60 +264,42 @@ static int optee_open(struct tee_context *ctx) |
| return 0; |
| } |
| |
| -static void optee_release(struct tee_context *ctx) |
| +static void optee_release_helper(struct tee_context *ctx, |
| + int (*close_session)(struct tee_context *ctx, |
| + u32 session)) |
| { |
| struct optee_context_data *ctxdata = ctx->data; |
| - struct tee_device *teedev = ctx->teedev; |
| - struct optee *optee = tee_get_drvdata(teedev); |
| - struct tee_shm *shm; |
| - struct optee_msg_arg *arg = NULL; |
| - phys_addr_t parg; |
| struct optee_session *sess; |
| struct optee_session *sess_tmp; |
| |
| if (!ctxdata) |
| return; |
| |
| - shm = tee_shm_alloc(ctx, sizeof(struct optee_msg_arg), |
| - TEE_SHM_MAPPED | TEE_SHM_PRIV); |
| - if (!IS_ERR(shm)) { |
| - arg = tee_shm_get_va(shm, 0); |
| - /* |
| - * If va2pa fails for some reason, we can't call into |
| - * secure world, only free the memory. Secure OS will leak |
| - * sessions and finally refuse more sessions, but we will |
| - * at least let normal world reclaim its memory. |
| - */ |
| - if (!IS_ERR(arg)) |
| - if (tee_shm_va2pa(shm, arg, &parg)) |
| - arg = NULL; /* prevent usage of parg below */ |
| - } |
| - |
| list_for_each_entry_safe(sess, sess_tmp, &ctxdata->sess_list, |
| list_node) { |
| list_del(&sess->list_node); |
| - if (!IS_ERR_OR_NULL(arg)) { |
| - memset(arg, 0, sizeof(*arg)); |
| - arg->cmd = OPTEE_MSG_CMD_CLOSE_SESSION; |
| - arg->session = sess->session_id; |
| - optee_do_call_with_arg(ctx, parg); |
| - } |
| + close_session(ctx, sess->session_id); |
| kfree(sess); |
| } |
| kfree(ctxdata); |
| + ctx->data = NULL; |
| +} |
| |
| - if (!IS_ERR(shm)) |
| - tee_shm_free(shm); |
| +static void optee_release(struct tee_context *ctx) |
| +{ |
| + optee_release_helper(ctx, optee_close_session_helper); |
| +} |
| |
| - ctx->data = NULL; |
| +static void optee_release_supp(struct tee_context *ctx) |
| +{ |
| + struct optee *optee = tee_get_drvdata(ctx->teedev); |
| |
| - if (teedev == optee->supp_teedev) { |
| - if (optee->scan_bus_wq) { |
| - destroy_workqueue(optee->scan_bus_wq); |
| - optee->scan_bus_wq = NULL; |
| - } |
| - optee_supp_release(&optee->supp); |
| + optee_release_helper(ctx, optee_close_session_helper); |
| + if (optee->scan_bus_wq) { |
| + destroy_workqueue(optee->scan_bus_wq); |
| + optee->scan_bus_wq = NULL; |
| } |
| + optee_supp_release(&optee->supp); |
| } |
| |
| static const struct tee_driver_ops optee_ops = { |
| @@ -341,7 +323,7 @@ static const struct tee_desc optee_desc = { |
| static const struct tee_driver_ops optee_supp_ops = { |
| .get_version = optee_get_version, |
| .open = optee_open, |
| - .release = optee_release, |
| + .release = optee_release_supp, |
| .supp_recv = optee_supp_recv, |
| .supp_send = optee_supp_send, |
| .shm_register = optee_shm_register_supp, |
| diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h |
| index f6bb4a763ba9..a55793f9f6eb 100644 |
| --- a/drivers/tee/optee/optee_private.h |
| +++ b/drivers/tee/optee/optee_private.h |
| @@ -152,6 +152,7 @@ u32 optee_do_call_with_arg(struct tee_context *ctx, phys_addr_t parg); |
| int optee_open_session(struct tee_context *ctx, |
| struct tee_ioctl_open_session_arg *arg, |
| struct tee_param *param); |
| +int optee_close_session_helper(struct tee_context *ctx, u32 session); |
| int optee_close_session(struct tee_context *ctx, u32 session); |
| int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg, |
| struct tee_param *param); |
| -- |
| 2.34.1 |
| |