@@ -649,6 +649,124 @@ static int optee_ffa_do_call_with_arg(struct tee_context *ctx,
649649 return optee_ffa_yielding_call (ctx , & data , rpc_arg , system_thread );
650650}
651651
652+ static int do_call_lend_protmem (struct optee * optee , u64 cookie , u32 use_case )
653+ {
654+ struct optee_shm_arg_entry * entry ;
655+ struct optee_msg_arg * msg_arg ;
656+ struct tee_shm * shm ;
657+ u_int offs ;
658+ int rc ;
659+
660+ msg_arg = optee_get_msg_arg (optee -> ctx , 1 , & entry , & shm , & offs );
661+ if (IS_ERR (msg_arg ))
662+ return PTR_ERR (msg_arg );
663+
664+ msg_arg -> cmd = OPTEE_MSG_CMD_ASSIGN_PROTMEM ;
665+ msg_arg -> params [0 ].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT ;
666+ msg_arg -> params [0 ].u .value .a = cookie ;
667+ msg_arg -> params [0 ].u .value .b = use_case ;
668+
669+ rc = optee -> ops -> do_call_with_arg (optee -> ctx , shm , offs , false);
670+ if (rc )
671+ goto out ;
672+ if (msg_arg -> ret != TEEC_SUCCESS ) {
673+ rc = - EINVAL ;
674+ goto out ;
675+ }
676+
677+ out :
678+ optee_free_msg_arg (optee -> ctx , entry , offs );
679+ return rc ;
680+ }
681+
682+ static int optee_ffa_lend_protmem (struct optee * optee , struct tee_shm * protmem ,
683+ u32 * mem_attrs , unsigned int ma_count ,
684+ u32 use_case )
685+ {
686+ struct ffa_device * ffa_dev = optee -> ffa .ffa_dev ;
687+ const struct ffa_mem_ops * mem_ops = ffa_dev -> ops -> mem_ops ;
688+ const struct ffa_msg_ops * msg_ops = ffa_dev -> ops -> msg_ops ;
689+ struct ffa_send_direct_data data ;
690+ struct ffa_mem_region_attributes * mem_attr ;
691+ struct ffa_mem_ops_args args = {
692+ .use_txbuf = true,
693+ .tag = use_case ,
694+ };
695+ struct page * page ;
696+ struct scatterlist sgl ;
697+ unsigned int n ;
698+ int rc ;
699+
700+ mem_attr = kcalloc (ma_count , sizeof (* mem_attr ), GFP_KERNEL );
701+ for (n = 0 ; n < ma_count ; n ++ ) {
702+ mem_attr [n ].receiver = mem_attrs [n ] & U16_MAX ;
703+ mem_attr [n ].attrs = mem_attrs [n ] >> 16 ;
704+ }
705+ args .attrs = mem_attr ;
706+ args .nattrs = ma_count ;
707+
708+ page = phys_to_page (protmem -> paddr );
709+ sg_init_table (& sgl , 1 );
710+ sg_set_page (& sgl , page , protmem -> size , 0 );
711+
712+ args .sg = & sgl ;
713+ rc = mem_ops -> memory_lend (& args );
714+ kfree (mem_attr );
715+ if (rc )
716+ return rc ;
717+
718+ rc = do_call_lend_protmem (optee , args .g_handle , use_case );
719+ if (rc )
720+ goto err_reclaim ;
721+
722+ rc = optee_shm_add_ffa_handle (optee , protmem , args .g_handle );
723+ if (rc )
724+ goto err_unreg ;
725+
726+ protmem -> sec_world_id = args .g_handle ;
727+
728+ return 0 ;
729+
730+ err_unreg :
731+ data = (struct ffa_send_direct_data ){
732+ .data0 = OPTEE_FFA_RELEASE_PROTMEM ,
733+ .data1 = (u32 )args .g_handle ,
734+ .data2 = (u32 )(args .g_handle >> 32 ),
735+ };
736+ msg_ops -> sync_send_receive (ffa_dev , & data );
737+ err_reclaim :
738+ mem_ops -> memory_reclaim (args .g_handle , 0 );
739+ return rc ;
740+ }
741+
742+ static int optee_ffa_reclaim_protmem (struct optee * optee ,
743+ struct tee_shm * protmem )
744+ {
745+ struct ffa_device * ffa_dev = optee -> ffa .ffa_dev ;
746+ const struct ffa_msg_ops * msg_ops = ffa_dev -> ops -> msg_ops ;
747+ const struct ffa_mem_ops * mem_ops = ffa_dev -> ops -> mem_ops ;
748+ u64 global_handle = protmem -> sec_world_id ;
749+ struct ffa_send_direct_data data = {
750+ .data0 = OPTEE_FFA_RELEASE_PROTMEM ,
751+ .data1 = (u32 )global_handle ,
752+ .data2 = (u32 )(global_handle >> 32 )
753+ };
754+ int rc ;
755+
756+ optee_shm_rem_ffa_handle (optee , global_handle );
757+ protmem -> sec_world_id = 0 ;
758+
759+ rc = msg_ops -> sync_send_receive (ffa_dev , & data );
760+ if (rc )
761+ pr_err ("Release SHM id 0x%llx rc %d\n" , global_handle , rc );
762+
763+ rc = mem_ops -> memory_reclaim (global_handle , 0 );
764+ if (rc )
765+ pr_err ("mem_reclaim: 0x%llx %d" , global_handle , rc );
766+
767+ return rc ;
768+ }
769+
652770/*
653771 * 6. Driver initialization
654772 *
@@ -819,6 +937,8 @@ static const struct optee_ops optee_ffa_ops = {
819937 .do_call_with_arg = optee_ffa_do_call_with_arg ,
820938 .to_msg_param = optee_ffa_to_msg_param ,
821939 .from_msg_param = optee_ffa_from_msg_param ,
940+ .lend_protmem = optee_ffa_lend_protmem ,
941+ .reclaim_protmem = optee_ffa_reclaim_protmem ,
822942};
823943
824944static void optee_ffa_remove (struct ffa_device * ffa_dev )
@@ -891,6 +1011,25 @@ static int optee_ffa_async_notif_init(struct ffa_device *ffa_dev,
8911011 return rc ;
8921012}
8931013
1014+ static int optee_ffa_protmem_pool_init (struct optee * optee , u32 sec_caps )
1015+ {
1016+ enum tee_dma_heap_id id = TEE_DMA_HEAP_SECURE_VIDEO_PLAY ;
1017+ struct tee_protmem_pool * pool ;
1018+ int rc = 0 ;
1019+
1020+ if (sec_caps & OPTEE_FFA_SEC_CAP_PROTMEM ) {
1021+ pool = optee_protmem_alloc_dyn_pool (optee , id );
1022+ if (IS_ERR (pool ))
1023+ return PTR_ERR (pool );
1024+
1025+ rc = tee_device_register_dma_heap (optee -> teedev , id , pool );
1026+ if (rc )
1027+ pool -> ops -> destroy_pool (pool );
1028+ }
1029+
1030+ return rc ;
1031+ }
1032+
8941033static int optee_ffa_probe (struct ffa_device * ffa_dev )
8951034{
8961035 const struct ffa_notifier_ops * notif_ops ;
@@ -941,7 +1080,7 @@ static int optee_ffa_probe(struct ffa_device *ffa_dev)
9411080 optee );
9421081 if (IS_ERR (teedev )) {
9431082 rc = PTR_ERR (teedev );
944- goto err_free_pool ;
1083+ goto err_free_shm_pool ;
9451084 }
9461085 optee -> teedev = teedev ;
9471086
@@ -988,6 +1127,9 @@ static int optee_ffa_probe(struct ffa_device *ffa_dev)
9881127 rc );
9891128 }
9901129
1130+ if (optee_ffa_protmem_pool_init (optee , sec_caps ))
1131+ pr_info ("Protected memory service not available\n" );
1132+
9911133 rc = optee_enumerate_devices (PTA_CMD_GET_DEVICES );
9921134 if (rc )
9931135 goto err_unregister_devices ;
@@ -1018,7 +1160,7 @@ static int optee_ffa_probe(struct ffa_device *ffa_dev)
10181160 tee_device_unregister (optee -> supp_teedev );
10191161err_unreg_teedev :
10201162 tee_device_unregister (optee -> teedev );
1021- err_free_pool :
1163+ err_free_shm_pool :
10221164 tee_shm_pool_free (pool );
10231165err_free_optee :
10241166 kfree (optee );
0 commit comments