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>
This commit is contained in:
parent
9028b2463c
commit
c0ab6db39a
@ -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,
|
||||
|
@ -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);
|
||||
|
||||
if (!IS_ERR(shm))
|
||||
tee_shm_free(shm);
|
||||
|
||||
ctx->data = NULL;
|
||||
}
|
||||
|
||||
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);
|
||||
static void optee_release(struct tee_context *ctx)
|
||||
{
|
||||
optee_release_helper(ctx, optee_close_session_helper);
|
||||
}
|
||||
|
||||
static void optee_release_supp(struct tee_context *ctx)
|
||||
{
|
||||
struct optee *optee = tee_get_drvdata(ctx->teedev);
|
||||
|
||||
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,
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user