OSDN Git Service

Merge tag 'tee-amdtee-fix2-for-5.6' of https://git.linaro.org/people/jens.wiklander...
[tomoyo/tomoyo-test1.git] / drivers / tee / amdtee / core.c
index dbc238c..27b4cd7 100644 (file)
@@ -215,6 +215,19 @@ unlock:
        return rc;
 }
 
+static void destroy_session(struct kref *ref)
+{
+       struct amdtee_session *sess = container_of(ref, struct amdtee_session,
+                                                  refcount);
+
+       /* Unload the TA from TEE */
+       handle_unload_ta(sess->ta_handle);
+       mutex_lock(&session_list_mutex);
+       list_del(&sess->list_node);
+       mutex_unlock(&session_list_mutex);
+       kfree(sess);
+}
+
 int amdtee_open_session(struct tee_context *ctx,
                        struct tee_ioctl_open_session_arg *arg,
                        struct tee_param *param)
@@ -239,15 +252,13 @@ int amdtee_open_session(struct tee_context *ctx,
 
        /* Load the TA binary into TEE environment */
        handle_load_ta(ta, ta_size, arg);
-       if (arg->ret == TEEC_SUCCESS) {
-               mutex_lock(&session_list_mutex);
-               sess = alloc_session(ctxdata, arg->session);
-               mutex_unlock(&session_list_mutex);
-       }
-
        if (arg->ret != TEEC_SUCCESS)
                goto out;
 
+       mutex_lock(&session_list_mutex);
+       sess = alloc_session(ctxdata, arg->session);
+       mutex_unlock(&session_list_mutex);
+
        if (!sess) {
                rc = -ENOMEM;
                goto out;
@@ -262,40 +273,29 @@ int amdtee_open_session(struct tee_context *ctx,
 
        if (i >= TEE_NUM_SESSIONS) {
                pr_err("reached maximum session count %d\n", TEE_NUM_SESSIONS);
+               kref_put(&sess->refcount, destroy_session);
                rc = -ENOMEM;
                goto out;
        }
 
        /* Open session with loaded TA */
        handle_open_session(arg, &session_info, param);
-
-       if (arg->ret == TEEC_SUCCESS) {
-               sess->session_info[i] = session_info;
-               set_session_id(sess->ta_handle, i, &arg->session);
-       } else {
+       if (arg->ret != TEEC_SUCCESS) {
                pr_err("open_session failed %d\n", arg->ret);
                spin_lock(&sess->lock);
                clear_bit(i, sess->sess_mask);
                spin_unlock(&sess->lock);
+               kref_put(&sess->refcount, destroy_session);
+               goto out;
        }
+
+       sess->session_info[i] = session_info;
+       set_session_id(sess->ta_handle, i, &arg->session);
 out:
        free_pages((u64)ta, get_order(ta_size));
        return rc;
 }
 
-static void destroy_session(struct kref *ref)
-{
-       struct amdtee_session *sess = container_of(ref, struct amdtee_session,
-                                                  refcount);
-
-       /* Unload the TA from TEE */
-       handle_unload_ta(sess->ta_handle);
-       mutex_lock(&session_list_mutex);
-       list_del(&sess->list_node);
-       mutex_unlock(&session_list_mutex);
-       kfree(sess);
-}
-
 int amdtee_close_session(struct tee_context *ctx, u32 session)
 {
        struct amdtee_context_data *ctxdata = ctx->data;