Skip to content
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: 2 additions & 2 deletions drivers/firmware/arm_scmi/optee.c
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ static int invoke_process_smt_channel(struct scmi_optee_channel *channel)
param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
param[0].u.value.a = channel->channel_id;

ret = tee_client_invoke_func(scmi_optee_private->tee_ctx, &arg, param);
ret = tee_client_system_invoke_func(scmi_optee_private->tee_ctx, &arg, param);
if (ret < 0 || arg.ret) {
dev_err(scmi_optee_private->dev, "Can't invoke channel %u: %d / %#x\n",
channel->channel_id, ret, arg.ret);
Expand Down Expand Up @@ -297,7 +297,7 @@ static int invoke_process_msg_channel(struct scmi_optee_channel *channel, size_t
param[2].u.memref.shm = channel->tee_shm;
param[2].u.memref.size = SCMI_OPTEE_MAX_MSG_SIZE;

ret = tee_client_invoke_func(scmi_optee_private->tee_ctx, &arg, param);
ret = tee_client_system_invoke_func(scmi_optee_private->tee_ctx, &arg, param);
if (ret < 0 || arg.ret) {
dev_err(scmi_optee_private->dev, "Can't invoke channel %u: %d / %#x\n",
channel->channel_id, ret, arg.ret);
Expand Down
6 changes: 3 additions & 3 deletions drivers/tee/amdtee/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ static void destroy_session(struct kref *ref)

int amdtee_open_session(struct tee_context *ctx,
struct tee_ioctl_open_session_arg *arg,
struct tee_param *param)
struct tee_param *param, bool system_thread)
{
struct amdtee_context_data *ctxdata = ctx->data;
struct amdtee_session *sess = NULL;
Expand Down Expand Up @@ -301,7 +301,7 @@ int amdtee_open_session(struct tee_context *ctx,
return rc;
}

int amdtee_close_session(struct tee_context *ctx, u32 session)
int amdtee_close_session(struct tee_context *ctx, u32 session, bool system_thread)
{
struct amdtee_context_data *ctxdata = ctx->data;
u32 i, ta_handle, session_info;
Expand Down Expand Up @@ -405,7 +405,7 @@ void amdtee_unmap_shmem(struct tee_shm *shm)

int amdtee_invoke_func(struct tee_context *ctx,
struct tee_ioctl_invoke_arg *arg,
struct tee_param *param)
struct tee_param *param, bool system_thread)
{
struct amdtee_context_data *ctxdata = ctx->data;
struct amdtee_session *sess;
Expand Down
10 changes: 5 additions & 5 deletions drivers/tee/optee/call.c
Original file line number Diff line number Diff line change
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 @@ -374,7 +374,7 @@ int optee_close_session_helper(struct tee_context *ctx, u32 session)

msg_arg->cmd = OPTEE_MSG_CMD_CLOSE_SESSION;
msg_arg->session = session;
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);

Expand All @@ -400,7 +400,7 @@ 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)
struct tee_param *param, bool system_thread)
{
struct optee *optee = tee_get_drvdata(ctx->teedev);
struct optee_context_data *ctxdata = ctx->data;
Expand Down Expand Up @@ -432,7 +432,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, system_thread)) {
msg_arg->ret = TEEC_ERROR_COMMUNICATION;
msg_arg->ret_origin = TEEC_ORIGIN_COMMS;
}
Expand Down Expand Up @@ -474,7 +474,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
3 changes: 2 additions & 1 deletion drivers/tee/optee/ffa_abi.c
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,7 @@ static int optee_ffa_yielding_call(struct tee_context *ctx,
* @ctx: calling context
* @shm: shared memory holding the message to pass to secure world
* @offs: offset of the message in @shm
* @system_thread True if invocation expects to use a provisioned TEE system thread
*
* Does a FF-A call to OP-TEE in secure world and handles eventual resulting
* Remote Procedure Calls (RPC) from OP-TEE.
Expand All @@ -612,7 +613,7 @@ 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_thread)
{
struct ffa_send_direct_data data = {
.data0 = OPTEE_FFA_YIELDING_CALL_WITH_ARG,
Expand Down
5 changes: 3 additions & 2 deletions drivers/tee/optee/optee_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,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_thread);
int (*to_msg_param)(struct optee *optee,
struct optee_msg_param *msg_params,
size_t num_params, const struct tee_param *params);
Expand Down Expand Up @@ -231,7 +232,7 @@ int optee_open_session(struct tee_context *ctx,
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);
struct tee_param *param, bool system_thread);
int optee_cancel_req(struct tee_context *ctx, u32 cancel_id, u32 session);

