1 // SPDX-License-Identifier: GPL-2.0
3 * cap_audit.c - audit iommu capabilities for boot time and hot plug
5 * Copyright (C) 2021 Intel Corporation
7 * Author: Kyung Min Park <kyung.min.park@intel.com>
8 * Lu Baolu <baolu.lu@linux.intel.com>
11 #define pr_fmt(fmt) "DMAR: " fmt
14 #include "cap_audit.h"
16 static u64 intel_iommu_cap_sanity
;
17 static u64 intel_iommu_ecap_sanity
;
19 static inline void check_irq_capabilities(struct intel_iommu
*a
,
20 struct intel_iommu
*b
)
22 CHECK_FEATURE_MISMATCH(a
, b
, cap
, pi_support
, CAP_PI_MASK
);
23 CHECK_FEATURE_MISMATCH(a
, b
, ecap
, eim_support
, ECAP_EIM_MASK
);
26 static inline void check_dmar_capabilities(struct intel_iommu
*a
,
27 struct intel_iommu
*b
)
29 MINIMAL_FEATURE_IOMMU(b
, cap
, CAP_MAMV_MASK
);
30 MINIMAL_FEATURE_IOMMU(b
, cap
, CAP_NFR_MASK
);
31 MINIMAL_FEATURE_IOMMU(b
, cap
, CAP_SLLPS_MASK
);
32 MINIMAL_FEATURE_IOMMU(b
, cap
, CAP_FRO_MASK
);
33 MINIMAL_FEATURE_IOMMU(b
, cap
, CAP_MGAW_MASK
);
34 MINIMAL_FEATURE_IOMMU(b
, cap
, CAP_SAGAW_MASK
);
35 MINIMAL_FEATURE_IOMMU(b
, cap
, CAP_NDOMS_MASK
);
36 MINIMAL_FEATURE_IOMMU(b
, ecap
, ECAP_PSS_MASK
);
37 MINIMAL_FEATURE_IOMMU(b
, ecap
, ECAP_MHMV_MASK
);
38 MINIMAL_FEATURE_IOMMU(b
, ecap
, ECAP_IRO_MASK
);
40 CHECK_FEATURE_MISMATCH(a
, b
, cap
, fl5lp_support
, CAP_FL5LP_MASK
);
41 CHECK_FEATURE_MISMATCH(a
, b
, cap
, fl1gp_support
, CAP_FL1GP_MASK
);
42 CHECK_FEATURE_MISMATCH(a
, b
, cap
, read_drain
, CAP_RD_MASK
);
43 CHECK_FEATURE_MISMATCH(a
, b
, cap
, write_drain
, CAP_WD_MASK
);
44 CHECK_FEATURE_MISMATCH(a
, b
, cap
, pgsel_inv
, CAP_PSI_MASK
);
45 CHECK_FEATURE_MISMATCH(a
, b
, cap
, zlr
, CAP_ZLR_MASK
);
46 CHECK_FEATURE_MISMATCH(a
, b
, cap
, caching_mode
, CAP_CM_MASK
);
47 CHECK_FEATURE_MISMATCH(a
, b
, cap
, phmr
, CAP_PHMR_MASK
);
48 CHECK_FEATURE_MISMATCH(a
, b
, cap
, plmr
, CAP_PLMR_MASK
);
49 CHECK_FEATURE_MISMATCH(a
, b
, cap
, rwbf
, CAP_RWBF_MASK
);
50 CHECK_FEATURE_MISMATCH(a
, b
, cap
, afl
, CAP_AFL_MASK
);
51 CHECK_FEATURE_MISMATCH(a
, b
, ecap
, rps
, ECAP_RPS_MASK
);
52 CHECK_FEATURE_MISMATCH(a
, b
, ecap
, smpwc
, ECAP_SMPWC_MASK
);
53 CHECK_FEATURE_MISMATCH(a
, b
, ecap
, flts
, ECAP_FLTS_MASK
);
54 CHECK_FEATURE_MISMATCH(a
, b
, ecap
, slts
, ECAP_SLTS_MASK
);
55 CHECK_FEATURE_MISMATCH(a
, b
, ecap
, nwfs
, ECAP_NWFS_MASK
);
56 CHECK_FEATURE_MISMATCH(a
, b
, ecap
, slads
, ECAP_SLADS_MASK
);
57 CHECK_FEATURE_MISMATCH(a
, b
, ecap
, smts
, ECAP_SMTS_MASK
);
58 CHECK_FEATURE_MISMATCH(a
, b
, ecap
, pds
, ECAP_PDS_MASK
);
59 CHECK_FEATURE_MISMATCH(a
, b
, ecap
, dit
, ECAP_DIT_MASK
);
60 CHECK_FEATURE_MISMATCH(a
, b
, ecap
, pasid
, ECAP_PASID_MASK
);
61 CHECK_FEATURE_MISMATCH(a
, b
, ecap
, eafs
, ECAP_EAFS_MASK
);
62 CHECK_FEATURE_MISMATCH(a
, b
, ecap
, srs
, ECAP_SRS_MASK
);
63 CHECK_FEATURE_MISMATCH(a
, b
, ecap
, ers
, ECAP_ERS_MASK
);
64 CHECK_FEATURE_MISMATCH(a
, b
, ecap
, prs
, ECAP_PRS_MASK
);
65 CHECK_FEATURE_MISMATCH(a
, b
, ecap
, nest
, ECAP_NEST_MASK
);
66 CHECK_FEATURE_MISMATCH(a
, b
, ecap
, mts
, ECAP_MTS_MASK
);
67 CHECK_FEATURE_MISMATCH(a
, b
, ecap
, sc_support
, ECAP_SC_MASK
);
68 CHECK_FEATURE_MISMATCH(a
, b
, ecap
, pass_through
, ECAP_PT_MASK
);
69 CHECK_FEATURE_MISMATCH(a
, b
, ecap
, dev_iotlb_support
, ECAP_DT_MASK
);
70 CHECK_FEATURE_MISMATCH(a
, b
, ecap
, qis
, ECAP_QI_MASK
);
71 CHECK_FEATURE_MISMATCH(a
, b
, ecap
, coherent
, ECAP_C_MASK
);
74 static int cap_audit_hotplug(struct intel_iommu
*iommu
, enum cap_audit_type type
)
76 bool mismatch
= false;
77 u64 old_cap
= intel_iommu_cap_sanity
;
78 u64 old_ecap
= intel_iommu_ecap_sanity
;
80 if (type
== CAP_AUDIT_HOTPLUG_IRQR
) {
81 CHECK_FEATURE_MISMATCH_HOTPLUG(iommu
, cap
, pi_support
, CAP_PI_MASK
);
82 CHECK_FEATURE_MISMATCH_HOTPLUG(iommu
, ecap
, eim_support
, ECAP_EIM_MASK
);
86 CHECK_FEATURE_MISMATCH_HOTPLUG(iommu
, cap
, fl5lp_support
, CAP_FL5LP_MASK
);
87 CHECK_FEATURE_MISMATCH_HOTPLUG(iommu
, cap
, fl1gp_support
, CAP_FL1GP_MASK
);
88 CHECK_FEATURE_MISMATCH_HOTPLUG(iommu
, cap
, read_drain
, CAP_RD_MASK
);
89 CHECK_FEATURE_MISMATCH_HOTPLUG(iommu
, cap
, write_drain
, CAP_WD_MASK
);
90 CHECK_FEATURE_MISMATCH_HOTPLUG(iommu
, cap
, pgsel_inv
, CAP_PSI_MASK
);
91 CHECK_FEATURE_MISMATCH_HOTPLUG(iommu
, cap
, zlr
, CAP_ZLR_MASK
);
92 CHECK_FEATURE_MISMATCH_HOTPLUG(iommu
, cap
, caching_mode
, CAP_CM_MASK
);
93 CHECK_FEATURE_MISMATCH_HOTPLUG(iommu
, cap
, phmr
, CAP_PHMR_MASK
);
94 CHECK_FEATURE_MISMATCH_HOTPLUG(iommu
, cap
, plmr
, CAP_PLMR_MASK
);
95 CHECK_FEATURE_MISMATCH_HOTPLUG(iommu
, cap
, rwbf
, CAP_RWBF_MASK
);
96 CHECK_FEATURE_MISMATCH_HOTPLUG(iommu
, cap
, afl
, CAP_AFL_MASK
);
97 CHECK_FEATURE_MISMATCH_HOTPLUG(iommu
, ecap
, rps
, ECAP_RPS_MASK
);
98 CHECK_FEATURE_MISMATCH_HOTPLUG(iommu
, ecap
, smpwc
, ECAP_SMPWC_MASK
);
99 CHECK_FEATURE_MISMATCH_HOTPLUG(iommu
, ecap
, flts
, ECAP_FLTS_MASK
);
100 CHECK_FEATURE_MISMATCH_HOTPLUG(iommu
, ecap
, slts
, ECAP_SLTS_MASK
);
101 CHECK_FEATURE_MISMATCH_HOTPLUG(iommu
, ecap
, nwfs
, ECAP_NWFS_MASK
);
102 CHECK_FEATURE_MISMATCH_HOTPLUG(iommu
, ecap
, slads
, ECAP_SLADS_MASK
);
103 CHECK_FEATURE_MISMATCH_HOTPLUG(iommu
, ecap
, smts
, ECAP_SMTS_MASK
);
104 CHECK_FEATURE_MISMATCH_HOTPLUG(iommu
, ecap
, pds
, ECAP_PDS_MASK
);
105 CHECK_FEATURE_MISMATCH_HOTPLUG(iommu
, ecap
, dit
, ECAP_DIT_MASK
);
106 CHECK_FEATURE_MISMATCH_HOTPLUG(iommu
, ecap
, pasid
, ECAP_PASID_MASK
);
107 CHECK_FEATURE_MISMATCH_HOTPLUG(iommu
, ecap
, eafs
, ECAP_EAFS_MASK
);
108 CHECK_FEATURE_MISMATCH_HOTPLUG(iommu
, ecap
, srs
, ECAP_SRS_MASK
);
109 CHECK_FEATURE_MISMATCH_HOTPLUG(iommu
, ecap
, ers
, ECAP_ERS_MASK
);
110 CHECK_FEATURE_MISMATCH_HOTPLUG(iommu
, ecap
, prs
, ECAP_PRS_MASK
);
111 CHECK_FEATURE_MISMATCH_HOTPLUG(iommu
, ecap
, nest
, ECAP_NEST_MASK
);
112 CHECK_FEATURE_MISMATCH_HOTPLUG(iommu
, ecap
, mts
, ECAP_MTS_MASK
);
113 CHECK_FEATURE_MISMATCH_HOTPLUG(iommu
, ecap
, sc_support
, ECAP_SC_MASK
);
114 CHECK_FEATURE_MISMATCH_HOTPLUG(iommu
, ecap
, pass_through
, ECAP_PT_MASK
);
115 CHECK_FEATURE_MISMATCH_HOTPLUG(iommu
, ecap
, dev_iotlb_support
, ECAP_DT_MASK
);
116 CHECK_FEATURE_MISMATCH_HOTPLUG(iommu
, ecap
, qis
, ECAP_QI_MASK
);
117 CHECK_FEATURE_MISMATCH_HOTPLUG(iommu
, ecap
, coherent
, ECAP_C_MASK
);
119 /* Abort hot plug if the hot plug iommu feature is smaller than global */
120 MINIMAL_FEATURE_HOTPLUG(iommu
, cap
, max_amask_val
, CAP_MAMV_MASK
, mismatch
);
121 MINIMAL_FEATURE_HOTPLUG(iommu
, cap
, num_fault_regs
, CAP_NFR_MASK
, mismatch
);
122 MINIMAL_FEATURE_HOTPLUG(iommu
, cap
, super_page_val
, CAP_SLLPS_MASK
, mismatch
);
123 MINIMAL_FEATURE_HOTPLUG(iommu
, cap
, fault_reg_offset
, CAP_FRO_MASK
, mismatch
);
124 MINIMAL_FEATURE_HOTPLUG(iommu
, cap
, mgaw
, CAP_MGAW_MASK
, mismatch
);
125 MINIMAL_FEATURE_HOTPLUG(iommu
, cap
, sagaw
, CAP_SAGAW_MASK
, mismatch
);
126 MINIMAL_FEATURE_HOTPLUG(iommu
, cap
, ndoms
, CAP_NDOMS_MASK
, mismatch
);
127 MINIMAL_FEATURE_HOTPLUG(iommu
, ecap
, pss
, ECAP_PSS_MASK
, mismatch
);
128 MINIMAL_FEATURE_HOTPLUG(iommu
, ecap
, max_handle_mask
, ECAP_MHMV_MASK
, mismatch
);
129 MINIMAL_FEATURE_HOTPLUG(iommu
, ecap
, iotlb_offset
, ECAP_IRO_MASK
, mismatch
);
133 intel_iommu_cap_sanity
= old_cap
;
134 intel_iommu_ecap_sanity
= old_ecap
;
141 static int cap_audit_static(struct intel_iommu
*iommu
, enum cap_audit_type type
)
143 struct dmar_drhd_unit
*d
;
144 struct intel_iommu
*i
;
148 if (list_empty(&dmar_drhd_units
))
151 for_each_active_iommu(i
, d
) {
153 intel_iommu_ecap_sanity
= i
->ecap
;
154 intel_iommu_cap_sanity
= i
->cap
;
159 if (type
== CAP_AUDIT_STATIC_DMAR
)
160 check_dmar_capabilities(iommu
, i
);
162 check_irq_capabilities(iommu
, i
);
166 * If the system is sane to support scalable mode, either SL or FL
169 if (intel_cap_smts_sanity() &&
170 !intel_cap_flts_sanity() && !intel_cap_slts_sanity())
178 int intel_cap_audit(enum cap_audit_type type
, struct intel_iommu
*iommu
)
181 case CAP_AUDIT_STATIC_DMAR
:
182 case CAP_AUDIT_STATIC_IRQR
:
183 return cap_audit_static(iommu
, type
);
184 case CAP_AUDIT_HOTPLUG_DMAR
:
185 case CAP_AUDIT_HOTPLUG_IRQR
:
186 return cap_audit_hotplug(iommu
, type
);
194 bool intel_cap_smts_sanity(void)
196 return ecap_smts(intel_iommu_ecap_sanity
);
199 bool intel_cap_pasid_sanity(void)
201 return ecap_pasid(intel_iommu_ecap_sanity
);
204 bool intel_cap_nest_sanity(void)
206 return ecap_nest(intel_iommu_ecap_sanity
);
209 bool intel_cap_flts_sanity(void)
211 return ecap_flts(intel_iommu_ecap_sanity
);
214 bool intel_cap_slts_sanity(void)
216 return ecap_slts(intel_iommu_ecap_sanity
);