Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

iommu/vt-d: Remove virtual command interface

Virtual command interface was introduced to allow using host PASIDs
inside VMs. It is unused and abandoned due to architectural change.

With this patch, we can safely remove this feature and the related helpers.

Link: https://lore.kernel.org/r/20230210230206.3160144-2-jacob.jun.pan@linux.intel.com
Signed-off-by: Jacob Pan <jacob.jun.pan@linux.intel.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>
Link: https://lore.kernel.org/r/20230322200803.869130-2-jacob.jun.pan@linux.intel.com
Signed-off-by: Joerg Roedel <jroedel@suse.de>

authored by

Jacob Pan and committed by
Joerg Roedel
760f41d1 c33fcc13

-91
-2
drivers/iommu/intel/cap_audit.c
··· 54 54 CHECK_FEATURE_MISMATCH(a, b, ecap, slts, ECAP_SLTS_MASK); 55 55 CHECK_FEATURE_MISMATCH(a, b, ecap, nwfs, ECAP_NWFS_MASK); 56 56 CHECK_FEATURE_MISMATCH(a, b, ecap, slads, ECAP_SLADS_MASK); 57 - CHECK_FEATURE_MISMATCH(a, b, ecap, vcs, ECAP_VCS_MASK); 58 57 CHECK_FEATURE_MISMATCH(a, b, ecap, smts, ECAP_SMTS_MASK); 59 58 CHECK_FEATURE_MISMATCH(a, b, ecap, pds, ECAP_PDS_MASK); 60 59 CHECK_FEATURE_MISMATCH(a, b, ecap, dit, ECAP_DIT_MASK); ··· 100 101 CHECK_FEATURE_MISMATCH_HOTPLUG(iommu, ecap, slts, ECAP_SLTS_MASK); 101 102 CHECK_FEATURE_MISMATCH_HOTPLUG(iommu, ecap, nwfs, ECAP_NWFS_MASK); 102 103 CHECK_FEATURE_MISMATCH_HOTPLUG(iommu, ecap, slads, ECAP_SLADS_MASK); 103 - CHECK_FEATURE_MISMATCH_HOTPLUG(iommu, ecap, vcs, ECAP_VCS_MASK); 104 104 CHECK_FEATURE_MISMATCH_HOTPLUG(iommu, ecap, smts, ECAP_SMTS_MASK); 105 105 CHECK_FEATURE_MISMATCH_HOTPLUG(iommu, ecap, pds, ECAP_PDS_MASK); 106 106 CHECK_FEATURE_MISMATCH_HOTPLUG(iommu, ecap, dit, ECAP_DIT_MASK);
-2
drivers/iommu/intel/dmar.c
··· 993 993 warn_invalid_dmar(phys_addr, " returns all ones"); 994 994 goto unmap; 995 995 } 996 - if (ecap_vcs(iommu->ecap)) 997 - iommu->vccap = dmar_readq(iommu->reg + DMAR_VCCAP_REG); 998 996 999 997 /* the registers might be more than one page */ 1000 998 map_size = max_t(int, ecap_max_iotlb_offset(iommu->ecap),
-85
drivers/iommu/intel/iommu.c
··· 1722 1722 if (ecap_prs(iommu->ecap)) 1723 1723 intel_svm_finish_prq(iommu); 1724 1724 } 1725 - if (vccap_pasid(iommu->vccap)) 1726 - ioasid_unregister_allocator(&iommu->pasid_allocator); 1727 - 1728 1725 #endif 1729 1726 } 1730 1727 ··· 2794 2797 return ret; 2795 2798 } 2796 2799 2797 - #ifdef CONFIG_INTEL_IOMMU_SVM 2798 - static ioasid_t intel_vcmd_ioasid_alloc(ioasid_t min, ioasid_t max, void *data) 2799 - { 2800 - struct intel_iommu *iommu = data; 2801 - ioasid_t ioasid; 2802 - 2803 - if (!iommu) 2804 - return INVALID_IOASID; 2805 - /* 2806 - * VT-d virtual command interface always uses the full 20 bit 2807 - * PASID range. Host can partition guest PASID range based on 2808 - * policies but it is out of guest's control. 2809 - */ 2810 - if (min < PASID_MIN || max > intel_pasid_max_id) 2811 - return INVALID_IOASID; 2812 - 2813 - if (vcmd_alloc_pasid(iommu, &ioasid)) 2814 - return INVALID_IOASID; 2815 - 2816 - return ioasid; 2817 - } 2818 - 2819 - static void intel_vcmd_ioasid_free(ioasid_t ioasid, void *data) 2820 - { 2821 - struct intel_iommu *iommu = data; 2822 - 2823 - if (!iommu) 2824 - return; 2825 - /* 2826 - * Sanity check the ioasid owner is done at upper layer, e.g. VFIO 2827 - * We can only free the PASID when all the devices are unbound. 2828 - */ 2829 - if (ioasid_find(NULL, ioasid, NULL)) { 2830 - pr_alert("Cannot free active IOASID %d\n", ioasid); 2831 - return; 2832 - } 2833 - vcmd_free_pasid(iommu, ioasid); 2834 - } 2835 - 2836 - static void register_pasid_allocator(struct intel_iommu *iommu) 2837 - { 2838 - /* 2839 - * If we are running in the host, no need for custom allocator 2840 - * in that PASIDs are allocated from the host system-wide. 2841 - */ 2842 - if (!cap_caching_mode(iommu->cap)) 2843 - return; 2844 - 2845 - if (!sm_supported(iommu)) { 2846 - pr_warn("VT-d Scalable Mode not enabled, no PASID allocation\n"); 2847 - return; 2848 - } 2849 - 2850 - /* 2851 - * Register a custom PASID allocator if we are running in a guest, 2852 - * guest PASID must be obtained via virtual command interface. 2853 - * There can be multiple vIOMMUs in each guest but only one allocator 2854 - * is active. All vIOMMU allocators will eventually be calling the same 2855 - * host allocator. 2856 - */ 2857 - if (!vccap_pasid(iommu->vccap)) 2858 - return; 2859 - 2860 - pr_info("Register custom PASID allocator\n"); 2861 - iommu->pasid_allocator.alloc = intel_vcmd_ioasid_alloc; 2862 - iommu->pasid_allocator.free = intel_vcmd_ioasid_free; 2863 - iommu->pasid_allocator.pdata = (void *)iommu; 2864 - if (ioasid_register_allocator(&iommu->pasid_allocator)) { 2865 - pr_warn("Custom PASID allocator failed, scalable mode disabled\n"); 2866 - /* 2867 - * Disable scalable mode on this IOMMU if there 2868 - * is no custom allocator. Mixing SM capable vIOMMU 2869 - * and non-SM vIOMMU are not supported. 2870 - */ 2871 - intel_iommu_sm = 0; 2872 - } 2873 - } 2874 - #endif 2875 - 2876 2800 static int __init init_dmars(void) 2877 2801 { 2878 2802 struct dmar_drhd_unit *drhd; ··· 2882 2964 */ 2883 2965 for_each_active_iommu(iommu, drhd) { 2884 2966 iommu_flush_write_buffer(iommu); 2885 - #ifdef CONFIG_INTEL_IOMMU_SVM 2886 - register_pasid_allocator(iommu); 2887 - #endif 2888 2967 iommu_set_root_entry(iommu); 2889 2968 } 2890 2969
-2
drivers/iommu/intel/iommu.h
··· 198 198 #define ecap_flts(e) (((e) >> 47) & 0x1) 199 199 #define ecap_slts(e) (((e) >> 46) & 0x1) 200 200 #define ecap_slads(e) (((e) >> 45) & 0x1) 201 - #define ecap_vcs(e) (((e) >> 44) & 0x1) 202 201 #define ecap_smts(e) (((e) >> 43) & 0x1) 203 202 #define ecap_dit(e) (((e) >> 41) & 0x1) 204 203 #define ecap_pds(e) (((e) >> 42) & 0x1) ··· 675 676 unsigned char prq_name[16]; /* Name for PRQ interrupt */ 676 677 unsigned long prq_seq_number; 677 678 struct completion prq_complete; 678 - struct ioasid_allocator_ops pasid_allocator; /* Custom allocator for PASIDs */ 679 679 #endif 680 680 struct iopf_queue *iopf_queue; 681 681 unsigned char iopfq_name[16];