#define PTA_CMD_GET_DEVICES 0x0
Expand Down
18 changes: 15 additions & 3 deletions drivers/tee/optee/optee_smc.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@ struct optee_smc_call_get_os_revision_result {
* Call with struct optee_msg_arg as argument
*
* When called with OPTEE_SMC_CALL_WITH_RPC_ARG or
* OPTEE_SMC_CALL_WITH_REGD_ARG in a0 there is one RPC struct optee_msg_arg
* OPTEE_SMC_CALL_WITH_REGD_ARG or OPTEE_SMC_FUNCID_CALL_SYSTEM_WITH_REGD_ARG
* in a0 there is one RPC struct optee_msg_arg
* following after the first struct optee_msg_arg. The RPC struct
* optee_msg_arg has reserved space for the number of RPC parameters as
* returned by OPTEE_SMC_EXCHANGE_CAPABILITIES.
Expand All @@ -130,8 +131,8 @@ struct optee_smc_call_get_os_revision_result {
* a4-6 Not used
* a7 Hypervisor Client ID register
*
* Call register usage, OPTEE_SMC_CALL_WITH_REGD_ARG:
* a0 SMC Function ID, OPTEE_SMC_CALL_WITH_REGD_ARG
* Call register usage, OPTEE_SMC_CALL_WITH_REGD_ARG and OPTEE_SMC_FUNCID_CALL_SYSTEM_WITH_REGD_ARG:
* a0 SMC Function ID, OPTEE_SMC_CALL_WITH_REGD_ARG or OPTEE_SMC_FUNCID_CALL_SYSTEM_WITH_REGD_ARG
* a1 Upper 32 bits of a 64-bit shared memory cookie
* a2 Lower 32 bits of a 64-bit shared memory cookie
* a3 Offset of the struct optee_msg_arg in the shared memory with the
Expand Down Expand Up @@ -175,6 +176,8 @@ struct optee_smc_call_get_os_revision_result {
OPTEE_SMC_STD_CALL_VAL(OPTEE_SMC_FUNCID_CALL_WITH_RPC_ARG)
#define OPTEE_SMC_CALL_WITH_REGD_ARG \
OPTEE_SMC_STD_CALL_VAL(OPTEE_SMC_FUNCID_CALL_WITH_REGD_ARG)
#define OPTEE_SMC_CALL_SYSTEM_WITH_REGD_ARG \
OPTEE_SMC_STD_CALL_VAL(OPTEE_SMC_FUNCID_CALL_SYSTEM_WITH_REGD_ARG)

/*
* Get Shared Memory Config
Expand Down Expand Up @@ -255,6 +258,12 @@ struct optee_smc_get_shm_config_result {
/* Secure world supports pre-allocating RPC arg struct */
#define OPTEE_SMC_SEC_CAP_RPC_ARG BIT(6)

/* Secure world provisions thread for system service invocation */
#define OPTEE_SMC_SEC_CAP_SYSTEM_THREAD BIT(8)

#define MAX_NOTIF_VALUE_MASK GENMASK(15, 0)
#define MAX_NOTIF_IT_SHIFT 16

#define OPTEE_SMC_FUNCID_EXCHANGE_CAPABILITIES 9
#define OPTEE_SMC_EXCHANGE_CAPABILITIES \
OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_EXCHANGE_CAPABILITIES)
Expand Down Expand Up @@ -426,6 +435,9 @@ struct optee_smc_disable_shm_cache_result {
/* See OPTEE_SMC_CALL_WITH_REGD_ARG above */
#define OPTEE_SMC_FUNCID_CALL_WITH_REGD_ARG 19

/* See OPTEE_SMC_CALL_SYSTEM_WITH_REGD_ARG above */
#define OPTEE_SMC_FUNCID_CALL_SYSTEM_WITH_REGD_ARG 22

/*
* Resume from RPC (for example after processing a foreign interrupt)
*
Expand Down
16 changes: 11 additions & 5 deletions drivers/tee/optee/smc_abi.c
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,7 @@ static int optee_shm_register(struct tee_context *ctx, struct tee_shm *shm,
msg_arg->params->u.tmem.buf_ptr = virt_to_phys(pages_list) |
(tee_shm_get_page_offset(shm) & (OPTEE_MSG_NONCONTIG_PAGE_SIZE - 1));

if (optee->ops->do_call_with_arg(ctx, shm_arg, 0) ||
if (optee->ops->do_call_with_arg(ctx, shm_arg, 0, false) ||
msg_arg->ret != TEEC_SUCCESS)
rc = -EINVAL;

Expand Down Expand Up @@ -530,7 +530,7 @@ static int optee_shm_unregister(struct tee_context *ctx, struct tee_shm *shm)
msg_arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_RMEM_INPUT;
msg_arg->params[0].u.rmem.shm_ref = (unsigned long)shm;

if (optee->ops->do_call_with_arg(ctx, shm_arg, 0) ||
if (optee->ops->do_call_with_arg(ctx, shm_arg, 0, false) ||
msg_arg->ret != TEEC_SUCCESS)
rc = -EINVAL;
out:
Expand Down Expand Up @@ -858,14 +858,15 @@ static void optee_handle_rpc(struct tee_context *ctx,
* @ctx: calling context
* @shm: shared memory holding the message to pass to secure world
* @offs: offset of the message in @shm
* @system_thread True if invocation can leverage TEE provisioned system thread
*
* Does and SMC to OP-TEE in secure world and handles eventual resulting
* Remote Procedure Calls (RPC) from OP-TEE.
*
* Returns return code from secure world, 0 is OK
*/
static int optee_smc_do_call_with_arg(struct tee_context *ctx,
struct tee_shm *shm, u_int offs)
struct tee_shm *shm, u_int offs, bool system_thread)
{
struct optee *optee = tee_get_drvdata(ctx->teedev);
struct optee_call_waiter w;
Expand All @@ -889,7 +890,12 @@ static int optee_smc_do_call_with_arg(struct tee_context *ctx,
}

if (rpc_arg && tee_shm_is_dynamic(shm)) {
param.a0 = OPTEE_SMC_CALL_WITH_REGD_ARG;
if (system_thread &&
optee->smc.sec_caps & OPTEE_SMC_SEC_CAP_SYSTEM_THREAD)
param.a0 = OPTEE_SMC_CALL_SYSTEM_WITH_REGD_ARG;
else
param.a0 = OPTEE_SMC_CALL_WITH_REGD_ARG;

reg_pair_from_64(&param.a1, &param.a2, (u_long)shm);
param.a3 = offs;
} else {
Expand Down Expand Up @@ -957,7 +963,7 @@ static int simple_call_with_arg(struct tee_context *ctx, u32 cmd)
return PTR_ERR(msg_arg);

msg_arg->cmd = cmd;
optee_smc_do_call_with_arg(ctx, shm, offs);
optee_smc_do_call_with_arg(ctx, shm, offs, false);

optee_free_msg_arg(ctx, entry, offs);
return 0;
Expand Down
23 changes: 19 additions & 4 deletions drivers/tee/tee_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -579,7 +579,7 @@ static int tee_ioctl_invoke(struct tee_context *ctx,
goto out;
}

rc = ctx->teedev->desc->ops->invoke_func(ctx, &arg, params);
rc = ctx->teedev->desc->ops->invoke_func(ctx, &arg, params, false);
if (rc)
goto out;

Expand Down Expand Up @@ -1170,16 +1170,31 @@ int tee_client_close_session(struct tee_context *ctx, u32 session)
}
EXPORT_SYMBOL_GPL(tee_client_close_session);

static int _tee_client_invoke_func(struct tee_context *ctx,
struct tee_ioctl_invoke_arg *arg,
struct tee_param *param, bool system_thread)
{
if (!ctx->teedev->desc->ops->invoke_func)
return -EINVAL;
return ctx->teedev->desc->ops->invoke_func(ctx, arg, param, system_thread);
}

int tee_client_invoke_func(struct tee_context *ctx,
struct tee_ioctl_invoke_arg *arg,
struct tee_param *param)
{
if (!ctx->teedev->desc->ops->invoke_func)
return -EINVAL;
return ctx->teedev->desc->ops->invoke_func(ctx, arg, param);
return _tee_client_invoke_func(ctx, arg, param, false);
}
EXPORT_SYMBOL_GPL(tee_client_invoke_func);

int tee_client_system_invoke_func(struct tee_context *ctx,
struct tee_ioctl_invoke_arg *arg,
struct tee_param *param)
{
return _tee_client_invoke_func(ctx, arg, param, true);
}
EXPORT_SYMBOL_GPL(tee_client_system_invoke_func);

int tee_client_cancel_req(struct tee_context *ctx,
struct tee_ioctl_cancel_arg *arg)
{
Expand Down
18 changes: 17 additions & 1 deletion include/linux/tee_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ struct tee_driver_ops {
int (*close_session)(struct tee_context *ctx, u32 session);
int (*invoke_func)(struct tee_context *ctx,
struct tee_ioctl_invoke_arg *arg,
struct tee_param *param);
struct tee_param *param, bool system_thread);
int (*cancel_req)(struct tee_context *ctx, u32 cancel_id, u32 session);
int (*supp_recv)(struct tee_context *ctx, u32 *func, u32 *num_params,
struct tee_param *param);
Expand Down Expand Up @@ -442,6 +442,22 @@ int tee_client_invoke_func(struct tee_context *ctx,
struct tee_ioctl_invoke_arg *arg,
struct tee_param *param);

/**
* tee_client_system_invoke_func() - Invoke a function in a system Trusted Application
* @ctx: TEE Context
* @arg: Invoke arguments, see description of
* struct tee_ioctl_invoke_arg
* @param: Parameters passed to the Trusted Application
*
* System trusted applications are trusted services requiring a provisioned
* execution context.
*
* Returns < 0 on error else see @arg->ret for result.
*/
int tee_client_system_invoke_func(struct tee_context *ctx,
struct tee_ioctl_invoke_arg *arg,
struct tee_param *param);

/**
* tee_client_cancel_req() - Request cancellation of the previous open-session
* or invoke-command operations in a Trusted Application
Expand Down