1
1
// SPDX-License-Identifier: GPL-2.0-only
2
2
/*
3
- * Copyright (c) 2015, Linaro Limited
3
+ * Copyright (c) 2015-2021 , Linaro Limited
4
4
*/
5
5
#include <linux/arm-smccc.h>
6
6
#include <linux/device.h>
@@ -118,20 +118,25 @@ static struct optee_session *find_session(struct optee_context_data *ctxdata,
118
118
/**
119
119
* optee_do_call_with_arg() - Do an SMC to OP-TEE in secure world
120
120
* @ctx: calling context
121
- * @parg: physical address of message to pass to secure world
121
+ * @arg: shared memory holding the message to pass to secure world
122
122
*
123
123
* Does and SMC to OP-TEE in secure world and handles eventual resulting
124
124
* Remote Procedure Calls (RPC) from OP-TEE.
125
125
*
126
126
* Returns return code from secure world, 0 is OK
127
127
*/
128
- u32 optee_do_call_with_arg (struct tee_context * ctx , phys_addr_t parg )
128
+ int optee_do_call_with_arg (struct tee_context * ctx , struct tee_shm * arg )
129
129
{
130
130
struct optee * optee = tee_get_drvdata (ctx -> teedev );
131
131
struct optee_call_waiter w ;
132
132
struct optee_rpc_param param = { };
133
133
struct optee_call_ctx call_ctx = { };
134
- u32 ret ;
134
+ phys_addr_t parg ;
135
+ int rc ;
136
+
137
+ rc = tee_shm_get_pa (arg , 0 , & parg );
138
+ if (rc )
139
+ return rc ;
135
140
136
141
param .a0 = OPTEE_SMC_CALL_WITH_ARG ;
137
142
reg_pair_from_64 (& param .a1 , & param .a2 , parg );
@@ -160,7 +165,7 @@ u32 optee_do_call_with_arg(struct tee_context *ctx, phys_addr_t parg)
160
165
param .a3 = res .a3 ;
161
166
optee_handle_rpc (ctx , & param , & call_ctx );
162
167
} else {
163
- ret = res .a0 ;
168
+ rc = res .a0 ;
164
169
break ;
165
170
}
166
171
}
@@ -172,14 +177,12 @@ u32 optee_do_call_with_arg(struct tee_context *ctx, phys_addr_t parg)
172
177
*/
173
178
optee_cq_wait_final (& optee -> call_queue , & w );
174
179
175
- return ret ;
180
+ return rc ;
176
181
}
177
182
178
183
static struct tee_shm * get_msg_arg (struct tee_context * ctx , size_t num_params ,
179
- struct optee_msg_arg * * msg_arg ,
180
- phys_addr_t * msg_parg )
184
+ struct optee_msg_arg * * msg_arg )
181
185
{
182
- int rc ;
183
186
struct tee_shm * shm ;
184
187
struct optee_msg_arg * ma ;
185
188
@@ -190,22 +193,13 @@ static struct tee_shm *get_msg_arg(struct tee_context *ctx, size_t num_params,
190
193
191
194
ma = tee_shm_get_va (shm , 0 );
192
195
if (IS_ERR (ma )) {
193
- rc = PTR_ERR ( ma );
194
- goto out ;
196
+ tee_shm_free ( shm );
197
+ return ( void * ) ma ;
195
198
}
196
199
197
- rc = tee_shm_get_pa (shm , 0 , msg_parg );
198
- if (rc )
199
- goto out ;
200
-
201
200
memset (ma , 0 , OPTEE_MSG_GET_ARG_SIZE (num_params ));
202
201
ma -> num_params = num_params ;
203
202
* msg_arg = ma ;
204
- out :
205
- if (rc ) {
206
- tee_shm_free (shm );
207
- return ERR_PTR (rc );
208
- }
209
203
210
204
return shm ;
211
205
}
@@ -214,16 +208,16 @@ int optee_open_session(struct tee_context *ctx,
214
208
struct tee_ioctl_open_session_arg * arg ,
215
209
struct tee_param * param )
216
210
{
211
+ struct optee * optee = tee_get_drvdata (ctx -> teedev );
217
212
struct optee_context_data * ctxdata = ctx -> data ;
218
213
int rc ;
219
214
struct tee_shm * shm ;
220
215
struct optee_msg_arg * msg_arg ;
221
- phys_addr_t msg_parg ;
222
216
struct optee_session * sess = NULL ;
223
217
uuid_t client_uuid ;
224
218
225
219
/* +2 for the meta parameters added below */
226
- shm = get_msg_arg (ctx , arg -> num_params + 2 , & msg_arg , & msg_parg );
220
+ shm = get_msg_arg (ctx , arg -> num_params + 2 , & msg_arg );
227
221
if (IS_ERR (shm ))
228
222
return PTR_ERR (shm );
229
223
@@ -247,7 +241,8 @@ int optee_open_session(struct tee_context *ctx,
247
241
goto out ;
248
242
export_uuid (msg_arg -> params [1 ].u .octets , & client_uuid );
249
243
250
- rc = optee_to_msg_param (msg_arg -> params + 2 , arg -> num_params , param );
244
+ rc = optee -> ops -> to_msg_param (optee , msg_arg -> params + 2 ,
245
+ arg -> num_params , param );
251
246
if (rc )
252
247
goto out ;
253
248
@@ -257,7 +252,7 @@ int optee_open_session(struct tee_context *ctx,
257
252
goto out ;
258
253
}
259
254
260
- if (optee_do_call_with_arg (ctx , msg_parg )) {
255
+ if (optee -> ops -> do_call_with_arg (ctx , shm )) {
261
256
msg_arg -> ret = TEEC_ERROR_COMMUNICATION ;
262
257
msg_arg -> ret_origin = TEEC_ORIGIN_COMMS ;
263
258
}
@@ -272,7 +267,8 @@ int optee_open_session(struct tee_context *ctx,
272
267
kfree (sess );
273
268
}
274
269
275
- if (optee_from_msg_param (param , arg -> num_params , msg_arg -> params + 2 )) {
270
+ if (optee -> ops -> from_msg_param (optee , param , arg -> num_params ,
271
+ msg_arg -> params + 2 )) {
276
272
arg -> ret = TEEC_ERROR_COMMUNICATION ;
277
273
arg -> ret_origin = TEEC_ORIGIN_COMMS ;
278
274
/* Close session again to avoid leakage */
@@ -291,16 +287,16 @@ int optee_open_session(struct tee_context *ctx,
291
287
int optee_close_session_helper (struct tee_context * ctx , u32 session )
292
288
{
293
289
struct tee_shm * shm ;
290
+ struct optee * optee = tee_get_drvdata (ctx -> teedev );
294
291
struct optee_msg_arg * msg_arg ;
295
- phys_addr_t msg_parg ;
296
292
297
- shm = get_msg_arg (ctx , 0 , & msg_arg , & msg_parg );
293
+ shm = get_msg_arg (ctx , 0 , & msg_arg );
298
294
if (IS_ERR (shm ))
299
295
return PTR_ERR (shm );
300
296
301
297
msg_arg -> cmd = OPTEE_MSG_CMD_CLOSE_SESSION ;
302
298
msg_arg -> session = session ;
303
- optee_do_call_with_arg (ctx , msg_parg );
299
+ optee -> ops -> do_call_with_arg (ctx , shm );
304
300
305
301
tee_shm_free (shm );
306
302
@@ -328,10 +324,10 @@ int optee_close_session(struct tee_context *ctx, u32 session)
328
324
int optee_invoke_func (struct tee_context * ctx , struct tee_ioctl_invoke_arg * arg ,
329
325
struct tee_param * param )
330
326
{
327
+ struct optee * optee = tee_get_drvdata (ctx -> teedev );
331
328
struct optee_context_data * ctxdata = ctx -> data ;
332
329
struct tee_shm * shm ;
333
330
struct optee_msg_arg * msg_arg ;
334
- phys_addr_t msg_parg ;
335
331
struct optee_session * sess ;
336
332
int rc ;
337
333
@@ -342,24 +338,26 @@ int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
342
338
if (!sess )
343
339
return - EINVAL ;
344
340
345
- shm = get_msg_arg (ctx , arg -> num_params , & msg_arg , & msg_parg );
341
+ shm = get_msg_arg (ctx , arg -> num_params , & msg_arg );
346
342
if (IS_ERR (shm ))
347
343
return PTR_ERR (shm );
348
344
msg_arg -> cmd = OPTEE_MSG_CMD_INVOKE_COMMAND ;
349
345
msg_arg -> func = arg -> func ;
350
346
msg_arg -> session = arg -> session ;
351
347
msg_arg -> cancel_id = arg -> cancel_id ;
352
348
353
- rc = optee_to_msg_param (msg_arg -> params , arg -> num_params , param );
349
+ rc = optee -> ops -> to_msg_param (optee , msg_arg -> params , arg -> num_params ,
350
+ param );
354
351
if (rc )
355
352
goto out ;
356
353
357
- if (optee_do_call_with_arg (ctx , msg_parg )) {
354
+ if (optee -> ops -> do_call_with_arg (ctx , shm )) {
358
355
msg_arg -> ret = TEEC_ERROR_COMMUNICATION ;
359
356
msg_arg -> ret_origin = TEEC_ORIGIN_COMMS ;
360
357
}
361
358
362
- if (optee_from_msg_param (param , arg -> num_params , msg_arg -> params )) {
359
+ if (optee -> ops -> from_msg_param (optee , param , arg -> num_params ,
360
+ msg_arg -> params )) {
363
361
msg_arg -> ret = TEEC_ERROR_COMMUNICATION ;
364
362
msg_arg -> ret_origin = TEEC_ORIGIN_COMMS ;
365
363
}
@@ -373,10 +371,10 @@ int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
373
371
374
372
int optee_cancel_req (struct tee_context * ctx , u32 cancel_id , u32 session )
375
373
{
374
+ struct optee * optee = tee_get_drvdata (ctx -> teedev );
376
375
struct optee_context_data * ctxdata = ctx -> data ;
377
376
struct tee_shm * shm ;
378
377
struct optee_msg_arg * msg_arg ;
379
- phys_addr_t msg_parg ;
380
378
struct optee_session * sess ;
381
379
382
380
/* Check that the session is valid */
@@ -386,14 +384,14 @@ int optee_cancel_req(struct tee_context *ctx, u32 cancel_id, u32 session)
386
384
if (!sess )
387
385
return - EINVAL ;
388
386
389
- shm = get_msg_arg (ctx , 0 , & msg_arg , & msg_parg );
387
+ shm = get_msg_arg (ctx , 0 , & msg_arg );
390
388
if (IS_ERR (shm ))
391
389
return PTR_ERR (shm );
392
390
393
391
msg_arg -> cmd = OPTEE_MSG_CMD_CANCEL ;
394
392
msg_arg -> session = session ;
395
393
msg_arg -> cancel_id = cancel_id ;
396
- optee_do_call_with_arg (ctx , msg_parg );
394
+ optee -> ops -> do_call_with_arg (ctx , shm );
397
395
398
396
tee_shm_free (shm );
399
397
return 0 ;
@@ -622,10 +620,10 @@ int optee_shm_register(struct tee_context *ctx, struct tee_shm *shm,
622
620
struct page * * pages , size_t num_pages ,
623
621
unsigned long start )
624
622
{
625
- struct tee_shm * shm_arg = NULL ;
623
+ struct optee * optee = tee_get_drvdata ( ctx -> teedev ) ;
626
624
struct optee_msg_arg * msg_arg ;
625
+ struct tee_shm * shm_arg ;
627
626
u64 * pages_list ;
628
- phys_addr_t msg_parg ;
629
627
int rc ;
630
628
631
629
if (!num_pages )
@@ -639,7 +637,7 @@ int optee_shm_register(struct tee_context *ctx, struct tee_shm *shm,
639
637
if (!pages_list )
640
638
return - ENOMEM ;
641
639
642
- shm_arg = get_msg_arg (ctx , 1 , & msg_arg , & msg_parg );
640
+ shm_arg = get_msg_arg (ctx , 1 , & msg_arg );
643
641
if (IS_ERR (shm_arg )) {
644
642
rc = PTR_ERR (shm_arg );
645
643
goto out ;
@@ -660,7 +658,7 @@ int optee_shm_register(struct tee_context *ctx, struct tee_shm *shm,
660
658
msg_arg -> params -> u .tmem .buf_ptr = virt_to_phys (pages_list ) |
661
659
(tee_shm_get_page_offset (shm ) & (OPTEE_MSG_NONCONTIG_PAGE_SIZE - 1 ));
662
660
663
- if (optee_do_call_with_arg (ctx , msg_parg ) ||
661
+ if (optee -> ops -> do_call_with_arg (ctx , shm_arg ) ||
664
662
msg_arg -> ret != TEEC_SUCCESS )
665
663
rc = - EINVAL ;
666
664
@@ -672,12 +670,12 @@ int optee_shm_register(struct tee_context *ctx, struct tee_shm *shm,
672
670
673
671
int optee_shm_unregister (struct tee_context * ctx , struct tee_shm * shm )
674
672
{
675
- struct tee_shm * shm_arg ;
673
+ struct optee * optee = tee_get_drvdata ( ctx -> teedev ) ;
676
674
struct optee_msg_arg * msg_arg ;
677
- phys_addr_t msg_parg ;
675
+ struct tee_shm * shm_arg ;
678
676
int rc = 0 ;
679
677
680
- shm_arg = get_msg_arg (ctx , 1 , & msg_arg , & msg_parg );
678
+ shm_arg = get_msg_arg (ctx , 1 , & msg_arg );
681
679
if (IS_ERR (shm_arg ))
682
680
return PTR_ERR (shm_arg );
683
681
@@ -686,7 +684,7 @@ int optee_shm_unregister(struct tee_context *ctx, struct tee_shm *shm)
686
684
msg_arg -> params [0 ].attr = OPTEE_MSG_ATTR_TYPE_RMEM_INPUT ;
687
685
msg_arg -> params [0 ].u .rmem .shm_ref = (unsigned long )shm ;
688
686
689
- if (optee_do_call_with_arg (ctx , msg_parg ) ||
687
+ if (optee -> ops -> do_call_with_arg (ctx , shm_arg ) ||
690
688
msg_arg -> ret != TEEC_SUCCESS )
691
689
rc = - EINVAL ;
692
690
tee_shm_free (shm_arg );
0 commit comments