Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC] Provision TEE threads for system invocation (take2) #109

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions drivers/firmware/arm_scmi/optee.c
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,10 @@ static int scmi_optee_chan_setup(struct scmi_chan_info *cinfo, struct device *de
if (ret)
goto err_free_shm;

ret = tee_client_system_session(scmi_optee_private->tee_ctx, channel->tee_session);
if (ret)
dev_warn(dev, "Could not switch to system session, do best effort\n");

ret = get_channel(channel);
if (ret)
goto err_close_sess;
Expand Down
28 changes: 16 additions & 12 deletions drivers/tee/optee/call.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,8 @@ void optee_cq_wait_final(struct optee_call_queue *cq,
}

/* Requires the filpstate mutex to be held */
static struct optee_session *find_session(struct optee_context_data *ctxdata,
u32 session_id)
struct optee_session *optee_find_session(struct optee_context_data *ctxdata,
u32 session_id)
{
struct optee_session *sess;

Expand Down Expand Up @@ -328,7 +328,7 @@ int optee_open_session(struct tee_context *ctx,
goto out;
}

if (optee->ops->do_call_with_arg(ctx, shm, offs)) {
if (optee->ops->do_call_with_arg(ctx, shm, offs, false)) {
msg_arg->ret = TEEC_ERROR_COMMUNICATION;
msg_arg->ret_origin = TEEC_ORIGIN_COMMS;
}
Expand Down Expand Up @@ -360,7 +360,8 @@ int optee_open_session(struct tee_context *ctx,
return rc;
}

int optee_close_session_helper(struct tee_context *ctx, u32 session)
int optee_close_session_helper(struct tee_context *ctx,
struct optee_session *sess)
{
struct optee *optee = tee_get_drvdata(ctx->teedev);
struct optee_shm_arg_entry *entry;
Expand All @@ -373,8 +374,8 @@ int optee_close_session_helper(struct tee_context *ctx, u32 session)
return PTR_ERR(msg_arg);

msg_arg->cmd = OPTEE_MSG_CMD_CLOSE_SESSION;
msg_arg->session = session;
optee->ops->do_call_with_arg(ctx, shm, offs);
msg_arg->session = sess->session_id;
optee->ops->do_call_with_arg(ctx, shm, offs, sess->system);

optee_free_msg_arg(ctx, entry, offs);

Expand All @@ -385,18 +386,21 @@ int optee_close_session(struct tee_context *ctx, u32 session)
{
struct optee_context_data *ctxdata = ctx->data;
struct optee_session *sess;
int rc;

/* Check that the session is valid and remove it from the list */
mutex_lock(&ctxdata->mutex);
sess = find_session(ctxdata, session);
sess = optee_find_session(ctxdata, session);
if (sess)
list_del(&sess->list_node);
mutex_unlock(&ctxdata->mutex);
if (!sess)
return -EINVAL;

rc = optee_close_session_helper(ctx, sess);
kfree(sess);

return optee_close_session_helper(ctx, session);
return rc;
}

int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
Expand All @@ -413,7 +417,7 @@ int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,

/* Check that the session is valid */
mutex_lock(&ctxdata->mutex);
sess = find_session(ctxdata, arg->session);
sess = optee_find_session(ctxdata, arg->session);
mutex_unlock(&ctxdata->mutex);
if (!sess)
return -EINVAL;
Expand All @@ -432,7 +436,7 @@ int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
if (rc)
goto out;

if (optee->ops->do_call_with_arg(ctx, shm, offs)) {
if (optee->ops->do_call_with_arg(ctx, shm, offs, sess->system)) {
msg_arg->ret = TEEC_ERROR_COMMUNICATION;
msg_arg->ret_origin = TEEC_ORIGIN_COMMS;
}
Expand Down Expand Up @@ -462,7 +466,7 @@ int optee_cancel_req(struct tee_context *ctx, u32 cancel_id, u32 session)

/* Check that the session is valid */
mutex_lock(&ctxdata->mutex);
sess = find_session(ctxdata, session);
sess = optee_find_session(ctxdata, session);
mutex_unlock(&ctxdata->mutex);
if (!sess)
return -EINVAL;
Expand All @@ -474,7 +478,7 @@ int optee_cancel_req(struct tee_context *ctx, u32 cancel_id, u32 session)
msg_arg->cmd = OPTEE_MSG_CMD_CANCEL;
msg_arg->session = session;
msg_arg->cancel_id = cancel_id;
optee->ops->do_call_with_arg(ctx, shm, offs);
optee->ops->do_call_with_arg(ctx, shm, offs, false);

optee_free_msg_arg(ctx, entry, offs);
return 0;
Expand Down
4 changes: 2 additions & 2 deletions drivers/tee/optee/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ int optee_open(struct tee_context *ctx, bool cap_memref_null)

static void optee_release_helper(struct tee_context *ctx,
int (*close_session)(struct tee_context *ctx,
u32 session))
struct optee_session *s))
{
struct optee_context_data *ctxdata = ctx->data;
struct optee_session *sess;
Expand All @@ -141,7 +141,7 @@ static void optee_release_helper(struct tee_context *ctx,
list_for_each_entry_safe(sess, sess_tmp, &ctxdata->sess_list,
list_node) {
list_del(&sess->list_node);
close_session(ctx, sess->session_id);
close_session(ctx, sess);
kfree(sess);
}
kfree(ctxdata);
Expand Down
3 changes: 2 additions & 1 deletion drivers/tee/optee/ffa_abi.c
Original file line number Diff line number Diff line change
Expand Up @@ -612,7 +612,8 @@ static int optee_ffa_yielding_call(struct tee_context *ctx,
*/

static int optee_ffa_do_call_with_arg(struct tee_context *ctx,
struct tee_shm *shm, u_int offs)
struct tee_shm *shm, u_int offs,
bool system_call)
{
struct ffa_send_direct_data data = {
.data0 = OPTEE_FFA_YIELDING_CALL_WITH_ARG,
Expand Down
22 changes: 20 additions & 2 deletions drivers/tee/optee/optee_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <linux/arm-smccc.h>
#include <linux/rhashtable.h>
#include <linux/semaphore.h>
#include <linux/spinlock.h>
#include <linux/tee_drv.h>
#include <linux/types.h>
#include "optee_msg.h"
Expand Down Expand Up @@ -130,7 +131,8 @@ struct optee;
*/
struct optee_ops {
int (*do_call_with_arg)(struct tee_context *ctx,
struct tee_shm *shm_arg, u_int offs);
struct tee_shm *shm_arg, u_int offs,
bool system_call);
int (*to_msg_param)(struct optee *optee,
struct optee_msg_param *msg_params,
size_t num_params, const struct tee_param *params);
Expand All @@ -139,6 +141,15 @@ struct optee_ops {
const struct optee_msg_param *msg_params);
};

struct optee_thread {
spinlock_t lock;
size_t thread_cnt;
size_t thread_free_cnt;
size_t system_thread_cnt;
size_t system_thread_free_cnt;
bool best_effort;
};

/**
* struct optee - main service struct
* @supp_teedev: supplicant device
Expand Down Expand Up @@ -175,11 +186,13 @@ struct optee {
bool scan_bus_done;
struct workqueue_struct *scan_bus_wq;
struct work_struct scan_bus_work;
struct optee_thread thread;
};

struct optee_session {
struct list_head list_node;
u32 session_id;
bool system;
};

struct optee_context_data {
Expand Down Expand Up @@ -228,7 +241,8 @@ int optee_supp_send(struct tee_context *ctx, u32 ret, u32 num_params,
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_helper(struct tee_context *ctx,
struct optee_session *sess);
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);
Expand Down Expand Up @@ -301,6 +315,10 @@ void optee_rpc_cmd_free_suppl(struct tee_context *ctx, struct tee_shm *shm);
void optee_rpc_cmd(struct tee_context *ctx, struct optee *optee,
struct optee_msg_arg *arg);

/* Find a session held in optee context */
struct optee_session *optee_find_session(struct optee_context_data *ctxdata,
u32 session_id);

/*
* Small helpers
*/
Expand Down
Loading