Skip to content

Commit 647242c

Browse files
author
Hernan Gatta
committed
tee: OCALL support
Enable Trusted Applications (TAs) to invoke functions on their corresponding Client Application (CA), both during session open and function invocation. These function invocations from TA to CA are referred to as "Out Calls", or OCALLs for short. The fundamental mechanism is one whereby upon a function invocation from the CA to the TA, the TEE returns prematurely from the invocation with an RPC. This RPC is generated after a TA calls the TEEC_InvokeCommand equivalent function in secure world. The RPC carries information describing the OCALL as well as its parameters. When this happens, the driver saves the state of the current call and returns to user-mode. The TEE Client API will have invoked the TEE_IOC_INVOKE IOCTL with a special parameter that carries OCALL information. When the IOCTL returns prematurely, this parameter includes information about what the CA is expected to do on behalf of the TA along with data to be used to reply to the request. The TEE Client API dispatches the request accordingly to the CA proper. Once that is done, the TEE Client API calls the TEE_IOC_INVOKE IOCTL again with the modified OCALL parameter and associated information (such as the result of the OCALL, and the parameters, as requested by the TA). The driver notices that this invocation is in fact a resumption as opposed to a brand-new invocation, and resumes the secure world thread that sent the RPC in the first place. The same mechanism applies to OCALLs during session open. This patch also minimally updates the OP-TEE and AMD TEE drivers to match the new signatures for session open and invoke. If an OCALL is specified by the CA, EOPNOTSUPP is returned. Signed-off-by: Hernan Gatta <[email protected]>
1 parent be70804 commit 647242c

File tree

8 files changed

+439
-81
lines changed

8 files changed

+439
-81
lines changed

drivers/tee/amdtee/amdtee_private.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,13 +122,17 @@ static inline u32 get_session_index(u32 session)
122122

123123
int amdtee_open_session(struct tee_context *ctx,
124124
struct tee_ioctl_open_session_arg *arg,
125-
struct tee_param *param);
125+
struct tee_param *normal_param,
126+
u32 num_normal_params,
127+
struct tee_param *ocall_param);
126128

127129
int amdtee_close_session(struct tee_context *ctx, u32 session);
128130

129131
int amdtee_invoke_func(struct tee_context *ctx,
130132
struct tee_ioctl_invoke_arg *arg,
131-
struct tee_param *param);
133+
struct tee_param *normal_param,
134+
u32 num_normal_params,
135+
struct tee_param *ocall_param);
132136

133137
int amdtee_cancel_req(struct tee_context *ctx, u32 cancel_id, u32 session);
134138

drivers/tee/amdtee/core.c

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,9 @@ static void destroy_session(struct kref *ref)
230230

