@@ -197,6 +197,8 @@ struct fastrpc_buf {
197197 struct dma_buf * dmabuf ;
198198 struct device * dev ;
199199 void * virt ;
200+ /* Type of buffer */
201+ u32 flag ;
200202 u64 phys ;
201203 u64 size ;
202204 /* Lock for dma buf attachments */
@@ -273,10 +275,12 @@ struct fastrpc_channel_ctx {
273275 struct kref refcount ;
274276 /* Flag if dsp attributes are cached */
275277 bool valid_attributes ;
278+ /* Flag if audio PD init mem was allocated */
279+ bool audio_init_mem ;
276280 u32 dsp_attributes [FASTRPC_MAX_DSP_ATTRIBUTES ];
277281 struct fastrpc_device * secure_fdevice ;
278282 struct fastrpc_device * fdevice ;
279- struct fastrpc_buf * remote_heap ;
283+ struct list_head rhmaps ;
280284 struct list_head invoke_interrupted_mmaps ;
281285 bool secure ;
282286 bool unsigned_support ;
@@ -394,6 +398,9 @@ static int fastrpc_map_lookup(struct fastrpc_user *fl, int fd,
394398
395399static void fastrpc_buf_free (struct fastrpc_buf * buf )
396400{
401+ if (!buf )
402+ return ;
403+
397404 dma_free_coherent (buf -> dev , buf -> size , buf -> virt ,
398405 FASTRPC_PHYS (buf -> phys ));
399406 kfree (buf );
@@ -1234,12 +1241,47 @@ static bool is_session_rejected(struct fastrpc_user *fl, bool unsigned_pd_reques
12341241 return false;
12351242}
12361243
1244+ static void fastrpc_cleanup_rhmaps (struct fastrpc_channel_ctx * cctx )
1245+ {
1246+ struct fastrpc_buf * buf , * b ;
1247+ struct list_head temp_list ;
1248+ int err ;
1249+ unsigned long flags ;
1250+
1251+ INIT_LIST_HEAD (& temp_list );
1252+
1253+ spin_lock_irqsave (& cctx -> lock , flags );
1254+ list_splice_init (& cctx -> rhmaps , & temp_list );
1255+ spin_unlock_irqrestore (& cctx -> lock , flags );
1256+
1257+ list_for_each_entry_safe (buf , b , & temp_list , node ) {
1258+ if (cctx -> vmcount ) {
1259+ u64 src_perms = 0 ;
1260+ struct qcom_scm_vmperm dst_perms ;
1261+ u32 i ;
1262+
1263+ for (i = 0 ; i < cctx -> vmcount ; i ++ )
1264+ src_perms |= BIT (cctx -> vmperms [i ].vmid );
1265+
1266+ dst_perms .vmid = QCOM_SCM_VMID_HLOS ;
1267+ dst_perms .perm = QCOM_SCM_PERM_RWX ;
1268+ err = qcom_scm_assign_mem (buf -> phys , (u64 )buf -> size ,
1269+ & src_perms , & dst_perms , 1 );
1270+ if (err )
1271+ continue ;
1272+ }
1273+ fastrpc_buf_free (buf );
1274+ }
1275+ }
1276+
12371277static int fastrpc_init_create_static_process (struct fastrpc_user * fl ,
12381278 char __user * argp )
12391279{
12401280 struct fastrpc_init_create_static init ;
12411281 struct fastrpc_invoke_args * args ;
12421282 struct fastrpc_phy_page pages [1 ];
1283+ struct fastrpc_buf * buf = NULL ;
1284+ u64 phys = 0 , size = 0 ;
12431285 char * name ;
12441286 int err ;
12451287 bool scm_done = false;
@@ -1249,6 +1291,7 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
12491291 u32 pageslen ;
12501292 } inbuf ;
12511293 u32 sc ;
1294+ unsigned long flags ;
12521295
12531296 args = kcalloc (FASTRPC_CREATE_STATIC_PROCESS_NARGS , sizeof (* args ), GFP_KERNEL );
12541297 if (!args )
@@ -1270,32 +1313,37 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
12701313 goto err ;
12711314 }
12721315
1273- if (!fl -> cctx -> remote_heap ) {
1316+ inbuf .client_id = fl -> client_id ;
1317+ inbuf .namelen = init .namelen ;
1318+ inbuf .pageslen = 0 ;
1319+ if (!fl -> cctx -> audio_init_mem ) {
12741320 err = fastrpc_remote_heap_alloc (fl , fl -> sctx -> dev , init .memlen ,
1275- & fl -> cctx -> remote_heap );
1321+ & buf );
12761322 if (err )
12771323 goto err_name ;
12781324
1325+ phys = buf -> phys ;
1326+ size = buf -> size ;
12791327 /* Map if we have any heap VMIDs associated with this ADSP Static Process. */
12801328 if (fl -> cctx -> vmcount ) {
12811329 u64 src_perms = BIT (QCOM_SCM_VMID_HLOS );
12821330
1283- err = qcom_scm_assign_mem (fl -> cctx -> remote_heap -> phys ,
1284- (u64 )fl -> cctx -> remote_heap -> size ,
1285- & src_perms ,
1286- fl -> cctx -> vmperms , fl -> cctx -> vmcount );
1331+ err = qcom_scm_assign_mem (phys , size , & src_perms ,
1332+ fl -> cctx -> vmperms , fl -> cctx -> vmcount );
12871333 if (err ) {
12881334 dev_err (fl -> sctx -> dev , "Failed to assign memory with phys 0x%llx size 0x%llx err %d\n" ,
1289- fl -> cctx -> remote_heap -> phys , fl -> cctx -> remote_heap -> size , err );
1335+ phys , size , err );
12901336 goto err_map ;
12911337 }
12921338 scm_done = true;
1339+ spin_lock_irqsave (& fl -> cctx -> lock , flags );
1340+ list_add_tail (& buf -> node , & fl -> cctx -> rhmaps );
1341+ spin_unlock_irqrestore (& fl -> cctx -> lock , flags );
1342+ fl -> cctx -> audio_init_mem = true;
1343+ inbuf .pageslen = 1 ;
12931344 }
12941345 }
12951346
1296- inbuf .client_id = fl -> client_id ;
1297- inbuf .namelen = init .namelen ;
1298- inbuf .pageslen = 0 ;
12991347 fl -> pd = USER_PD ;
13001348
13011349 args [0 ].ptr = (u64 )(uintptr_t )& inbuf ;
@@ -1306,8 +1354,8 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
13061354 args [1 ].length = inbuf .namelen ;
13071355 args [1 ].fd = -1 ;
13081356
1309- pages [0 ].addr = fl -> cctx -> remote_heap -> phys ;
1310- pages [0 ].size = fl -> cctx -> remote_heap -> size ;
1357+ pages [0 ].addr = phys ;
1358+ pages [0 ].size = size ;
13111359
13121360 args [2 ].ptr = (u64 )(uintptr_t ) pages ;
13131361 args [2 ].length = sizeof (* pages );
@@ -1325,6 +1373,11 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
13251373
13261374 return 0 ;
13271375err_invoke :
1376+ if (buf ) {
1377+ spin_lock_irqsave (& fl -> cctx -> lock , flags );
1378+ list_del (& buf -> node );
1379+ spin_unlock_irqrestore (& fl -> cctx -> lock , flags );
1380+ }
13281381 if (fl -> cctx -> vmcount && scm_done ) {
13291382 u64 src_perms = 0 ;
13301383 struct qcom_scm_vmperm dst_perms ;
@@ -1335,15 +1388,15 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
13351388
13361389 dst_perms .vmid = QCOM_SCM_VMID_HLOS ;
13371390 dst_perms .perm = QCOM_SCM_PERM_RWX ;
1338- err = qcom_scm_assign_mem (fl -> cctx -> remote_heap -> phys ,
1339- (u64 )fl -> cctx -> remote_heap -> size ,
1340- & src_perms , & dst_perms , 1 );
1391+ err = qcom_scm_assign_mem (phys , size , & src_perms ,
1392+ & dst_perms , 1 );
13411393 if (err )
13421394 dev_err (fl -> sctx -> dev , "Failed to assign memory phys 0x%llx size 0x%llx err %d\n" ,
1343- fl -> cctx -> remote_heap -> phys , fl -> cctx -> remote_heap -> size , err );
1395+ phys , size , err );
13441396 }
13451397err_map :
1346- fastrpc_buf_free (fl -> cctx -> remote_heap );
1398+ fl -> cctx -> audio_init_mem = false;
1399+ fastrpc_buf_free (buf );
13471400err_name :
13481401 kfree (name );
13491402err :
@@ -1816,11 +1869,26 @@ static int fastrpc_req_munmap_impl(struct fastrpc_user *fl, struct fastrpc_buf *
18161869 err = fastrpc_internal_invoke (fl , true, FASTRPC_INIT_HANDLE , sc ,
18171870 & args [0 ]);
18181871 if (!err ) {
1819- dev_dbg (dev , "unmmap\tpt 0x%09lx OK\n" , buf -> raddr );
1820- spin_lock (& fl -> lock );
1821- list_del (& buf -> node );
1822- spin_unlock (& fl -> lock );
1872+ if (buf -> flag == ADSP_MMAP_REMOTE_HEAP_ADDR && fl -> cctx -> vmcount ) {
1873+ u64 src_perms = 0 ;
1874+ struct qcom_scm_vmperm dst_perms ;
1875+ u32 i ;
1876+
1877+ for (i = 0 ; i < fl -> cctx -> vmcount ; i ++ )
1878+ src_perms |= BIT (fl -> cctx -> vmperms [i ].vmid );
1879+
1880+ dst_perms .vmid = QCOM_SCM_VMID_HLOS ;
1881+ dst_perms .perm = QCOM_SCM_PERM_RWX ;
1882+ err = qcom_scm_assign_mem (buf -> phys , (u64 )buf -> size ,
1883+ & src_perms , & dst_perms , 1 );
1884+ if (err ) {
1885+ dev_err (fl -> sctx -> dev , "Failed to assign memory phys 0x%llx size 0x%llx err %d\n" ,
1886+ buf -> phys , buf -> size , err );
1887+ return err ;
1888+ }
1889+ }
18231890 fastrpc_buf_free (buf );
1891+ dev_dbg (dev , "unmmap\tpt 0x%09lx OK\n" , buf -> raddr );
18241892 } else {
18251893 dev_err (dev , "unmmap\tpt 0x%09lx ERROR\n" , buf -> raddr );
18261894 }
@@ -1833,26 +1901,54 @@ static int fastrpc_req_munmap(struct fastrpc_user *fl, char __user *argp)
18331901 struct fastrpc_buf * buf = NULL , * iter , * b ;
18341902 struct fastrpc_req_munmap req ;
18351903 struct device * dev = fl -> sctx -> dev ;
1904+ int err ;
1905+ unsigned long flags ;
18361906
18371907 if (copy_from_user (& req , argp , sizeof (req )))
18381908 return - EFAULT ;
18391909
18401910 spin_lock (& fl -> lock );
18411911 list_for_each_entry_safe (iter , b , & fl -> mmaps , node ) {
1842- if ((iter -> raddr == req .vaddrout ) && (iter -> size == req .size )) {
1912+ if (iter -> raddr == req .vaddrout && iter -> size == req .size ) {
1913+ list_del (& iter -> node );
18431914 buf = iter ;
18441915 break ;
18451916 }
18461917 }
18471918 spin_unlock (& fl -> lock );
18481919
1849- if (!buf ) {
1850- dev_err (dev , "mmap\t\tpt 0x%09llx [len 0x%08llx] not in list\n" ,
1851- req .vaddrout , req .size );
1852- return - EINVAL ;
1920+ if (buf ) {
1921+ err = fastrpc_req_munmap_impl (fl , buf );
1922+ if (err ) {
1923+ spin_lock (& fl -> lock );
1924+ list_add_tail (& buf -> node , & fl -> mmaps );
1925+ spin_unlock (& fl -> lock );
1926+ }
1927+ return err ;
1928+ }
1929+
1930+ spin_lock_irqsave (& fl -> cctx -> lock , flags );
1931+ list_for_each_entry_safe (iter , b , & fl -> cctx -> rhmaps , node ) {
1932+ if (iter -> raddr == req .vaddrout && iter -> size == req .size ) {
1933+ list_del (& iter -> node );
1934+ buf = iter ;
1935+ break ;
1936+ }
1937+ }
1938+ spin_unlock_irqrestore (& fl -> cctx -> lock , flags );
1939+ if (buf ) {
1940+ err = fastrpc_req_munmap_impl (fl , buf );
1941+ if (err ) {
1942+ spin_lock_irqsave (& fl -> cctx -> lock , flags );
1943+ list_add_tail (& buf -> node , & fl -> cctx -> rhmaps );
1944+ spin_unlock_irqrestore (& fl -> cctx -> lock , flags );
1945+ }
1946+ return err ;
18531947 }
1948+ dev_err (dev , "mmap\t\tpt 0x%09llx [len 0x%08llx] not in list\n" ,
1949+ req .vaddrout , req .size );
18541950
1855- return fastrpc_req_munmap_impl ( fl , buf ) ;
1951+ return - EINVAL ;
18561952}
18571953
18581954static int fastrpc_req_mmap (struct fastrpc_user * fl , char __user * argp )
@@ -1866,6 +1962,7 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp)
18661962 struct device * dev = fl -> sctx -> dev ;
18671963 int err ;
18681964 u32 sc ;
1965+ unsigned long flags ;
18691966
18701967 if (copy_from_user (& req , argp , sizeof (req )))
18711968 return - EFAULT ;
@@ -1919,6 +2016,7 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp)
19192016
19202017 /* update the buffer to be able to deallocate the memory on the DSP */
19212018 buf -> raddr = (uintptr_t ) rsp_msg .vaddr ;
2019+ buf -> flag = req .flags ;
19222020
19232021 /* let the client know the address to use */
19242022 req .vaddrout = rsp_msg .vaddr ;
@@ -1934,22 +2032,34 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp)
19342032 buf -> phys , buf -> size , err );
19352033 goto err_assign ;
19362034 }
2035+ spin_lock_irqsave (& fl -> cctx -> lock , flags );
2036+ list_add_tail (& buf -> node , & fl -> cctx -> rhmaps );
2037+ spin_unlock_irqrestore (& fl -> cctx -> lock , flags );
2038+ } else {
2039+ spin_lock (& fl -> lock );
2040+ list_add_tail (& buf -> node , & fl -> mmaps );
2041+ spin_unlock (& fl -> lock );
19372042 }
19382043
1939- spin_lock (& fl -> lock );
1940- list_add_tail (& buf -> node , & fl -> mmaps );
1941- spin_unlock (& fl -> lock );
1942-
19432044 if (copy_to_user ((void __user * )argp , & req , sizeof (req ))) {
19442045 err = - EFAULT ;
1945- goto err_assign ;
2046+ goto err_copy ;
19462047 }
19472048
19482049 dev_dbg (dev , "mmap\t\tpt 0x%09lx OK [len 0x%08llx]\n" ,
19492050 buf -> raddr , buf -> size );
19502051
19512052 return 0 ;
1952-
2053+ err_copy :
2054+ if (req .flags == ADSP_MMAP_REMOTE_HEAP_ADDR ) {
2055+ spin_lock_irqsave (& fl -> cctx -> lock , flags );
2056+ list_del (& buf -> node );
2057+ spin_unlock_irqrestore (& fl -> cctx -> lock , flags );
2058+ } else {
2059+ spin_lock (& fl -> lock );
2060+ list_del (& buf -> node );
2061+ spin_unlock (& fl -> lock );
2062+ }
19532063err_assign :
19542064 fastrpc_req_munmap_impl (fl , buf );
19552065
@@ -2359,6 +2469,7 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev)
23592469 rdev -> dma_mask = & data -> dma_mask ;
23602470 dma_set_mask_and_coherent (rdev , DMA_BIT_MASK (32 ));
23612471 INIT_LIST_HEAD (& data -> users );
2472+ INIT_LIST_HEAD (& data -> rhmaps );
23622473 INIT_LIST_HEAD (& data -> invoke_interrupted_mmaps );
23632474 spin_lock_init (& data -> lock );
23642475 idr_init (& data -> ctx_idr );
@@ -2417,8 +2528,7 @@ static void fastrpc_rpmsg_remove(struct rpmsg_device *rpdev)
24172528 list_for_each_entry_safe (buf , b , & cctx -> invoke_interrupted_mmaps , node )
24182529 list_del (& buf -> node );
24192530
2420- if (cctx -> remote_heap )
2421- fastrpc_buf_free (cctx -> remote_heap );
2531+ fastrpc_cleanup_rhmaps (cctx );
24222532
24232533 of_platform_depopulate (& rpdev -> dev );
24242534
0 commit comments