@@ -133,6 +133,7 @@ TEST_F(iommufd, cmd_length)
133
133
TEST_LENGTH (iommu_option , IOMMU_OPTION , val64 );
134
134
TEST_LENGTH (iommu_vfio_ioas , IOMMU_VFIO_IOAS , __reserved );
135
135
TEST_LENGTH (iommu_ioas_map_file , IOMMU_IOAS_MAP_FILE , iova );
136
+ TEST_LENGTH (iommu_viommu_alloc , IOMMU_VIOMMU_ALLOC , out_viommu_id );
136
137
#undef TEST_LENGTH
137
138
}
138
139
@@ -2480,4 +2481,140 @@ TEST_F(vfio_compat_mock_domain, huge_map)
2480
2481
}
2481
2482
}
2482
2483
2484
+ FIXTURE (iommufd_viommu )
2485
+ {
2486
+ int fd ;
2487
+ uint32_t ioas_id ;
2488
+ uint32_t stdev_id ;
2489
+ uint32_t hwpt_id ;
2490
+ uint32_t nested_hwpt_id ;
2491
+ uint32_t device_id ;
2492
+ uint32_t viommu_id ;
2493
+ };
2494
+
2495
+ FIXTURE_VARIANT (iommufd_viommu )
2496
+ {
2497
+ unsigned int viommu ;
2498
+ };
2499
+
2500
+ FIXTURE_SETUP (iommufd_viommu )
2501
+ {
2502
+ self -> fd = open ("/dev/iommu" , O_RDWR );
2503
+ ASSERT_NE (-1 , self -> fd );
2504
+ test_ioctl_ioas_alloc (& self -> ioas_id );
2505
+ test_ioctl_set_default_memory_limit ();
2506
+
2507
+ if (variant -> viommu ) {
2508
+ struct iommu_hwpt_selftest data = {
2509
+ .iotlb = IOMMU_TEST_IOTLB_DEFAULT ,
2510
+ };
2511
+
2512
+ test_cmd_mock_domain (self -> ioas_id , & self -> stdev_id , NULL ,
2513
+ & self -> device_id );
2514
+
2515
+ /* Allocate a nesting parent hwpt */
2516
+ test_cmd_hwpt_alloc (self -> device_id , self -> ioas_id ,
2517
+ IOMMU_HWPT_ALLOC_NEST_PARENT ,
2518
+ & self -> hwpt_id );
2519
+
2520
+ /* Allocate a vIOMMU taking refcount of the parent hwpt */
2521
+ test_cmd_viommu_alloc (self -> device_id , self -> hwpt_id ,
2522
+ IOMMU_VIOMMU_TYPE_SELFTEST ,
2523
+ & self -> viommu_id );
2524
+
2525
+ /* Allocate a regular nested hwpt */
2526
+ test_cmd_hwpt_alloc_nested (self -> device_id , self -> viommu_id , 0 ,
2527
+ & self -> nested_hwpt_id ,
2528
+ IOMMU_HWPT_DATA_SELFTEST , & data ,
2529
+ sizeof (data ));
2530
+ }
2531
+ }
2532
+
2533
+ FIXTURE_TEARDOWN (iommufd_viommu )
2534
+ {
2535
+ teardown_iommufd (self -> fd , _metadata );
2536
+ }
2537
+
2538
+ FIXTURE_VARIANT_ADD (iommufd_viommu , no_viommu )
2539
+ {
2540
+ .viommu = 0 ,
2541
+ };
2542
+
2543
+ FIXTURE_VARIANT_ADD (iommufd_viommu , mock_viommu )
2544
+ {
2545
+ .viommu = 1 ,
2546
+ };
2547
+
2548
+ TEST_F (iommufd_viommu , viommu_auto_destroy )
2549
+ {
2550
+ }
2551
+
2552
+ TEST_F (iommufd_viommu , viommu_negative_tests )
2553
+ {
2554
+ uint32_t device_id = self -> device_id ;
2555
+ uint32_t ioas_id = self -> ioas_id ;
2556
+ uint32_t hwpt_id ;
2557
+
2558
+ if (self -> device_id ) {
2559
+ /* Negative test -- invalid hwpt (hwpt_id=0) */
2560
+ test_err_viommu_alloc (ENOENT , device_id , 0 ,
2561
+ IOMMU_VIOMMU_TYPE_SELFTEST , NULL );
2562
+
2563
+ /* Negative test -- not a nesting parent hwpt */
2564
+ test_cmd_hwpt_alloc (device_id , ioas_id , 0 , & hwpt_id );
2565
+ test_err_viommu_alloc (EINVAL , device_id , hwpt_id ,
2566
+ IOMMU_VIOMMU_TYPE_SELFTEST , NULL );
2567
+ test_ioctl_destroy (hwpt_id );
2568
+
2569
+ /* Negative test -- unsupported viommu type */
2570
+ test_err_viommu_alloc (EOPNOTSUPP , device_id , self -> hwpt_id ,
2571
+ 0xdead , NULL );
2572
+ EXPECT_ERRNO (EBUSY ,
2573
+ _test_ioctl_destroy (self -> fd , self -> hwpt_id ));
2574
+ EXPECT_ERRNO (EBUSY ,
2575
+ _test_ioctl_destroy (self -> fd , self -> viommu_id ));
2576
+ } else {
2577
+ test_err_viommu_alloc (ENOENT , self -> device_id , self -> hwpt_id ,
2578
+ IOMMU_VIOMMU_TYPE_SELFTEST , NULL );
2579
+ }
2580
+ }
2581
+
2582
+ TEST_F (iommufd_viommu , viommu_alloc_nested_iopf )
2583
+ {
2584
+ struct iommu_hwpt_selftest data = {
2585
+ .iotlb = IOMMU_TEST_IOTLB_DEFAULT ,
2586
+ };
2587
+ uint32_t viommu_id = self -> viommu_id ;
2588
+ uint32_t dev_id = self -> device_id ;
2589
+ uint32_t iopf_hwpt_id ;
2590
+ uint32_t fault_id ;
2591
+ uint32_t fault_fd ;
2592
+
2593
+ if (self -> device_id ) {
2594
+ test_ioctl_fault_alloc (& fault_id , & fault_fd );
2595
+ test_err_hwpt_alloc_iopf (
2596
+ ENOENT , dev_id , viommu_id , UINT32_MAX ,
2597
+ IOMMU_HWPT_FAULT_ID_VALID , & iopf_hwpt_id ,
2598
+ IOMMU_HWPT_DATA_SELFTEST , & data , sizeof (data ));
2599
+ test_err_hwpt_alloc_iopf (
2600
+ EOPNOTSUPP , dev_id , viommu_id , fault_id ,
2601
+ IOMMU_HWPT_FAULT_ID_VALID | (1 << 31 ), & iopf_hwpt_id ,
2602
+ IOMMU_HWPT_DATA_SELFTEST , & data , sizeof (data ));
2603
+ test_cmd_hwpt_alloc_iopf (
2604
+ dev_id , viommu_id , fault_id , IOMMU_HWPT_FAULT_ID_VALID ,
2605
+ & iopf_hwpt_id , IOMMU_HWPT_DATA_SELFTEST , & data ,
2606
+ sizeof (data ));
2607
+
2608
+ test_cmd_mock_domain_replace (self -> stdev_id , iopf_hwpt_id );
2609
+ EXPECT_ERRNO (EBUSY ,
2610
+ _test_ioctl_destroy (self -> fd , iopf_hwpt_id ));
2611
+ test_cmd_trigger_iopf (dev_id , fault_fd );
2612
+
2613
+ test_cmd_mock_domain_replace (self -> stdev_id , self -> ioas_id );
2614
+ test_ioctl_destroy (iopf_hwpt_id );
2615
+ close (fault_fd );
2616
+ test_ioctl_destroy (fault_id );
2617
+ }
2618
+ }
2619
+
2483
2620
TEST_HARNESS_MAIN
0 commit comments