aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tee/optee/ffa_abi.c
diff options
context:
space:
mode:
authorJens Wiklander <jens.wiklander@linaro.org>2022-01-25 21:26:42 +0100
committerJens Wiklander <jens.wiklander@linaro.org>2022-04-25 21:13:05 +0200
commit5b4018b959149eb5b5f3004fc0339674af67516b (patch)
tree8a5463d7692bcc860ab5cf0cdfe1ebc76768f7af /drivers/tee/optee/ffa_abi.c
parentoptee: add FF-A capability OPTEE_FFA_SEC_CAP_ARG_OFFSET (diff)
downloadlinux-dev-5b4018b959149eb5b5f3004fc0339674af67516b.tar.xz
linux-dev-5b4018b959149eb5b5f3004fc0339674af67516b.zip
optee: cache argument shared memory structs
Implements a cache to handle shared memory used to pass the argument struct needed when doing a normal yielding call into secure world. Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
Diffstat (limited to 'drivers/tee/optee/ffa_abi.c')
-rw-r--r--drivers/tee/optee/ffa_abi.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/drivers/tee/optee/ffa_abi.c b/drivers/tee/optee/ffa_abi.c
index cc863aaefcd9..1552cd3f9d4e 100644
--- a/drivers/tee/optee/ffa_abi.c
+++ b/drivers/tee/optee/ffa_abi.c
@@ -601,6 +601,7 @@ done:
* optee_ffa_do_call_with_arg() - Do a FF-A call to enter OP-TEE in secure world
* @ctx: calling context
* @shm: shared memory holding the message to pass to secure world
+ * @offs: offset of the message in @shm
*
* Does a FF-A call to OP-TEE in secure world and handles eventual resulting
* Remote Procedure Calls (RPC) from OP-TEE.
@@ -609,13 +610,13 @@ done:
*/
static int optee_ffa_do_call_with_arg(struct tee_context *ctx,
- struct tee_shm *shm)
+ struct tee_shm *shm, u_int offs)
{
struct ffa_send_direct_data data = {
.data0 = OPTEE_FFA_YIELDING_CALL_WITH_ARG,
.data1 = (u32)shm->sec_world_id,
.data2 = (u32)(shm->sec_world_id >> 32),
- .data3 = 0,
+ .data3 = offs,
};
struct optee_msg_arg *arg;
unsigned int rpc_arg_offs;
@@ -630,12 +631,12 @@ static int optee_ffa_do_call_with_arg(struct tee_context *ctx,
if (shm->offset)
return -EINVAL;
- arg = tee_shm_get_va(shm, 0);
+ arg = tee_shm_get_va(shm, offs);
if (IS_ERR(arg))
return PTR_ERR(arg);
rpc_arg_offs = OPTEE_MSG_GET_ARG_SIZE(arg->num_params);
- rpc_arg = tee_shm_get_va(shm, rpc_arg_offs);
+ rpc_arg = tee_shm_get_va(shm, offs + rpc_arg_offs);
if (IS_ERR(rpc_arg))
return PTR_ERR(rpc_arg);
@@ -787,6 +788,7 @@ static int optee_ffa_probe(struct ffa_device *ffa_dev)
struct tee_shm_pool *pool;
struct tee_device *teedev;
struct tee_context *ctx;
+ u32 arg_cache_flags = 0;
struct optee *optee;
u32 sec_caps;
int rc;
@@ -803,6 +805,8 @@ static int optee_ffa_probe(struct ffa_device *ffa_dev)
if (!optee_ffa_exchange_caps(ffa_dev, ffa_ops, &sec_caps,
&rpc_param_count))
return -EINVAL;
+ if (sec_caps & OPTEE_FFA_SEC_CAP_ARG_OFFSET)
+ arg_cache_flags |= OPTEE_SHM_ARG_SHARED;
optee = kzalloc(sizeof(*optee), GFP_KERNEL);
if (!optee)
@@ -851,6 +855,7 @@ static int optee_ffa_probe(struct ffa_device *ffa_dev)
mutex_init(&optee->call_queue.mutex);
INIT_LIST_HEAD(&optee->call_queue.waiters);
optee_supp_init(&optee->supp);
+ optee_shm_arg_cache_init(optee, arg_cache_flags);
ffa_dev_set_drvdata(ffa_dev, optee);
ctx = teedev_open(optee->teedev);
if (IS_ERR(ctx)) {