GNU Linux-libre 5.13.14-gnu1
[releases.git] / drivers / iommu / intel / cap_audit.h
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);