@@ -2642,4 +2642,177 @@ TEST_F(iommufd_viommu, vdevice_alloc)
26422642 }
26432643}
26442644
2645+ TEST_F (iommufd_viommu , vdevice_cache )
2646+ {
2647+ struct iommu_viommu_invalidate_selftest inv_reqs [2 ] = {};
2648+ uint32_t viommu_id = self -> viommu_id ;
2649+ uint32_t dev_id = self -> device_id ;
2650+ uint32_t vdev_id = 0 ;
2651+ uint32_t num_inv ;
2652+
2653+ if (dev_id ) {
2654+ test_cmd_vdevice_alloc (viommu_id , dev_id , 0x99 , & vdev_id );
2655+
2656+ test_cmd_dev_check_cache_all (dev_id ,
2657+ IOMMU_TEST_DEV_CACHE_DEFAULT );
2658+
2659+ /* Check data_type by passing zero-length array */
2660+ num_inv = 0 ;
2661+ test_cmd_viommu_invalidate (viommu_id , inv_reqs ,
2662+ sizeof (* inv_reqs ), & num_inv );
2663+ assert (!num_inv );
2664+
2665+ /* Negative test: Invalid data_type */
2666+ num_inv = 1 ;
2667+ test_err_viommu_invalidate (EINVAL , viommu_id , inv_reqs ,
2668+ IOMMU_VIOMMU_INVALIDATE_DATA_SELFTEST_INVALID ,
2669+ sizeof (* inv_reqs ), & num_inv );
2670+ assert (!num_inv );
2671+
2672+ /* Negative test: structure size sanity */
2673+ num_inv = 1 ;
2674+ test_err_viommu_invalidate (EINVAL , viommu_id , inv_reqs ,
2675+ IOMMU_VIOMMU_INVALIDATE_DATA_SELFTEST ,
2676+ sizeof (* inv_reqs ) + 1 , & num_inv );
2677+ assert (!num_inv );
2678+
2679+ num_inv = 1 ;
2680+ test_err_viommu_invalidate (EINVAL , viommu_id , inv_reqs ,
2681+ IOMMU_VIOMMU_INVALIDATE_DATA_SELFTEST ,
2682+ 1 , & num_inv );
2683+ assert (!num_inv );
2684+
2685+ /* Negative test: invalid flag is passed */
2686+ num_inv = 1 ;
2687+ inv_reqs [0 ].flags = 0xffffffff ;
2688+ inv_reqs [0 ].vdev_id = 0x99 ;
2689+ test_err_viommu_invalidate (EOPNOTSUPP , viommu_id , inv_reqs ,
2690+ IOMMU_VIOMMU_INVALIDATE_DATA_SELFTEST ,
2691+ sizeof (* inv_reqs ), & num_inv );
2692+ assert (!num_inv );
2693+
2694+ /* Negative test: invalid data_uptr when array is not empty */
2695+ num_inv = 1 ;
2696+ inv_reqs [0 ].flags = 0 ;
2697+ inv_reqs [0 ].vdev_id = 0x99 ;
2698+ test_err_viommu_invalidate (EINVAL , viommu_id , NULL ,
2699+ IOMMU_VIOMMU_INVALIDATE_DATA_SELFTEST ,
2700+ sizeof (* inv_reqs ), & num_inv );
2701+ assert (!num_inv );
2702+
2703+ /* Negative test: invalid entry_len when array is not empty */
2704+ num_inv = 1 ;
2705+ inv_reqs [0 ].flags = 0 ;
2706+ inv_reqs [0 ].vdev_id = 0x99 ;
2707+ test_err_viommu_invalidate (EINVAL , viommu_id , inv_reqs ,
2708+ IOMMU_VIOMMU_INVALIDATE_DATA_SELFTEST ,
2709+ 0 , & num_inv );
2710+ assert (!num_inv );
2711+
2712+ /* Negative test: invalid cache_id */
2713+ num_inv = 1 ;
2714+ inv_reqs [0 ].flags = 0 ;
2715+ inv_reqs [0 ].vdev_id = 0x99 ;
2716+ inv_reqs [0 ].cache_id = MOCK_DEV_CACHE_ID_MAX + 1 ;
2717+ test_err_viommu_invalidate (EINVAL , viommu_id , inv_reqs ,
2718+ IOMMU_VIOMMU_INVALIDATE_DATA_SELFTEST ,
2719+ sizeof (* inv_reqs ), & num_inv );
2720+ assert (!num_inv );
2721+
2722+ /* Negative test: invalid vdev_id */
2723+ num_inv = 1 ;
2724+ inv_reqs [0 ].flags = 0 ;
2725+ inv_reqs [0 ].vdev_id = 0x9 ;
2726+ inv_reqs [0 ].cache_id = 0 ;
2727+ test_err_viommu_invalidate (EINVAL , viommu_id , inv_reqs ,
2728+ IOMMU_VIOMMU_INVALIDATE_DATA_SELFTEST ,
2729+ sizeof (* inv_reqs ), & num_inv );
2730+ assert (!num_inv );
2731+
2732+ /*
2733+ * Invalidate the 1st cache entry but fail the 2nd request
2734+ * due to invalid flags configuration in the 2nd request.
2735+ */
2736+ num_inv = 2 ;
2737+ inv_reqs [0 ].flags = 0 ;
2738+ inv_reqs [0 ].vdev_id = 0x99 ;
2739+ inv_reqs [0 ].cache_id = 0 ;
2740+ inv_reqs [1 ].flags = 0xffffffff ;
2741+ inv_reqs [1 ].vdev_id = 0x99 ;
2742+ inv_reqs [1 ].cache_id = 1 ;
2743+ test_err_viommu_invalidate (EOPNOTSUPP , viommu_id , inv_reqs ,
2744+ IOMMU_VIOMMU_INVALIDATE_DATA_SELFTEST ,
2745+ sizeof (* inv_reqs ), & num_inv );
2746+ assert (num_inv == 1 );
2747+ test_cmd_dev_check_cache (dev_id , 0 , 0 );
2748+ test_cmd_dev_check_cache (dev_id , 1 ,
2749+ IOMMU_TEST_DEV_CACHE_DEFAULT );
2750+ test_cmd_dev_check_cache (dev_id , 2 ,
2751+ IOMMU_TEST_DEV_CACHE_DEFAULT );
2752+ test_cmd_dev_check_cache (dev_id , 3 ,
2753+ IOMMU_TEST_DEV_CACHE_DEFAULT );
2754+
2755+ /*
2756+ * Invalidate the 1st cache entry but fail the 2nd request
2757+ * due to invalid cache_id configuration in the 2nd request.
2758+ */
2759+ num_inv = 2 ;
2760+ inv_reqs [0 ].flags = 0 ;
2761+ inv_reqs [0 ].vdev_id = 0x99 ;
2762+ inv_reqs [0 ].cache_id = 0 ;
2763+ inv_reqs [1 ].flags = 0 ;
2764+ inv_reqs [1 ].vdev_id = 0x99 ;
2765+ inv_reqs [1 ].cache_id = MOCK_DEV_CACHE_ID_MAX + 1 ;
2766+ test_err_viommu_invalidate (EINVAL , viommu_id , inv_reqs ,
2767+ IOMMU_VIOMMU_INVALIDATE_DATA_SELFTEST ,
2768+ sizeof (* inv_reqs ), & num_inv );
2769+ assert (num_inv == 1 );
2770+ test_cmd_dev_check_cache (dev_id , 0 , 0 );
2771+ test_cmd_dev_check_cache (dev_id , 1 ,
2772+ IOMMU_TEST_DEV_CACHE_DEFAULT );
2773+ test_cmd_dev_check_cache (dev_id , 2 ,
2774+ IOMMU_TEST_DEV_CACHE_DEFAULT );
2775+ test_cmd_dev_check_cache (dev_id , 3 ,
2776+ IOMMU_TEST_DEV_CACHE_DEFAULT );
2777+
2778+ /* Invalidate the 2nd cache entry and verify */
2779+ num_inv = 1 ;
2780+ inv_reqs [0 ].flags = 0 ;
2781+ inv_reqs [0 ].vdev_id = 0x99 ;
2782+ inv_reqs [0 ].cache_id = 1 ;
2783+ test_cmd_viommu_invalidate (viommu_id , inv_reqs ,
2784+ sizeof (* inv_reqs ), & num_inv );
2785+ assert (num_inv == 1 );
2786+ test_cmd_dev_check_cache (dev_id , 0 , 0 );
2787+ test_cmd_dev_check_cache (dev_id , 1 , 0 );
2788+ test_cmd_dev_check_cache (dev_id , 2 ,
2789+ IOMMU_TEST_DEV_CACHE_DEFAULT );
2790+ test_cmd_dev_check_cache (dev_id , 3 ,
2791+ IOMMU_TEST_DEV_CACHE_DEFAULT );
2792+
2793+ /* Invalidate the 3rd and 4th cache entries and verify */
2794+ num_inv = 2 ;
2795+ inv_reqs [0 ].flags = 0 ;
2796+ inv_reqs [0 ].vdev_id = 0x99 ;
2797+ inv_reqs [0 ].cache_id = 2 ;
2798+ inv_reqs [1 ].flags = 0 ;
2799+ inv_reqs [1 ].vdev_id = 0x99 ;
2800+ inv_reqs [1 ].cache_id = 3 ;
2801+ test_cmd_viommu_invalidate (viommu_id , inv_reqs ,
2802+ sizeof (* inv_reqs ), & num_inv );
2803+ assert (num_inv == 2 );
2804+ test_cmd_dev_check_cache_all (dev_id , 0 );
2805+
2806+ /* Invalidate all cache entries for nested_dev_id[1] and verify */
2807+ num_inv = 1 ;
2808+ inv_reqs [0 ].vdev_id = 0x99 ;
2809+ inv_reqs [0 ].flags = IOMMU_TEST_INVALIDATE_FLAG_ALL ;
2810+ test_cmd_viommu_invalidate (viommu_id , inv_reqs ,
2811+ sizeof (* inv_reqs ), & num_inv );
2812+ assert (num_inv == 1 );
2813+ test_cmd_dev_check_cache_all (dev_id , 0 );
2814+ test_ioctl_destroy (vdev_id );
2815+ }
2816+ }
2817+
26452818TEST_HARNESS_MAIN
0 commit comments