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