diff --git a/core/arch/arm/include/kernel/pseudo_ta.h b/core/arch/arm/include/kernel/pseudo_ta.h index dde764e971c..5a7f4fcee0a 100644 --- a/core/arch/arm/include/kernel/pseudo_ta.h +++ b/core/arch/arm/include/kernel/pseudo_ta.h @@ -58,7 +58,8 @@ static inline struct pseudo_ta_ctx *to_pseudo_ta_ctx(struct tee_ta_ctx *ctx) return container_of(ctx, struct pseudo_ta_ctx, ctx); } -TEE_Result pseudo_ta_get_ctx(const TEE_UUID *uuid, struct tee_ta_ctx **ctx); +TEE_Result tee_ta_init_pseudo_ta_session(const TEE_UUID *uuid, + struct tee_ta_session *s); #endif /* KERNEL_PSEUDO_TA_H */ diff --git a/core/arch/arm/include/kernel/user_ta.h b/core/arch/arm/include/kernel/user_ta.h index 81ebbf46b6a..0eb2603108e 100644 --- a/core/arch/arm/include/kernel/user_ta.h +++ b/core/arch/arm/include/kernel/user_ta.h @@ -60,11 +60,13 @@ static inline struct user_ta_ctx *to_user_ta_ctx(struct tee_ta_ctx *ctx) struct user_ta_store_ops; #ifdef CFG_WITH_USER_TA -TEE_Result user_ta_get_ctx(const TEE_UUID *uuid, struct tee_ta_ctx **ctx); +TEE_Result tee_ta_init_user_ta_session(const TEE_UUID *uuid, + struct tee_ta_session *s); TEE_Result tee_ta_register_ta_store(struct user_ta_store_ops *ops); #else -static inline TEE_Result user_ta_get_ctx(const TEE_UUID *uuid __unused, - struct tee_ta_ctx **ctx __unused) +static inline TEE_Result tee_ta_init_user_ta_session( + const TEE_UUID *uuid __unused, + struct tee_ta_session *s __unused) { return TEE_ERROR_ITEM_NOT_FOUND; } diff --git a/core/arch/arm/kernel/pseudo_ta.c b/core/arch/arm/kernel/pseudo_ta.c index de9863657eb..3326a1a8a90 100644 --- a/core/arch/arm/kernel/pseudo_ta.c +++ b/core/arch/arm/kernel/pseudo_ta.c @@ -279,8 +279,12 @@ static TEE_Result verify_pseudo_tas_conformance(void) service_init(verify_pseudo_tas_conformance); -/* Initializes and returns a TA context based on the UUID of a pseudo TA. */ -TEE_Result pseudo_ta_get_ctx(const TEE_UUID *uuid, struct tee_ta_ctx **ctx_ret) +/*----------------------------------------------------------------------------- + * Initialises a session based on the UUID or ptr to the ta + * Returns ptr to the session (ta_session) and a TEE_Result + *---------------------------------------------------------------------------*/ +TEE_Result tee_ta_init_pseudo_ta_session(const TEE_UUID *uuid, + struct tee_ta_session *s) { struct pseudo_ta_ctx *stc = NULL; struct tee_ta_ctx *ctx; @@ -305,13 +309,13 @@ TEE_Result pseudo_ta_get_ctx(const TEE_UUID *uuid, struct tee_ta_ctx **ctx_ret) ctx = &stc->ctx; ctx->ref_count = 1; + s->ctx = ctx; ctx->flags = ta->flags; stc->pseudo_ta = ta; ctx->uuid = ta->uuid; ctx->ops = &pseudo_ta_ops; - tee_ta_register_ctx(ctx); + TAILQ_INSERT_TAIL(&tee_ctxes, ctx, link); - *ctx_ret = ctx; DMSG("%s : %pUl", stc->pseudo_ta->name, (void *)&ctx->uuid); return TEE_SUCCESS; diff --git a/core/arch/arm/kernel/user_ta.c b/core/arch/arm/kernel/user_ta.c index 3a15d240dce..636ae990a61 100644 --- a/core/arch/arm/kernel/user_ta.c +++ b/core/arch/arm/kernel/user_ta.c @@ -320,7 +320,7 @@ static TEE_Result ta_load(const TEE_UUID *uuid, utc->entry_func = ta_head->entry.ptr64; utc->ctx.ref_count = 1; condvar_init(&utc->ctx.busy_cv); - tee_ta_register_ctx(&utc->ctx); + TAILQ_INSERT_TAIL(&tee_ctxes, &utc->ctx, link); *ta_ctx = &utc->ctx; tee_mmu_set_ctx(NULL); @@ -626,7 +626,8 @@ TEE_Result tee_ta_register_ta_store(struct user_ta_store_ops *ops) return TEE_SUCCESS; } -TEE_Result user_ta_get_ctx(const TEE_UUID *uuid, struct tee_ta_ctx **ctx) +TEE_Result tee_ta_init_user_ta_session(const TEE_UUID *uuid, + struct tee_ta_session *s) { const struct user_ta_store_ops *store; TEE_Result res; @@ -634,11 +635,11 @@ TEE_Result user_ta_get_ctx(const TEE_UUID *uuid, struct tee_ta_ctx **ctx) SLIST_FOREACH(store, &uta_store_list, link) { DMSG("Lookup user TA %pUl (%s)", (void *)uuid, store->description); - res = ta_load(uuid, store, ctx); + res = ta_load(uuid, store, &s->ctx); if (res == TEE_ERROR_ITEM_NOT_FOUND) continue; if (res == TEE_SUCCESS) - (*ctx)->ops = &user_ta_ops; + s->ctx->ops = &user_ta_ops; else DMSG("res=0x%x", res); return res; diff --git a/core/include/kernel/tee_ta_manager.h b/core/include/kernel/tee_ta_manager.h index e7506f5b7a7..49b5956f668 100644 --- a/core/include/kernel/tee_ta_manager.h +++ b/core/include/kernel/tee_ta_manager.h @@ -129,7 +129,10 @@ struct tee_ta_session { #endif }; -void tee_ta_register_ctx(struct tee_ta_ctx *ctx); +/* Registered contexts */ +extern struct tee_ta_ctx_head tee_ctxes; + +extern struct mutex tee_ta_mutex; TEE_Result tee_ta_open_session(TEE_ErrorOrigin *err, struct tee_ta_session **sess, diff --git a/core/kernel/tee_ta_manager.c b/core/kernel/tee_ta_manager.c index 3f7937fdce1..134aad38eaf 100644 --- a/core/kernel/tee_ta_manager.c +++ b/core/kernel/tee_ta_manager.c @@ -55,8 +55,8 @@ #include /* This mutex protects the critical section in tee_ta_init_session */ -static struct mutex tee_ta_mutex = MUTEX_INITIALIZER; -static struct tee_ta_ctx_head tee_ctxes = TAILQ_HEAD_INITIALIZER(tee_ctxes); +struct mutex tee_ta_mutex = MUTEX_INITIALIZER; +struct tee_ta_ctx_head tee_ctxes = TAILQ_HEAD_INITIALIZER(tee_ctxes); #ifndef CFG_CONCURRENT_SINGLE_INSTANCE_TA static struct condvar tee_ta_cv = CONDVAR_INITIALIZER; @@ -460,11 +460,9 @@ TEE_Result tee_ta_close_session(struct tee_ta_session *csess, return TEE_SUCCESS; } -static TEE_Result get_ctx(struct tee_ta_ctx *ctx) +static TEE_Result tee_ta_init_session_with_context(struct tee_ta_ctx *ctx, + struct tee_ta_session *s) { - if (!ctx) - return TEE_ERROR_ITEM_NOT_FOUND; - /* * If TA isn't single instance it should be loaded as new * instance instead of doing anything with this instance. @@ -484,15 +482,10 @@ static TEE_Result get_ctx(struct tee_ta_ctx *ctx) DMSG("Re-open TA %pUl", (void *)&ctx->uuid); ctx->ref_count++; + s->ctx = ctx; return TEE_SUCCESS; } -void tee_ta_register_ctx(struct tee_ta_ctx *ctx) -{ - mutex_lock(&tee_ta_mutex); - TAILQ_INSERT_TAIL(&tee_ctxes, ctx, link); - mutex_unlock(&tee_ta_mutex); -} static TEE_Result tee_ta_init_session(TEE_ErrorOrigin *err, struct tee_ta_session_head *open_sessions, @@ -507,43 +500,48 @@ static TEE_Result tee_ta_init_session(TEE_ErrorOrigin *err, if (!s) return TEE_ERROR_OUT_OF_MEMORY; + s->cancel_mask = true; + condvar_init(&s->refc_cv); + condvar_init(&s->lock_cv); + s->lock_thread = THREAD_ID_INVALID; + s->ref_count = 1; + + + /* + * We take the global TA mutex here and hold it while doing + * RPC to load the TA. This big critical section should be broken + * down into smaller pieces. + */ + - /* Look for already loaded TA */ mutex_lock(&tee_ta_mutex); + TAILQ_INSERT_TAIL(open_sessions, s, link); + + /* Look for already loaded TA */ ctx = tee_ta_context_find(uuid); - res = get_ctx(ctx); - mutex_unlock(&tee_ta_mutex); - if (res != TEE_ERROR_ITEM_NOT_FOUND) - goto out; + if (ctx) { + res = tee_ta_init_session_with_context(ctx, s); + if (res == TEE_SUCCESS || res != TEE_ERROR_ITEM_NOT_FOUND) + goto out; + } /* Look for static TA */ - res = pseudo_ta_get_ctx(uuid, &ctx); - if (res != TEE_ERROR_ITEM_NOT_FOUND) + res = tee_ta_init_pseudo_ta_session(uuid, s); + if (res == TEE_SUCCESS || res != TEE_ERROR_ITEM_NOT_FOUND) goto out; /* Look for user TA */ - res = user_ta_get_ctx(uuid, &ctx); + res = tee_ta_init_user_ta_session(uuid, s); + out: - if (res) { + if (res == TEE_SUCCESS) { + *sess = s; + } else { + TAILQ_REMOVE(open_sessions, s, link); free(s); - return res; } - - /* - * We have a context, let's finish initialization of the session - */ - s->cancel_mask = true; - condvar_init(&s->refc_cv); - condvar_init(&s->lock_cv); - s->lock_thread = THREAD_ID_INVALID; - s->ref_count = 1; - s->ctx = ctx; - mutex_lock(&tee_ta_mutex); - TAILQ_INSERT_TAIL(open_sessions, s, link); mutex_unlock(&tee_ta_mutex); - *sess = s; - - return TEE_SUCCESS; + return res; } TEE_Result tee_ta_open_session(TEE_ErrorOrigin *err,