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) \
68do { \
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) \
79do { \
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) \
86do { \
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) \
94do { \
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
103enum 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
110bool intel_cap_smts_sanity(void);
111bool intel_cap_pasid_sanity(void);
112bool intel_cap_nest_sanity(void);
113bool intel_cap_flts_sanity(void);
114bool intel_cap_slts_sanity(void);
115
116static inline bool scalable_mode_support(void)
117{
118 return (intel_iommu_sm && intel_cap_smts_sanity());
119}
120
121static inline bool pasid_mode_support(void)
122{
123 return scalable_mode_support() && intel_cap_pasid_sanity();
124}
125
126static inline bool nested_mode_support(void)
127{
128 return scalable_mode_support() && intel_cap_nest_sanity();
129}
130
131int intel_cap_audit(enum cap_audit_type type, struct intel_iommu *iommu);
132

source code of linux/drivers/iommu/intel/cap_audit.h