@@ -504,6 +504,8 @@ static bool mock_domain_capable(struct device *dev, enum iommu_cap cap)
504504 return false;
505505}
506506
507+ static struct iopf_queue * mock_iommu_iopf_queue ;
508+
507509static struct iommu_device mock_iommu_device = {
508510};
509511
@@ -514,6 +516,29 @@ static struct iommu_device *mock_probe_device(struct device *dev)
514516 return & mock_iommu_device ;
515517}
516518
519+ static void mock_domain_page_response (struct device * dev , struct iopf_fault * evt ,
520+ struct iommu_page_response * msg )
521+ {
522+ }
523+
524+ static int mock_dev_enable_feat (struct device * dev , enum iommu_dev_features feat )
525+ {
526+ if (feat != IOMMU_DEV_FEAT_IOPF || !mock_iommu_iopf_queue )
527+ return - ENODEV ;
528+
529+ return iopf_queue_add_device (mock_iommu_iopf_queue , dev );
530+ }
531+
532+ static int mock_dev_disable_feat (struct device * dev , enum iommu_dev_features feat )
533+ {
534+ if (feat != IOMMU_DEV_FEAT_IOPF || !mock_iommu_iopf_queue )
535+ return - ENODEV ;
536+
537+ iopf_queue_remove_device (mock_iommu_iopf_queue , dev );
538+
539+ return 0 ;
540+ }
541+
517542static const struct iommu_ops mock_ops = {
518543 /*
519544 * IOMMU_DOMAIN_BLOCKED cannot be returned from def_domain_type()
@@ -529,6 +554,10 @@ static const struct iommu_ops mock_ops = {
529554 .capable = mock_domain_capable ,
530555 .device_group = generic_device_group ,
531556 .probe_device = mock_probe_device ,
557+ .page_response = mock_domain_page_response ,
558+ .dev_enable_feat = mock_dev_enable_feat ,
559+ .dev_disable_feat = mock_dev_disable_feat ,
560+ .user_pasid_table = true,
532561 .default_domain_ops =
533562 & (struct iommu_domain_ops ){
534563 .free = mock_domain_free ,
@@ -1375,6 +1404,31 @@ static int iommufd_test_dirty(struct iommufd_ucmd *ucmd, unsigned int mockpt_id,
13751404 return rc ;
13761405}
13771406
1407+ static int iommufd_test_trigger_iopf (struct iommufd_ucmd * ucmd ,
1408+ struct iommu_test_cmd * cmd )
1409+ {
1410+ struct iopf_fault event = { };
1411+ struct iommufd_device * idev ;
1412+
1413+ idev = iommufd_get_device (ucmd , cmd -> trigger_iopf .dev_id );
1414+ if (IS_ERR (idev ))
1415+ return PTR_ERR (idev );
1416+
1417+ event .fault .prm .flags = IOMMU_FAULT_PAGE_REQUEST_LAST_PAGE ;
1418+ if (cmd -> trigger_iopf .pasid != IOMMU_NO_PASID )
1419+ event .fault .prm .flags |= IOMMU_FAULT_PAGE_REQUEST_PASID_VALID ;
1420+ event .fault .type = IOMMU_FAULT_PAGE_REQ ;
1421+ event .fault .prm .addr = cmd -> trigger_iopf .addr ;
1422+ event .fault .prm .pasid = cmd -> trigger_iopf .pasid ;
1423+ event .fault .prm .grpid = cmd -> trigger_iopf .grpid ;
1424+ event .fault .prm .perm = cmd -> trigger_iopf .perm ;
1425+
1426+ iommu_report_device_fault (idev -> dev , & event );
1427+ iommufd_put_object (ucmd -> ictx , & idev -> obj );
1428+
1429+ return 0 ;
1430+ }
1431+
13781432void iommufd_selftest_destroy (struct iommufd_object * obj )
13791433{
13801434 struct selftest_obj * sobj = container_of (obj , struct selftest_obj , obj );
@@ -1450,6 +1504,8 @@ int iommufd_test(struct iommufd_ucmd *ucmd)
14501504 cmd -> dirty .page_size ,
14511505 u64_to_user_ptr (cmd -> dirty .uptr ),
14521506 cmd -> dirty .flags );
1507+ case IOMMU_TEST_OP_TRIGGER_IOPF :
1508+ return iommufd_test_trigger_iopf (ucmd , cmd );
14531509 default :
14541510 return - EOPNOTSUPP ;
14551511 }
@@ -1491,6 +1547,9 @@ int __init iommufd_test_init(void)
14911547 & iommufd_mock_bus_type .nb );
14921548 if (rc )
14931549 goto err_sysfs ;
1550+
1551+ mock_iommu_iopf_queue = iopf_queue_alloc ("mock-iopfq" );
1552+
14941553 return 0 ;
14951554
14961555err_sysfs :
@@ -1506,6 +1565,11 @@ int __init iommufd_test_init(void)
15061565
15071566void iommufd_test_exit (void )
15081567{
1568+ if (mock_iommu_iopf_queue ) {
1569+ iopf_queue_free (mock_iommu_iopf_queue );
1570+ mock_iommu_iopf_queue = NULL ;
1571+ }
1572+
15091573 iommu_device_sysfs_remove (& mock_iommu_device );
15101574 iommu_device_unregister_bus (& mock_iommu_device ,
15111575 & iommufd_mock_bus_type .bus ,
0 commit comments