@@ -1117,6 +1117,7 @@ static int ffa_memory_lend(struct ffa_mem_ops_args *args)
11171117struct notifier_cb_info {
11181118 struct hlist_node hnode ;
11191119 struct ffa_device * dev ;
1120+ ffa_fwk_notifier_cb fwk_cb ;
11201121 ffa_notifier_cb cb ;
11211122 void * cb_data ;
11221123};
@@ -1180,28 +1181,61 @@ static enum notify_type ffa_notify_type_get(u16 vm_id)
11801181 return NON_SECURE_VM ;
11811182}
11821183
1183- /* Should be called while the notify_lock is taken */
1184+ /* notifier_hnode_get* should be called with notify_lock held */
11841185static struct notifier_cb_info *
1185- notifier_hash_node_get (u16 notify_id , enum notify_type type )
1186+ notifier_hnode_get_by_vmid (u16 notify_id , int vmid )
11861187{
11871188 struct notifier_cb_info * node ;
11881189
11891190 hash_for_each_possible (drv_info -> notifier_hash , node , hnode , notify_id )
1190- if (type == ffa_notify_type_get (node -> dev -> vm_id ))
1191+ if (node -> fwk_cb && vmid == node -> dev -> vm_id )
1192+ return node ;
1193+
1194+ return NULL ;
1195+ }
1196+
1197+ static struct notifier_cb_info *
1198+ notifier_hnode_get_by_vmid_uuid (u16 notify_id , int vmid , const uuid_t * uuid )
1199+ {
1200+ struct notifier_cb_info * node ;
1201+
1202+ if (uuid_is_null (uuid ))
1203+ return notifier_hnode_get_by_vmid (notify_id , vmid );
1204+
1205+ hash_for_each_possible (drv_info -> notifier_hash , node , hnode , notify_id )
1206+ if (node -> fwk_cb && vmid == node -> dev -> vm_id &&
1207+ uuid_equal (& node -> dev -> uuid , uuid ))
1208+ return node ;
1209+
1210+ return NULL ;
1211+ }
1212+
1213+ static struct notifier_cb_info *
1214+ notifier_hnode_get_by_type (u16 notify_id , enum notify_type type )
1215+ {
1216+ struct notifier_cb_info * node ;
1217+
1218+ hash_for_each_possible (drv_info -> notifier_hash , node , hnode , notify_id )
1219+ if (node -> cb && type == ffa_notify_type_get (node -> dev -> vm_id ))
11911220 return node ;
11921221
11931222 return NULL ;
11941223}
11951224
11961225static int
1197- update_notifier_cb (struct ffa_device * dev , int notify_id , ffa_notifier_cb cb ,
1198- void * cb_data , bool is_registration )
1226+ update_notifier_cb (struct ffa_device * dev , int notify_id , void * cb ,
1227+ void * cb_data , bool is_registration , bool is_framework )
11991228{
12001229 struct notifier_cb_info * cb_info = NULL ;
12011230 enum notify_type type = ffa_notify_type_get (dev -> vm_id );
12021231 bool cb_found ;
12031232
1204- cb_info = notifier_hash_node_get (notify_id , type );
1233+ if (is_framework )
1234+ cb_info = notifier_hnode_get_by_vmid_uuid (notify_id , dev -> vm_id ,
1235+ & dev -> uuid );
1236+ else
1237+ cb_info = notifier_hnode_get_by_type (notify_id , type );
1238+
12051239 cb_found = !!cb_info ;
12061240
12071241 if (!(is_registration ^ cb_found ))
@@ -1213,8 +1247,11 @@ update_notifier_cb(struct ffa_device *dev, int notify_id, ffa_notifier_cb cb,
12131247 return - ENOMEM ;
12141248
12151249 cb_info -> dev = dev ;
1216- cb_info -> cb = cb ;
12171250 cb_info -> cb_data = cb_data ;
1251+ if (is_framework )
1252+ cb_info -> fwk_cb = cb ;
1253+ else
1254+ cb_info -> cb = cb ;
12181255
12191256 hash_add (drv_info -> notifier_hash , & cb_info -> hnode , notify_id );
12201257 } else {
@@ -1224,7 +1261,8 @@ update_notifier_cb(struct ffa_device *dev, int notify_id, ffa_notifier_cb cb,
12241261 return 0 ;
12251262}
12261263
1227- static int ffa_notify_relinquish (struct ffa_device * dev , int notify_id )
1264+ static int __ffa_notify_relinquish (struct ffa_device * dev , int notify_id ,
1265+ bool is_framework )
12281266{
12291267 int rc ;
12301268
@@ -1236,22 +1274,35 @@ static int ffa_notify_relinquish(struct ffa_device *dev, int notify_id)
12361274
12371275 mutex_lock (& drv_info -> notify_lock );
12381276
1239- rc = update_notifier_cb (dev , notify_id , NULL , NULL , false);
1277+ rc = update_notifier_cb (dev , notify_id , NULL , NULL , false,
1278+ is_framework );
12401279 if (rc ) {
12411280 pr_err ("Could not unregister notification callback\n" );
12421281 mutex_unlock (& drv_info -> notify_lock );
12431282 return rc ;
12441283 }
12451284
1246- rc = ffa_notification_unbind (dev -> vm_id , BIT (notify_id ));
1285+ if (!is_framework )
1286+ rc = ffa_notification_unbind (dev -> vm_id , BIT (notify_id ));
12471287
12481288 mutex_unlock (& drv_info -> notify_lock );
12491289
12501290 return rc ;
12511291}
12521292
1253- static int ffa_notify_request (struct ffa_device * dev , bool is_per_vcpu ,
1254- ffa_notifier_cb cb , void * cb_data , int notify_id )
1293+ static int ffa_notify_relinquish (struct ffa_device * dev , int notify_id )
1294+ {
1295+ return __ffa_notify_relinquish (dev , notify_id , false);
1296+ }
1297+
1298+ static int ffa_fwk_notify_relinquish (struct ffa_device * dev , int notify_id )
1299+ {
1300+ return __ffa_notify_relinquish (dev , notify_id , true);
1301+ }
1302+
1303+ static int __ffa_notify_request (struct ffa_device * dev , bool is_per_vcpu ,
1304+ void * cb , void * cb_data ,
1305+ int notify_id , bool is_framework )
12551306{
12561307 int rc ;
12571308 u32 flags = 0 ;
@@ -1264,26 +1315,44 @@ static int ffa_notify_request(struct ffa_device *dev, bool is_per_vcpu,
12641315
12651316 mutex_lock (& drv_info -> notify_lock );
12661317
1267- if (is_per_vcpu )
1268- flags = PER_VCPU_NOTIFICATION_FLAG ;
1318+ if (!is_framework ) {
1319+ if (is_per_vcpu )
1320+ flags = PER_VCPU_NOTIFICATION_FLAG ;
12691321
1270- rc = ffa_notification_bind (dev -> vm_id , BIT (notify_id ), flags );
1271- if (rc ) {
1272- mutex_unlock (& drv_info -> notify_lock );
1273- return rc ;
1322+ rc = ffa_notification_bind (dev -> vm_id , BIT (notify_id ), flags );
1323+ if (rc ) {
1324+ mutex_unlock (& drv_info -> notify_lock );
1325+ return rc ;
1326+ }
12741327 }
12751328
1276- rc = update_notifier_cb (dev , notify_id , cb , cb_data , true);
1329+ rc = update_notifier_cb (dev , notify_id , cb , cb_data , true,
1330+ is_framework );
12771331 if (rc ) {
12781332 pr_err ("Failed to register callback for %d - %d\n" ,
12791333 notify_id , rc );
1280- ffa_notification_unbind (dev -> vm_id , BIT (notify_id ));
1334+ if (!is_framework )
1335+ ffa_notification_unbind (dev -> vm_id , BIT (notify_id ));
12811336 }
12821337 mutex_unlock (& drv_info -> notify_lock );
12831338
12841339 return rc ;
12851340}
12861341
1342+ static int ffa_notify_request (struct ffa_device * dev , bool is_per_vcpu ,
1343+ ffa_notifier_cb cb , void * cb_data , int notify_id )
1344+ {
1345+ return __ffa_notify_request (dev , is_per_vcpu , cb , cb_data , notify_id ,
1346+ false);
1347+ }
1348+
1349+ static int
1350+ ffa_fwk_notify_request (struct ffa_device * dev , ffa_fwk_notifier_cb cb ,
1351+ void * cb_data , int notify_id )
1352+ {
1353+ return __ffa_notify_request (dev , false, cb , cb_data , notify_id , true);
1354+ }
1355+
12871356static int ffa_notify_send (struct ffa_device * dev , int notify_id ,
12881357 bool is_per_vcpu , u16 vcpu )
12891358{
@@ -1313,7 +1382,7 @@ static void handle_notif_callbacks(u64 bitmap, enum notify_type type)
13131382 continue ;
13141383
13151384 mutex_lock (& drv_info -> notify_lock );
1316- cb_info = notifier_hash_node_get (notify_id , type );
1385+ cb_info = notifier_hnode_get_by_type (notify_id , type );
13171386 mutex_unlock (& drv_info -> notify_lock );
13181387
13191388 if (cb_info && cb_info -> cb )
@@ -1386,6 +1455,8 @@ static const struct ffa_notifier_ops ffa_drv_notifier_ops = {
13861455 .sched_recv_cb_unregister = ffa_sched_recv_cb_unregister ,
13871456 .notify_request = ffa_notify_request ,
13881457 .notify_relinquish = ffa_notify_relinquish ,
1458+ .fwk_notify_request = ffa_fwk_notify_request ,
1459+ .fwk_notify_relinquish = ffa_fwk_notify_relinquish ,
13891460 .notify_send = ffa_notify_send ,
13901461};
13911462
0 commit comments