231231
int amdtee_open_session(struct tee_context *ctx,
232232
struct tee_ioctl_open_session_arg *arg,
233-
struct tee_param *param)
233+
struct tee_param *normal_param,
234+
u32 num_normal_params,
235+
struct tee_param *ocall_param)
234236
{
235237
struct amdtee_context_data *ctxdata = ctx->data;
236238
struct amdtee_session *sess = NULL;
@@ -239,6 +241,11 @@ int amdtee_open_session(struct tee_context *ctx,
239241
int rc, i;
240242
void *ta;
241243

244+
if (ocall_param) {
245+
pr_err("OCALLs not supported\n");
246+
return -EOPNOTSUPP;
247+
}
248+
242249
if (arg->clnt_login != TEE_IOCTL_LOGIN_PUBLIC) {
243250
pr_err("unsupported client login method\n");
244251
return -EINVAL;
@@ -279,7 +286,7 @@ int amdtee_open_session(struct tee_context *ctx,
279286
}
280287

281288
/* Open session with loaded TA */
282-
handle_open_session(arg, &session_info, param);
289+
handle_open_session(arg, &session_info, normal_param);
283290
if (arg->ret != TEEC_SUCCESS) {
284291
pr_err("open_session failed %d\n", arg->ret);
285292
spin_lock(&sess->lock);
@@ -391,12 +398,19 @@ void amdtee_unmap_shmem(struct tee_shm *shm)
391398

392399
int amdtee_invoke_func(struct tee_context *ctx,
393400
struct tee_ioctl_invoke_arg *arg,
394-
struct tee_param *param)
401+
struct tee_param *normal_param,
402+
u32 num_normal_params,
403+
struct tee_param *ocall_param)
395404
{
396405
struct amdtee_context_data *ctxdata = ctx->data;
397406
struct amdtee_session *sess;
398407
u32 i, session_info;
399408

409+
if (ocall_param) {
410+
pr_err("OCALLs not supported\n");
411+
return -EOPNOTSUPP;
412+
}
413+
400414
/* Check that the session is valid */
401415
mutex_lock(&session_list_mutex);
402416
sess = find_session(ctxdata, arg->session);
@@ -409,7 +423,7 @@ int amdtee_invoke_func(struct tee_context *ctx,
409423
if (!sess)
410424
return -EINVAL;
411425

412-
handle_invoke_cmd(arg, session_info, param);
426+
handle_invoke_cmd(arg, session_info, normal_param);
413427

414428
return 0;
415429
}
@@ -422,6 +436,7 @@ int amdtee_cancel_req(struct tee_context *ctx, u32 cancel_id, u32 session)
422436
static const struct tee_driver_ops amdtee_ops = {
423437
.get_version = amdtee_get_version,
424438
.open = amdtee_open,
439+
.pre_release = NULL,
425440
.release = amdtee_release,
426441
.open_session = amdtee_open_session,
427442
.close_session = amdtee_close_session,

drivers/tee/optee/call.c

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,9 @@ static struct tee_shm *get_msg_arg(struct tee_context *ctx, size_t num_params,
127127

128128
int optee_open_session(struct tee_context *ctx,
129129
struct tee_ioctl_open_session_arg *arg,
130-
struct tee_param *param)
130+
struct tee_param *normal_param,
131+
u32 num_normal_params,
132+
struct tee_param *ocall_param)
131133
{
132134
struct optee_context_data *ctxdata = ctx->data;
133135
int rc;
@@ -136,6 +138,11 @@ int optee_open_session(struct tee_context *ctx,
136138
phys_addr_t msg_parg;
137139
struct optee_session *sess = NULL;
138140

141+
if (ocall_param) {
142+
pr_err("OCALLs not supported\n");
143+
return -EOPNOTSUPP;
144+
}
145+
139146
/* +2 for the meta parameters added below */
140147
shm = get_msg_arg(ctx, arg->num_params + 2, &msg_arg, &msg_parg);
141148
if (IS_ERR(shm))
@@ -160,7 +167,8 @@ int optee_open_session(struct tee_context *ctx,
160167
if (rc)
161168
goto out;
162169

163-
rc = optee_to_msg_param(msg_arg->params + 2, arg->num_params, param);
170+
rc = optee_to_msg_param(msg_arg->params + 2, arg->num_params,
171+
normal_param);
164172
if (rc)
165173
goto out;
166174

@@ -185,7 +193,8 @@ int optee_open_session(struct tee_context *ctx,
185193
kfree(sess);
186194
}
187195

188-
if (optee_from_msg_param(param, arg->num_params, msg_arg->params + 2)) {
196+
if (optee_from_msg_param(normal_param, arg->num_params,
197+
msg_arg->params + 2)) {
189198
arg->ret = TEEC_ERROR_COMMUNICATION;
190199
arg->ret_origin = TEEC_ORIGIN_COMMS;
191200
/* Close session again to avoid leakage */
@@ -232,7 +241,8 @@ int optee_close_session(struct tee_context *ctx, u32 session)
232241
}
233242

234243
int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
235-
struct tee_param *param)
244+
struct tee_param *normal_param, u32 num_normal_params,
245+
struct tee_param *ocall_param)
236246
{
237247
struct optee_context_data *ctxdata = ctx->data;
238248
struct tee_shm *shm;
@@ -241,6 +251,11 @@ int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
241251
struct optee_session *sess;
242252
int rc;
243253

254+
if (ocall_param) {
255+
pr_err("OCALLs not supported\n");
256+
return -EOPNOTSUPP;
257+
}
258+
244259
/* Check that the session is valid */
245260
mutex_lock(&ctxdata->mutex);
246261
sess = find_session(ctxdata, arg->session);
@@ -256,7 +271,7 @@ int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
256271
msg_arg->session = arg->session;
257272
msg_arg->cancel_id = arg->cancel_id;
258273

259-
rc = optee_to_msg_param(msg_arg->params, arg->num_params, param);
274+
rc = optee_to_msg_param(msg_arg->params, arg->num_params, normal_param);
260275
if (rc)
261276
goto out;
262277

@@ -265,7 +280,8 @@ int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
265280
msg_arg->ret_origin = TEEC_ORIGIN_COMMS;
266281
}
267282

268-
if (optee_from_msg_param(param, arg->num_params, msg_arg->params)) {
283+
if (optee_from_msg_param(normal_param, arg->num_params,
284+
msg_arg->params)) {
269285
msg_arg->ret = TEEC_ERROR_COMMUNICATION;
270286
msg_arg->ret_origin = TEEC_ORIGIN_COMMS;
271287
}

drivers/tee/optee/core.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,7 @@ static void optee_release(struct tee_context *ctx)
334334
static const struct tee_driver_ops optee_ops = {
335335
.get_version = optee_get_version,
336336
.open = optee_open,
337+
.pre_release = NULL,
337338
.release = optee_release,
338339
.open_session = optee_open_session,
339340
.close_session = optee_close_session,

drivers/tee/optee/optee_private.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,10 +155,12 @@ int optee_supp_send(struct tee_context *ctx, u32 ret, u32 num_params,
155155
u32 optee_do_call_with_arg(struct tee_context *ctx, phys_addr_t parg);
156156
int optee_open_session(struct tee_context *ctx,
157157
struct tee_ioctl_open_session_arg *arg,
158-
struct tee_param *param);
158+
struct tee_param *normal_param, u32 num_normal_params,
159+
struct tee_param *ocall_param);
159160
int optee_close_session(struct tee_context *ctx, u32 session);
160161
int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
161-
struct tee_param *param);
162+
struct tee_param *normal_param, u32 num_normal_params,
163+
struct tee_param *ocall_param);
162164
int optee_cancel_req(struct tee_context *ctx, u32 cancel_id, u32 session);
163165

164166
void optee_enable_shm_cache(struct optee *optee);

0 commit comments

Comments
 (0)