@@ -504,6 +504,8 @@ static bool mock_domain_capable(struct device *dev, enum iommu_cap cap)
504
504
return false;
505
505
}
506
506
507
+ static struct iopf_queue * mock_iommu_iopf_queue ;
508
+
507
509
static struct iommu_device mock_iommu_device = {
508
510
};
509
511
@@ -514,6 +516,29 @@ static struct iommu_device *mock_probe_device(struct device *dev)
514
516
return & mock_iommu_device ;
515
517
}
516
518
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
+
517
542
static const struct iommu_ops mock_ops = {
518
543
/*
519
544
* IOMMU_DOMAIN_BLOCKED cannot be returned from def_domain_type()
@@ -529,6 +554,10 @@ static const struct iommu_ops mock_ops = {
529
554
.capable = mock_domain_capable ,
530
555
.device_group = generic_device_group ,
531
556
.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,
532
561
.default_domain_ops =
533
562
& (struct iommu_domain_ops ){
534
563
.free = mock_domain_free ,
@@ -1375,6 +1404,31 @@ static int iommufd_test_dirty(struct iommufd_ucmd *ucmd, unsigned int mockpt_id,
1375
1404
return rc ;
1376
1405
}
1377
1406
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
+
1378
1432
void iommufd_selftest_destroy (struct iommufd_object * obj )
1379
1433
{
1380
1434
struct selftest_obj * sobj = container_of (obj , struct selftest_obj , obj );
@@ -1450,6 +1504,8 @@ int iommufd_test(struct iommufd_ucmd *ucmd)
1450
1504
cmd -> dirty .page_size ,
1451
1505
u64_to_user_ptr (cmd -> dirty .uptr ),
1452
1506
cmd -> dirty .flags );
1507
+ case IOMMU_TEST_OP_TRIGGER_IOPF :
1508
+ return iommufd_test_trigger_iopf (ucmd , cmd );
1453
1509
default :
1454
1510
return - EOPNOTSUPP ;
1455
1511
}
@@ -1491,6 +1547,9 @@ int __init iommufd_test_init(void)
1491
1547
& iommufd_mock_bus_type .nb );
1492
1548
if (rc )
1493
1549
goto err_sysfs ;
1550
+
1551
+ mock_iommu_iopf_queue = iopf_queue_alloc ("mock-iopfq" );
1552
+
1494
1553
return 0 ;
1495
1554
1496
1555
err_sysfs :
@@ -1506,6 +1565,11 @@ int __init iommufd_test_init(void)
1506
1565
1507
1566
void iommufd_test_exit (void )
1508
1567
{
1568
+ if (mock_iommu_iopf_queue ) {
1569
+ iopf_queue_free (mock_iommu_iopf_queue );
1570
+ mock_iommu_iopf_queue = NULL ;
1571
+ }
1572
+
1509
1573
iommu_device_sysfs_remove (& mock_iommu_device );
1510
1574
iommu_device_unregister_bus (& mock_iommu_device ,
1511
1575
& iommufd_mock_bus_type .bus ,
0 commit comments