optee: simplify optee_release()
authorJens Wiklander <jens.wiklander@linaro.org>
Thu, 25 Mar 2021 14:08:46 +0000 (15:08 +0100)
committerJens Wiklander <jens.wiklander@linaro.org>
Fri, 15 Oct 2021 09:55:41 +0000 (11:55 +0200)
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>
drivers/tee/optee/call.c
drivers/tee/optee/core.c
drivers/tee/optee/optee_private.h

index 945f03d..103976d 100644 (file)
@@ -288,12 +288,28 @@ out:
        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,
index 5363ebe..79f67a7 100644 (file)
@@ -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,
index f6bb4a7..a55793f 100644 (file)
@@ -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);