1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * cap_audit.h - audit iommu capabilities header 4 * 5 * Copyright (C) 2021 Intel Corporation 6 * 7 * Author: Kyung Min Park <kyung.min.park@intel.com> 8 */ 9 10 /* 11 * Capability Register Mask 12 */ 13 #define CAP_FL5LP_MASK BIT_ULL(60) 14 #define CAP_PI_MASK BIT_ULL(59) 15 #define CAP_FL1GP_MASK BIT_ULL(56) 16 #define CAP_RD_MASK BIT_ULL(55) 17 #define CAP_WD_MASK BIT_ULL(54) 18 #define CAP_MAMV_MASK GENMASK_ULL(53, 48) 19 #define CAP_NFR_MASK GENMASK_ULL(47, 40) 20 #define CAP_PSI_MASK BIT_ULL(39) 21 #define CAP_SLLPS_MASK GENMASK_ULL(37, 34) 22 #define CAP_FRO_MASK GENMASK_ULL(33, 24) 23 #define CAP_ZLR_MASK BIT_ULL(22) 24 #define CAP_MGAW_MASK GENMASK_ULL(21, 16) 25 #define CAP_SAGAW_MASK GENMASK_ULL(12, 8) 26 #define CAP_CM_MASK BIT_ULL(7) 27 #define CAP_PHMR_MASK BIT_ULL(6) 28 #define CAP_PLMR_MASK BIT_ULL(5) 29 #define CAP_RWBF_MASK BIT_ULL(4) 30 #define CAP_AFL_MASK BIT_ULL(3) 31 #define CAP_NDOMS_MASK GENMASK_ULL(2, 0) 32 33 /* 34 * Extended Capability Register Mask 35 */ 36 #define ECAP_RPS_MASK BIT_ULL(49) 37 #define ECAP_SMPWC_MASK BIT_ULL(48) 38 #define ECAP_FLTS_MASK BIT_ULL(47) 39 #define ECAP_SLTS_MASK BIT_ULL(46) 40 #define ECAP_SLADS_MASK BIT_ULL(45) 41 #define ECAP_VCS_MASK BIT_ULL(44) 42 #define ECAP_SMTS_MASK BIT_ULL(43) 43 #define ECAP_PDS_MASK BIT_ULL(42) 44 #define ECAP_DIT_MASK BIT_ULL(41) 45 #define ECAP_PASID_MASK BIT_ULL(40) 46 #define ECAP_PSS_MASK GENMASK_ULL(39, 35) 47 #define ECAP_EAFS_MASK BIT_ULL(34) 48 #define ECAP_NWFS_MASK BIT_ULL(33) 49 #define ECAP_SRS_MASK BIT_ULL(31) 50 #define ECAP_ERS_MASK BIT_ULL(30) 51 #define ECAP_PRS_MASK BIT_ULL(29) 52 #define ECAP_NEST_MASK BIT_ULL(26) 53 #define ECAP_MTS_MASK BIT_ULL(25) 54 #define ECAP_MHMV_MASK GENMASK_ULL(23, 20) 55 #define ECAP_IRO_MASK GENMASK_ULL(17, 8) 56 #define ECAP_SC_MASK BIT_ULL(7) 57 #define ECAP_PT_MASK BIT_ULL(6) 58 #define ECAP_EIM_MASK BIT_ULL(4) 59 #define ECAP_DT_MASK BIT_ULL(2) 60 #define ECAP_QI_MASK BIT_ULL(1) 61 #define ECAP_C_MASK BIT_ULL(0) 62 63 /* 64 * u64 intel_iommu_cap_sanity, intel_iommu_ecap_sanity will be adjusted as each 65 * IOMMU gets audited. 66 */ 67 #define DO_CHECK_FEATURE_MISMATCH(a, b, cap, feature, MASK) \ 68 do { \ 69 if (cap##_##feature(a) != cap##_##feature(b)) { \ 70 intel_iommu_##cap##_sanity &= ~(MASK); \ 71 pr_info("IOMMU feature %s inconsistent", #feature); \ 72 } \ 73 } while (0) 74 75 #define CHECK_FEATURE_MISMATCH(a, b, cap, feature, MASK) \ 76 DO_CHECK_FEATURE_MISMATCH((a)->cap, (b)->cap, cap, feature, MASK) 77 78 #define CHECK_FEATURE_MISMATCH_HOTPLUG(b, cap, feature, MASK) \ 79 do { \ 80 if (cap##_##feature(intel_iommu_##cap##_sanity)) \ 81 DO_CHECK_FEATURE_MISMATCH(intel_iommu_##cap##_sanity, \ 82 (b)->cap, cap, feature, MASK); \ 83 } while (0) 84 85 #define MINIMAL_FEATURE_IOMMU(iommu, cap, MASK) \ 86 do { \ 87 u64 min_feature = intel_iommu_##cap##_sanity & (MASK); \ 88 min_feature = min_t(u64, min_feature, (iommu)->cap & (MASK)); \ 89 intel_iommu_##cap##_sanity = (intel_iommu_##cap##_sanity & ~(MASK)) | \ 90 min_feature; \ 91 } while (0) 92 93 #define MINIMAL_FEATURE_HOTPLUG(iommu, cap, feature, MASK, mismatch) \ 94 do { \ 95 if ((intel_iommu_##cap##_sanity & (MASK)) > \ 96 (cap##_##feature((iommu)->cap))) \ 97 mismatch = true; \ 98 else \ 99 (iommu)->cap = ((iommu)->cap & ~(MASK)) | \ 100 (intel_iommu_##cap##_sanity & (MASK)); \ 101 } while (0) 102 103 enum cap_audit_type { 104 CAP_AUDIT_STATIC_DMAR, 105 CAP_AUDIT_STATIC_IRQR, 106 CAP_AUDIT_HOTPLUG_DMAR, 107 CAP_AUDIT_HOTPLUG_IRQR, 108 }; 109 110 bool intel_cap_smts_sanity(void); 111 bool intel_cap_pasid_sanity(void); 112 bool intel_cap_nest_sanity(void); 113 bool intel_cap_flts_sanity(void); 114 115 static inline bool scalable_mode_support(void) 116 { 117 return (intel_iommu_sm && intel_cap_smts_sanity()); 118 } 119 120 static inline bool pasid_mode_support(void) 121 { 122 return scalable_mode_support() && intel_cap_pasid_sanity(); 123 } 124 125 static inline bool nested_mode_support(void) 126 { 127 return scalable_mode_support() && intel_cap_nest_sanity(); 128 } 129 130 int intel_cap_audit(enum cap_audit_type type, struct intel_iommu *iommu); 131