@@ -133,6 +133,7 @@ TEST_F(iommufd, cmd_length)
133133 TEST_LENGTH (iommu_option , IOMMU_OPTION , val64 );
134134 TEST_LENGTH (iommu_vfio_ioas , IOMMU_VFIO_IOAS , __reserved );
135135 TEST_LENGTH (iommu_ioas_map_file , IOMMU_IOAS_MAP_FILE , iova );
136+ TEST_LENGTH (iommu_viommu_alloc , IOMMU_VIOMMU_ALLOC , out_viommu_id );
136137#undef TEST_LENGTH
137138}
138139
@@ -2480,4 +2481,140 @@ TEST_F(vfio_compat_mock_domain, huge_map)
24802481 }
24812482}
24822483
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+
24832620TEST_HARNESS_MAIN
0 commit comments