11// SPDX-License-Identifier: GPL-2.0-only
22/*
3- * Copyright (c) 2015, Linaro Limited
3+ * Copyright (c) 2015-2021 , Linaro Limited
44 */
55#include <linux/arm-smccc.h>
66#include <linux/device.h>
@@ -118,20 +118,25 @@ static struct optee_session *find_session(struct optee_context_data *ctxdata,
118118/**
119119 * optee_do_call_with_arg() - Do an SMC to OP-TEE in secure world
120120 * @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
122122 *
123123 * Does and SMC to OP-TEE in secure world and handles eventual resulting
124124 * Remote Procedure Calls (RPC) from OP-TEE.
125125 *
126126 * Returns return code from secure world, 0 is OK
127127 */
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 )
129129{
130130 struct optee * optee = tee_get_drvdata (ctx -> teedev );
131131 struct optee_call_waiter w ;
132132 struct optee_rpc_param param = { };
133133 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 ;
135140
136141 param .a0 = OPTEE_SMC_CALL_WITH_ARG ;
137142 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)
160165 param .a3 = res .a3 ;
161166 optee_handle_rpc (ctx , & param , & call_ctx );
162167 } else {
163- ret = res .a0 ;
168+ rc = res .a0 ;
164169 break ;
165170 }
166171 }
@@ -172,14 +177,12 @@ u32 optee_do_call_with_arg(struct tee_context *ctx, phys_addr_t parg)
172177 */
173178 optee_cq_wait_final (& optee -> call_queue , & w );
174179
175- return ret ;
180+ return rc ;
176181}
177182
178183static 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 )
181185{
182- int rc ;
183186 struct tee_shm * shm ;
184187 struct optee_msg_arg * ma ;
185188
@@ -190,22 +193,13 @@ static struct tee_shm *get_msg_arg(struct tee_context *ctx, size_t num_params,
190193
191194 ma = tee_shm_get_va (shm , 0 );
192195 if (IS_ERR (ma )) {
193- rc = PTR_ERR ( ma );
194- goto out ;
196+ tee_shm_free ( shm );
197+ return ( void * ) ma ;
195198 }
196199
197- rc = tee_shm_get_pa (shm , 0 , msg_parg );
198- if (rc )
199- goto out ;
200-
201200 memset (ma , 0 , OPTEE_MSG_GET_ARG_SIZE (num_params ));
202201 ma -> num_params = num_params ;
203202 * msg_arg = ma ;
204- out :
205- if (rc ) {
206- tee_shm_free (shm );
207- return ERR_PTR (rc );
208- }
209203
210204 return shm ;
211205}
@@ -214,16 +208,16 @@ int optee_open_session(struct tee_context *ctx,
214208 struct tee_ioctl_open_session_arg * arg ,
215209 struct tee_param * param )
216210{
211+ struct optee * optee = tee_get_drvdata (ctx -> teedev );
217212 struct optee_context_data * ctxdata = ctx -> data ;
218213 int rc ;
219214 struct tee_shm * shm ;
220215 struct optee_msg_arg * msg_arg ;
221- phys_addr_t msg_parg ;
222216 struct optee_session * sess = NULL ;
223217 uuid_t client_uuid ;
224218
225219 /* +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 );
227221 if (IS_ERR (shm ))
228222 return PTR_ERR (shm );
229223
@@ -247,7 +241,8 @@ int optee_open_session(struct tee_context *ctx,
247241 goto out ;
248242 export_uuid (msg_arg -> params [1 ].u .octets , & client_uuid );
249243
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 );
251246 if (rc )
252247 goto out ;
253248
@@ -257,7 +252,7 @@ int optee_open_session(struct tee_context *ctx,
257252 goto out ;
258253 }
259254
260- if (optee_do_call_with_arg (ctx , msg_parg )) {
255+ if (optee -> ops -> do_call_with_arg (ctx , shm )) {
261256 msg_arg -> ret = TEEC_ERROR_COMMUNICATION ;
262257 msg_arg -> ret_origin = TEEC_ORIGIN_COMMS ;
263258 }
@@ -272,7 +267,8 @@ int optee_open_session(struct tee_context *ctx,
272267 kfree (sess );
273268 }
274269
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 )) {
276272 arg -> ret = TEEC_ERROR_COMMUNICATION ;
277273 arg -> ret_origin = TEEC_ORIGIN_COMMS ;
278274 /* Close session again to avoid leakage */
@@ -291,16 +287,16 @@ int optee_open_session(struct tee_context *ctx,
291287int optee_close_session_helper (struct tee_context * ctx , u32 session )
292288{
293289 struct tee_shm * shm ;
290+ struct optee * optee = tee_get_drvdata (ctx -> teedev );
294291 struct optee_msg_arg * msg_arg ;
295- phys_addr_t msg_parg ;
296292
297- shm = get_msg_arg (ctx , 0 , & msg_arg , & msg_parg );
293+ shm = get_msg_arg (ctx , 0 , & msg_arg );
298294 if (IS_ERR (shm ))
299295 return PTR_ERR (shm );
300296
301297 msg_arg -> cmd = OPTEE_MSG_CMD_CLOSE_SESSION ;
302298 msg_arg -> session = session ;
303- optee_do_call_with_arg (ctx , msg_parg );
299+ optee -> ops -> do_call_with_arg (ctx , shm );
304300
305301 tee_shm_free (shm );
306302
@@ -328,10 +324,10 @@ int optee_close_session(struct tee_context *ctx, u32 session)
328324int optee_invoke_func (struct tee_context * ctx , struct tee_ioctl_invoke_arg * arg ,
329325 struct tee_param * param )
330326{
327+ struct optee * optee = tee_get_drvdata (ctx -> teedev );
331328 struct optee_context_data * ctxdata = ctx -> data ;
332329 struct tee_shm * shm ;
333330 struct optee_msg_arg * msg_arg ;
334- phys_addr_t msg_parg ;
335331 struct optee_session * sess ;
336332 int rc ;
337333
@@ -342,24 +338,26 @@ int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
342338 if (!sess )
343339 return - EINVAL ;
344340
345- shm = get_msg_arg (ctx , arg -> num_params , & msg_arg , & msg_parg );
341+ shm = get_msg_arg (ctx , arg -> num_params , & msg_arg );
346342 if (IS_ERR (shm ))
347343 return PTR_ERR (shm );
348344 msg_arg -> cmd = OPTEE_MSG_CMD_INVOKE_COMMAND ;
349345 msg_arg -> func = arg -> func ;
350346 msg_arg -> session = arg -> session ;
351347 msg_arg -> cancel_id = arg -> cancel_id ;
352348
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 );
354351 if (rc )
355352 goto out ;
356353
357- if (optee_do_call_with_arg (ctx , msg_parg )) {
354+ if (optee -> ops -> do_call_with_arg (ctx , shm )) {
358355 msg_arg -> ret = TEEC_ERROR_COMMUNICATION ;
359356 msg_arg -> ret_origin = TEEC_ORIGIN_COMMS ;
360357 }
361358
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 )) {
363361 msg_arg -> ret = TEEC_ERROR_COMMUNICATION ;
364362 msg_arg -> ret_origin = TEEC_ORIGIN_COMMS ;
365363 }
@@ -373,10 +371,10 @@ int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
373371
374372int optee_cancel_req (struct tee_context * ctx , u32 cancel_id , u32 session )
375373{
374+ struct optee * optee = tee_get_drvdata (ctx -> teedev );
376375 struct optee_context_data * ctxdata = ctx -> data ;
377376 struct tee_shm * shm ;
378377 struct optee_msg_arg * msg_arg ;
379- phys_addr_t msg_parg ;
380378 struct optee_session * sess ;
381379
382380 /* Check that the session is valid */
@@ -386,14 +384,14 @@ int optee_cancel_req(struct tee_context *ctx, u32 cancel_id, u32 session)
386384 if (!sess )
387385 return - EINVAL ;
388386
389- shm = get_msg_arg (ctx , 0 , & msg_arg , & msg_parg );
387+ shm = get_msg_arg (ctx , 0 , & msg_arg );
390388 if (IS_ERR (shm ))
391389 return PTR_ERR (shm );
392390
393391 msg_arg -> cmd = OPTEE_MSG_CMD_CANCEL ;
394392 msg_arg -> session = session ;
395393 msg_arg -> cancel_id = cancel_id ;
396- optee_do_call_with_arg (ctx , msg_parg );
394+ optee -> ops -> do_call_with_arg (ctx , shm );
397395
398396 tee_shm_free (shm );
399397 return 0 ;
@@ -622,10 +620,10 @@ int optee_shm_register(struct tee_context *ctx, struct tee_shm *shm,
622620 struct page * * pages , size_t num_pages ,
623621 unsigned long start )
624622{
625- struct tee_shm * shm_arg = NULL ;
623+ struct optee * optee = tee_get_drvdata ( ctx -> teedev ) ;
626624 struct optee_msg_arg * msg_arg ;
625+ struct tee_shm * shm_arg ;
627626 u64 * pages_list ;
628- phys_addr_t msg_parg ;
629627 int rc ;
630628
631629 if (!num_pages )
@@ -639,7 +637,7 @@ int optee_shm_register(struct tee_context *ctx, struct tee_shm *shm,
639637 if (!pages_list )
640638 return - ENOMEM ;
641639
642- shm_arg = get_msg_arg (ctx , 1 , & msg_arg , & msg_parg );
640+ shm_arg = get_msg_arg (ctx , 1 , & msg_arg );
643641 if (IS_ERR (shm_arg )) {
644642 rc = PTR_ERR (shm_arg );
645643 goto out ;
@@ -660,7 +658,7 @@ int optee_shm_register(struct tee_context *ctx, struct tee_shm *shm,
660658 msg_arg -> params -> u .tmem .buf_ptr = virt_to_phys (pages_list ) |
661659 (tee_shm_get_page_offset (shm ) & (OPTEE_MSG_NONCONTIG_PAGE_SIZE - 1 ));
662660
663- if (optee_do_call_with_arg (ctx , msg_parg ) ||
661+ if (optee -> ops -> do_call_with_arg (ctx , shm_arg ) ||
664662 msg_arg -> ret != TEEC_SUCCESS )
665663 rc = - EINVAL ;
666664
@@ -672,12 +670,12 @@ int optee_shm_register(struct tee_context *ctx, struct tee_shm *shm,
672670
673671int optee_shm_unregister (struct tee_context * ctx , struct tee_shm * shm )
674672{
675- struct tee_shm * shm_arg ;
673+ struct optee * optee = tee_get_drvdata ( ctx -> teedev ) ;
676674 struct optee_msg_arg * msg_arg ;
677- phys_addr_t msg_parg ;
675+ struct tee_shm * shm_arg ;
678676 int rc = 0 ;
679677
680- shm_arg = get_msg_arg (ctx , 1 , & msg_arg , & msg_parg );
678+ shm_arg = get_msg_arg (ctx , 1 , & msg_arg );
681679 if (IS_ERR (shm_arg ))
682680 return PTR_ERR (shm_arg );
683681
@@ -686,7 +684,7 @@ int optee_shm_unregister(struct tee_context *ctx, struct tee_shm *shm)
686684 msg_arg -> params [0 ].attr = OPTEE_MSG_ATTR_TYPE_RMEM_INPUT ;
687685 msg_arg -> params [0 ].u .rmem .shm_ref = (unsigned long )shm ;
688686
689- if (optee_do_call_with_arg (ctx , msg_parg ) ||
687+ if (optee -> ops -> do_call_with_arg (ctx , shm_arg ) ||
690688 msg_arg -> ret != TEEC_SUCCESS )
691689 rc = - EINVAL ;
692690 tee_shm_free (shm_arg );
0 commit comments