@@ -965,6 +965,70 @@ static int optee_smc_do_call_with_arg(struct tee_context *ctx,
965965 return rc ;
966966}
967967
968+ static int optee_smc_lend_protmem (struct optee * optee , struct tee_shm * protmem ,
969+ u32 * mem_attrs , unsigned int ma_count ,
970+ u32 use_case )
971+ {
972+ struct optee_shm_arg_entry * entry ;
973+ struct optee_msg_arg * msg_arg ;
974+ struct tee_shm * shm ;
975+ u_int offs ;
976+ int rc ;
977+
978+ msg_arg = optee_get_msg_arg (optee -> ctx , 2 , & entry , & shm , & offs );
979+ if (IS_ERR (msg_arg ))
980+ return PTR_ERR (msg_arg );
981+
982+ msg_arg -> cmd = OPTEE_MSG_CMD_LEND_PROTMEM ;
983+ msg_arg -> params [0 ].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT ;
984+ msg_arg -> params [0 ].u .value .a = use_case ;
985+ msg_arg -> params [1 ].attr = OPTEE_MSG_ATTR_TYPE_TMEM_INPUT ;
986+ msg_arg -> params [1 ].u .tmem .buf_ptr = protmem -> paddr ;
987+ msg_arg -> params [1 ].u .tmem .size = protmem -> size ;
988+ msg_arg -> params [1 ].u .tmem .shm_ref = (u_long )protmem ;
989+
990+ rc = optee -> ops -> do_call_with_arg (optee -> ctx , shm , offs , false);
991+ if (rc )
992+ goto out ;
993+ if (msg_arg -> ret != TEEC_SUCCESS ) {
994+ rc = - EINVAL ;
995+ goto out ;
996+ }
997+ protmem -> sec_world_id = (u_long )protmem ;
998+
999+ out :
1000+ optee_free_msg_arg (optee -> ctx , entry , offs );
1001+ return rc ;
1002+ }
1003+
1004+ static int optee_smc_reclaim_protmem (struct optee * optee ,
1005+ struct tee_shm * protmem )
1006+ {
1007+ struct optee_shm_arg_entry * entry ;
1008+ struct optee_msg_arg * msg_arg ;
1009+ struct tee_shm * shm ;
1010+ u_int offs ;
1011+ int rc ;
1012+
1013+ msg_arg = optee_get_msg_arg (optee -> ctx , 1 , & entry , & shm , & offs );
1014+ if (IS_ERR (msg_arg ))
1015+ return PTR_ERR (msg_arg );
1016+
1017+ msg_arg -> cmd = OPTEE_MSG_CMD_RECLAIM_PROTMEM ;
1018+ msg_arg -> params [0 ].attr = OPTEE_MSG_ATTR_TYPE_RMEM_INPUT ;
1019+ msg_arg -> params [0 ].u .rmem .shm_ref = (u_long )protmem ;
1020+
1021+ rc = optee -> ops -> do_call_with_arg (optee -> ctx , shm , offs , false);
1022+ if (rc )
1023+ goto out ;
1024+ if (msg_arg -> ret != TEEC_SUCCESS )
1025+ rc = - EINVAL ;
1026+
1027+ out :
1028+ optee_free_msg_arg (optee -> ctx , entry , offs );
1029+ return rc ;
1030+ }
1031+
9681032/*
9691033 * 5. Asynchronous notification
9701034 */
@@ -1216,6 +1280,8 @@ static const struct optee_ops optee_ops = {
12161280 .do_call_with_arg = optee_smc_do_call_with_arg ,
12171281 .to_msg_param = optee_to_msg_param ,
12181282 .from_msg_param = optee_from_msg_param ,
1283+ .lend_protmem = optee_smc_lend_protmem ,
1284+ .reclaim_protmem = optee_smc_reclaim_protmem ,
12191285};
12201286
12211287static int enable_async_notif (optee_invoke_fn * invoke_fn )
@@ -1627,14 +1693,20 @@ static struct tee_protmem_pool *static_protmem_pool_init(struct optee *optee)
16271693
16281694static int optee_protmem_pool_init (struct optee * optee )
16291695{
1696+ bool protm = optee -> smc .sec_caps & OPTEE_SMC_SEC_CAP_PROTMEM ;
1697+ bool dyn_protm = optee -> smc .sec_caps &
1698+ OPTEE_SMC_SEC_CAP_DYNAMIC_PROTMEM ;
16301699 enum tee_dma_heap_id heap_id = TEE_DMA_HEAP_SECURE_VIDEO_PLAY ;
16311700 struct tee_protmem_pool * pool = ERR_PTR (- EINVAL );
1632- int rc ;
1701+ int rc = - EINVAL ;
16331702
1634- if (!( optee -> smc . sec_caps & OPTEE_SMC_SEC_CAP_PROTMEM ) )
1703+ if (!protm && ! dyn_protm )
16351704 return 0 ;
16361705
1637- pool = static_protmem_pool_init (optee );
1706+ if (protm )
1707+ pool = static_protmem_pool_init (optee );
1708+ if (dyn_protm && IS_ERR (pool ))
1709+ pool = optee_protmem_alloc_dyn_pool (optee , heap_id );
16381710 if (IS_ERR (pool ))
16391711 return PTR_ERR (pool );
16401712
0 commit comments