1717#include <linux/rpmsg.h>
1818#include <linux/scatterlist.h>
1919#include <linux/slab.h>
20+ #include <linux/qcom_scm.h>
2021#include <uapi/misc/fastrpc.h>
2122
2223#define ADSP_DOMAIN_ID (0)
2526#define CDSP_DOMAIN_ID (3)
2627#define FASTRPC_DEV_MAX 4 /* adsp, mdsp, slpi, cdsp*/
2728#define FASTRPC_MAX_SESSIONS 13 /*12 compute, 1 cpz*/
29+ #define FASTRPC_MAX_VMIDS 16
2830#define FASTRPC_ALIGN 128
2931#define FASTRPC_MAX_FDLIST 16
3032#define FASTRPC_MAX_CRCLIST 64
@@ -195,6 +197,7 @@ struct fastrpc_map {
195197 void * va ;
196198 u64 len ;
197199 u64 raddr ;
200+ u32 attr ;
198201 struct kref refcount ;
199202};
200203
@@ -232,6 +235,9 @@ struct fastrpc_session_ctx {
232235struct fastrpc_channel_ctx {
233236 int domain_id ;
234237 int sesscount ;
238+ int vmcount ;
239+ u32 perms ;
240+ struct qcom_scm_vmperm vmperms [FASTRPC_MAX_VMIDS ];
235241 struct rpmsg_device * rpdev ;
236242 struct fastrpc_session_ctx session [FASTRPC_MAX_SESSIONS ];
237243 spinlock_t lock ;
@@ -279,6 +285,20 @@ static void fastrpc_free_map(struct kref *ref)
279285 map = container_of (ref , struct fastrpc_map , refcount );
280286
281287 if (map -> table ) {
288+ if (map -> attr & FASTRPC_ATTR_SECUREMAP ) {
289+ struct qcom_scm_vmperm perm ;
290+ int err = 0 ;
291+
292+ perm .vmid = QCOM_SCM_VMID_HLOS ;
293+ perm .perm = QCOM_SCM_PERM_RWX ;
294+ err = qcom_scm_assign_mem (map -> phys , map -> size ,
295+ & (map -> fl -> cctx -> vmperms [0 ].vmid ), & perm , 1 );
296+ if (err ) {
297+ dev_err (map -> fl -> sctx -> dev , "Failed to assign memory phys 0x%llx size 0x%llx err %d" ,
298+ map -> phys , map -> size , err );
299+ return ;
300+ }
301+ }
282302 dma_buf_unmap_attachment (map -> attach , map -> table ,
283303 DMA_BIDIRECTIONAL );
284304 dma_buf_detach (map -> buf , map -> attach );
@@ -655,7 +675,7 @@ static const struct dma_buf_ops fastrpc_dma_buf_ops = {
655675};
656676
657677static int fastrpc_map_create (struct fastrpc_user * fl , int fd ,
658- u64 len , struct fastrpc_map * * ppmap )
678+ u64 len , u32 attr , struct fastrpc_map * * ppmap )
659679{
660680 struct fastrpc_session_ctx * sess = fl -> sctx ;
661681 struct fastrpc_map * map = NULL ;
@@ -697,6 +717,22 @@ static int fastrpc_map_create(struct fastrpc_user *fl, int fd,
697717 map -> len = len ;
698718 kref_init (& map -> refcount );
699719
720+ if (attr & FASTRPC_ATTR_SECUREMAP ) {
721+ /*
722+ * If subsystem VMIDs are defined in DTSI, then do
723+ * hyp_assign from HLOS to those VM(s)
724+ */
725+ unsigned int perms = BIT (QCOM_SCM_VMID_HLOS );
726+
727+ map -> attr = attr ;
728+ err = qcom_scm_assign_mem (map -> phys , (u64 )map -> size , & perms ,
729+ fl -> cctx -> vmperms , fl -> cctx -> vmcount );
730+ if (err ) {
731+ dev_err (sess -> dev , "Failed to assign memory with phys 0x%llx size 0x%llx err %d" ,
732+ map -> phys , map -> size , err );
733+ goto map_err ;
734+ }
735+ }
700736 spin_lock (& fl -> lock );
701737 list_add_tail (& map -> node , & fl -> maps );
702738 spin_unlock (& fl -> lock );
@@ -781,16 +817,13 @@ static int fastrpc_create_maps(struct fastrpc_invoke_ctx *ctx)
781817 int i , err ;
782818
783819 for (i = 0 ; i < ctx -> nscalars ; ++ i ) {
784- /* Make sure reserved field is set to 0 */
785- if (ctx -> args [i ].reserved )
786- return - EINVAL ;
787820
788821 if (ctx -> args [i ].fd == 0 || ctx -> args [i ].fd == -1 ||
789822 ctx -> args [i ].length == 0 )
790823 continue ;
791824
792825 err = fastrpc_map_create (ctx -> fl , ctx -> args [i ].fd ,
793- ctx -> args [i ].length , & ctx -> maps [i ]);
826+ ctx -> args [i ].length , ctx -> args [ i ]. attr , & ctx -> maps [i ]);
794827 if (err ) {
795828 dev_err (dev , "Error Creating map %d\n" , err );
796829 return - EINVAL ;
@@ -1124,7 +1157,7 @@ static int fastrpc_init_create_process(struct fastrpc_user *fl,
11241157 fl -> pd = USER_PD ;
11251158
11261159 if (init .filelen && init .filefd ) {
1127- err = fastrpc_map_create (fl , init .filefd , init .filelen , & map );
1160+ err = fastrpc_map_create (fl , init .filefd , init .filelen , 0 , & map );
11281161 if (err )
11291162 goto err ;
11301163 }
@@ -1233,7 +1266,6 @@ static int fastrpc_release_current_dsp_process(struct fastrpc_user *fl)
12331266 args [0 ].ptr = (u64 )(uintptr_t ) & tgid ;
12341267 args [0 ].length = sizeof (tgid );
12351268 args [0 ].fd = -1 ;
1236- args [0 ].reserved = 0 ;
12371269 sc = FASTRPC_SCALARS (FASTRPC_RMID_INIT_RELEASE , 1 , 0 );
12381270
12391271 return fastrpc_internal_invoke (fl , true, FASTRPC_INIT_HANDLE ,
@@ -1381,7 +1413,6 @@ static int fastrpc_init_attach(struct fastrpc_user *fl, int pd)
13811413 args [0 ].ptr = (u64 )(uintptr_t ) & tgid ;
13821414 args [0 ].length = sizeof (tgid );
13831415 args [0 ].fd = -1 ;
1384- args [0 ].reserved = 0 ;
13851416 sc = FASTRPC_SCALARS (FASTRPC_RMID_INIT_ATTACH , 1 , 0 );
13861417 fl -> pd = pd ;
13871418
@@ -1954,9 +1985,10 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev)
19541985{
19551986 struct device * rdev = & rpdev -> dev ;
19561987 struct fastrpc_channel_ctx * data ;
1957- int i , err , domain_id = -1 ;
1988+ int i , err , domain_id = -1 , vmcount ;
19581989 const char * domain ;
19591990 bool secure_dsp ;
1991+ unsigned int vmids [FASTRPC_MAX_VMIDS ];
19601992
19611993 err = of_property_read_string (rdev -> of_node , "label" , & domain );
19621994 if (err ) {
@@ -1976,10 +2008,25 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev)
19762008 return - EINVAL ;
19772009 }
19782010
2011+ vmcount = of_property_read_variable_u32_array (rdev -> of_node ,
2012+ "qcom,vmids" , & vmids [0 ], 0 , FASTRPC_MAX_VMIDS );
2013+ if (vmcount < 0 )
2014+ vmcount = 0 ;
2015+ else if (!qcom_scm_is_available ())
2016+ return - EPROBE_DEFER ;
2017+
19792018 data = kzalloc (sizeof (* data ), GFP_KERNEL );
19802019 if (!data )
19812020 return - ENOMEM ;
19822021
2022+ if (vmcount ) {
2023+ data -> vmcount = vmcount ;
2024+ data -> perms = BIT (QCOM_SCM_VMID_HLOS );
2025+ for (i = 0 ; i < data -> vmcount ; i ++ ) {
2026+ data -> vmperms [i ].vmid = vmids [i ];
2027+ data -> vmperms [i ].perm = QCOM_SCM_PERM_RWX ;
2028+ }
2029+ }
19832030
19842031 secure_dsp = !(of_property_read_bool (rdev -> of_node , "qcom,non-secure-domain" ));
19852032 data -> secure = secure_dsp ;
0 commit comments