@@ -2642,4 +2642,177 @@ TEST_F(iommufd_viommu, vdevice_alloc)
2642
2642
}
2643
2643
}
2644
2644
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
+
2645
2818
TEST_HARNESS_MAIN
0 commit comments