diff --git a/core/tee_context.c b/core/tee_context.c index b86c61a..9c3bce6 100644 --- a/core/tee_context.c +++ b/core/tee_context.c @@ -173,10 +173,8 @@ static void _tee_context_do_release(struct kref *kref) dev_dbg(_DEV(tee), "%s: > ctx=%p\n", __func__, ctx); - mutex_lock(&tee->lock); tee_dec_stats(&tee->stats[TEE_STATS_CONTEXT_IDX]); list_del(&ctx->entry); - mutex_unlock(&tee->lock); devm_kfree(_DEV(tee), ctx); tee_put(tee); @@ -202,10 +200,8 @@ static int is_in_list(struct tee *tee, struct list_head *entry) { int present = 1; - mutex_lock(&tee->lock); if ((entry->next == LIST_POISON1) && (entry->prev == LIST_POISON2)) present = 0; - mutex_unlock(&tee->lock); return present; } @@ -245,7 +241,9 @@ void tee_context_destroy(struct tee_context *ctx) dev_dbg(_DEV(tee), "%s: ctx=%p\n", __func__, ctx); + mutex_lock(&tee->lock); tee_context_put(ctx); + mutex_unlock(&tee->lock); } int tee_context_copy_from_client(const struct tee_context *ctx, diff --git a/core/tee_session.c b/core/tee_session.c index e72d87e..d68bd69 100644 --- a/core/tee_session.c +++ b/core/tee_session.c @@ -388,11 +388,11 @@ int tee_session_close_and_destroy(struct tee_session *sess) mutex_lock(&sess->ctx->tee->lock); tee_dec_stats(&tee->stats[TEE_STATS_SESSION_IDX]); list_del(&sess->entry); - mutex_unlock(&sess->ctx->tee->lock); devm_kfree(_DEV(tee), sess); tee_context_put(ctx); tee_put(tee); + mutex_unlock(&sess->ctx->tee->lock); dev_dbg(_DEV(tee), "%s: <\n", __func__); return ret; @@ -426,6 +426,7 @@ struct tee_session *tee_session_create_and_open(struct tee_context *ctx, sess->ctx = ctx; ret = tee_session_open_be(sess, cmd_io); + mutex_lock(&tee->lock); if (ret || !sess->sessid || cmd_io->err) { dev_err(_DEV(tee), "%s: ERROR ret=%d (err=0x%08x, org=%d, sessid=0x%08x)\n", __func__, ret, cmd_io->err, @@ -433,13 +434,13 @@ struct tee_session *tee_session_create_and_open(struct tee_context *ctx, tee_put(tee); tee_context_put(ctx); devm_kfree(_DEV(tee), sess); + mutex_unlock(&tee->lock); if (ret) return ERR_PTR(ret); else return NULL; } - mutex_lock(&tee->lock); tee_inc_stats(&tee->stats[TEE_STATS_SESSION_IDX]); list_add_tail(&sess->entry, &ctx->list_sess); mutex_unlock(&tee->lock); diff --git a/core/tee_shm.c b/core/tee_shm.c index 1744463..e310316 100644 --- a/core/tee_shm.c +++ b/core/tee_shm.c @@ -43,6 +43,7 @@ struct tee_shm *tee_shm_alloc_from_rpc(struct tee *tee, size_t size) INMSG(); + mutex_lock(&tee->lock); shm = tee_shm_alloc(tee, size, TEE_SHM_TEMP | TEE_SHM_FROM_RPC); if (IS_ERR_OR_NULL(shm)) { dev_err(_DEV(tee), "%s: buffer allocation failed (%ld)\n", @@ -50,13 +51,13 @@ struct tee_shm *tee_shm_alloc_from_rpc(struct tee *tee, size_t size) goto out; } - mutex_lock(&tee->lock); tee_inc_stats(&tee->stats[TEE_STATS_SHM_IDX]); list_add_tail(&shm->entry, &tee->list_rpc_shm); - mutex_unlock(&tee->lock); + shm->ctx = NULL; out: + mutex_unlock(&tee->lock); OUTMSGX(shm); return shm; } @@ -66,14 +67,14 @@ void tee_shm_free_from_rpc(struct tee_shm *shm) if (shm == NULL) return; + mutex_lock(&shm->tee->lock); if (shm->ctx == NULL) { - mutex_lock(&shm->tee->lock); tee_dec_stats(&shm->tee->stats[TEE_STATS_SHM_IDX]); list_del(&shm->entry); - mutex_unlock(&shm->tee->lock); } tee_shm_free(shm); + mutex_unlock(&shm->tee->lock); } struct tee_shm *tee_shm_alloc(struct tee *tee, size_t size, uint32_t flags) @@ -398,11 +399,13 @@ int tee_shm_alloc_io(struct tee_context *ctx, struct tee_shm_io *shm_io) if (ctx->usr_client) shm_io->fd_shm = 0; + mutex_lock(&tee->lock); shm = tee_shm_alloc(tee, shm_io->size, shm_io->flags); if (IS_ERR_OR_NULL(shm)) { dev_err(_DEV(tee), "%s: buffer allocation failed (%ld)\n", __func__, PTR_ERR(shm)); - return PTR_ERR(shm); + ret = PTR_ERR(shm); + goto out; } if (ctx->usr_client) { @@ -422,11 +425,10 @@ int tee_shm_alloc_io(struct tee_context *ctx, struct tee_shm_io *shm_io) BUG_ON(ret); /* tee_core_get must not issue */ tee_context_get(ctx); - mutex_lock(&tee->lock); tee_inc_stats(&tee->stats[TEE_STATS_SHM_IDX]); list_add_tail(&shm->entry, &ctx->list_shm); - mutex_unlock(&tee->lock); out: + mutex_unlock(&tee->lock); OUTMSG(ret); return ret; } @@ -440,13 +442,13 @@ void tee_shm_free_io(struct tee_shm *shm) mutex_lock(&ctx->tee->lock); tee_dec_stats(&tee->stats[TEE_STATS_SHM_IDX]); list_del(&shm->entry); - mutex_unlock(&ctx->tee->lock); tee_shm_free(shm); tee_put(ctx->tee); tee_context_put(ctx); if (dev) put_device(dev); + mutex_unlock(&ctx->tee->lock); } /* Buffer allocated by rpc from fw and to be accessed by the user @@ -462,6 +464,7 @@ int tee_shm_fd_for_rpc(struct tee_context *ctx, struct tee_shm_io *shm_io) shm_io->fd_shm = 0; + mutex_lock(&tee->lock); if (!list_empty(&tee->list_rpc_shm)) { list_for_each(pshm, &tee->list_rpc_shm) { shm = list_entry(pshm, struct tee_shm, entry); @@ -482,9 +485,7 @@ int tee_shm_fd_for_rpc(struct tee_context *ctx, struct tee_shm_io *shm_io) } shm->ctx = ctx; - mutex_lock(&tee->lock); list_move(&shm->entry, &ctx->list_shm); - mutex_unlock(&tee->lock); shm->dev = get_device(_DEV(tee)); ret = tee_get(tee); @@ -493,6 +494,7 @@ int tee_shm_fd_for_rpc(struct tee_context *ctx, struct tee_shm_io *shm_io) BUG_ON(!tee->ops->shm_inc_ref(shm)); out: + mutex_unlock(&tee->lock); OUTMSG(ret); return ret; } @@ -719,10 +721,12 @@ struct tee_shm *tee_shm_get(struct tee_context *ctx, TEEC_SharedMemory *c_shm, dev_dbg(_DEV(tee), "%s: > fd=%d flags=%08x\n", __func__, c_shm->d.fd, c_shm->flags); + mutex_lock(&tee->lock); shm = kzalloc(sizeof(*shm), GFP_KERNEL); if (IS_ERR_OR_NULL(shm)) { dev_err(_DEV(tee), "can't alloc tee_shm\n"); - return ERR_PTR(-ENOMEM); + ret = -ENOMEM; + goto err; } shm->ctx = ctx; @@ -770,11 +774,13 @@ struct tee_shm *tee_shm_get(struct tee_context *ctx, TEEC_SharedMemory *c_shm, #endif } + mutex_unlock(&tee->lock); OUTMSGX(shm); return shm; err: kfree(shm); + mutex_unlock(&tee->lock); OUTMSGX(ERR_PTR(ret)); return ERR_PTR(ret); } @@ -789,6 +795,7 @@ void tee_shm_put(struct tee_context *ctx, struct tee_shm *shm) BUG_ON(!shm); BUG_ON(!(shm->flags & TEE_SHM_MEMREF)); + mutex_lock(&tee->lock); if (shm->flags & TEEC_MEM_DMABUF) { struct tee_shm_dma_buf *sdb; struct dma_buf *dma_buf; @@ -807,6 +814,7 @@ void tee_shm_put(struct tee_context *ctx, struct tee_shm *shm) } kfree(shm); + mutex_unlock(&tee->lock); OUTMSG(0); }