Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * cap_audit.h - audit iommu capabilities header
0004  *
0005  * Copyright (C) 2021 Intel Corporation
0006  *
0007  * Author: Kyung Min Park <kyung.min.park@intel.com>
0008  */
0009 
0010 /*
0011  * Capability Register Mask
0012  */
0013 #define CAP_FL5LP_MASK      BIT_ULL(60)
0014 #define CAP_PI_MASK     BIT_ULL(59)
0015 #define CAP_FL1GP_MASK      BIT_ULL(56)
0016 #define CAP_RD_MASK     BIT_ULL(55)
0017 #define CAP_WD_MASK     BIT_ULL(54)
0018 #define CAP_MAMV_MASK       GENMASK_ULL(53, 48)
0019 #define CAP_NFR_MASK        GENMASK_ULL(47, 40)
0020 #define CAP_PSI_MASK        BIT_ULL(39)
0021 #define CAP_SLLPS_MASK      GENMASK_ULL(37, 34)
0022 #define CAP_FRO_MASK        GENMASK_ULL(33, 24)
0023 #define CAP_ZLR_MASK        BIT_ULL(22)
0024 #define CAP_MGAW_MASK       GENMASK_ULL(21, 16)
0025 #define CAP_SAGAW_MASK      GENMASK_ULL(12, 8)
0026 #define CAP_CM_MASK     BIT_ULL(7)
0027 #define CAP_PHMR_MASK       BIT_ULL(6)
0028 #define CAP_PLMR_MASK       BIT_ULL(5)
0029 #define CAP_RWBF_MASK       BIT_ULL(4)
0030 #define CAP_AFL_MASK        BIT_ULL(3)
0031 #define CAP_NDOMS_MASK      GENMASK_ULL(2, 0)
0032 
0033 /*
0034  * Extended Capability Register Mask
0035  */
0036 #define ECAP_RPS_MASK       BIT_ULL(49)
0037 #define ECAP_SMPWC_MASK     BIT_ULL(48)
0038 #define ECAP_FLTS_MASK      BIT_ULL(47)
0039 #define ECAP_SLTS_MASK      BIT_ULL(46)
0040 #define ECAP_SLADS_MASK     BIT_ULL(45)
0041 #define ECAP_VCS_MASK       BIT_ULL(44)
0042 #define ECAP_SMTS_MASK      BIT_ULL(43)
0043 #define ECAP_PDS_MASK       BIT_ULL(42)
0044 #define ECAP_DIT_MASK       BIT_ULL(41)
0045 #define ECAP_PASID_MASK     BIT_ULL(40)
0046 #define ECAP_PSS_MASK       GENMASK_ULL(39, 35)
0047 #define ECAP_EAFS_MASK      BIT_ULL(34)
0048 #define ECAP_NWFS_MASK      BIT_ULL(33)
0049 #define ECAP_SRS_MASK       BIT_ULL(31)
0050 #define ECAP_ERS_MASK       BIT_ULL(30)
0051 #define ECAP_PRS_MASK       BIT_ULL(29)
0052 #define ECAP_NEST_MASK      BIT_ULL(26)
0053 #define ECAP_MTS_MASK       BIT_ULL(25)
0054 #define ECAP_MHMV_MASK      GENMASK_ULL(23, 20)
0055 #define ECAP_IRO_MASK       GENMASK_ULL(17, 8)
0056 #define ECAP_SC_MASK        BIT_ULL(7)
0057 #define ECAP_PT_MASK        BIT_ULL(6)
0058 #define ECAP_EIM_MASK       BIT_ULL(4)
0059 #define ECAP_DT_MASK        BIT_ULL(2)
0060 #define ECAP_QI_MASK        BIT_ULL(1)
0061 #define ECAP_C_MASK     BIT_ULL(0)
0062 
0063 /*
0064  * u64 intel_iommu_cap_sanity, intel_iommu_ecap_sanity will be adjusted as each
0065  * IOMMU gets audited.
0066  */
0067 #define DO_CHECK_FEATURE_MISMATCH(a, b, cap, feature, MASK) \
0068 do { \
0069     if (cap##_##feature(a) != cap##_##feature(b)) { \
0070         intel_iommu_##cap##_sanity &= ~(MASK); \
0071         pr_info("IOMMU feature %s inconsistent", #feature); \
0072     } \
0073 } while (0)
0074 
0075 #define CHECK_FEATURE_MISMATCH(a, b, cap, feature, MASK) \
0076     DO_CHECK_FEATURE_MISMATCH((a)->cap, (b)->cap, cap, feature, MASK)
0077 
0078 #define CHECK_FEATURE_MISMATCH_HOTPLUG(b, cap, feature, MASK) \
0079 do { \
0080     if (cap##_##feature(intel_iommu_##cap##_sanity)) \
0081         DO_CHECK_FEATURE_MISMATCH(intel_iommu_##cap##_sanity, \
0082                       (b)->cap, cap, feature, MASK); \
0083 } while (0)
0084 
0085 #define MINIMAL_FEATURE_IOMMU(iommu, cap, MASK) \
0086 do { \
0087     u64 min_feature = intel_iommu_##cap##_sanity & (MASK); \
0088     min_feature = min_t(u64, min_feature, (iommu)->cap & (MASK)); \
0089     intel_iommu_##cap##_sanity = (intel_iommu_##cap##_sanity & ~(MASK)) | \
0090                      min_feature; \
0091 } while (0)
0092 
0093 #define MINIMAL_FEATURE_HOTPLUG(iommu, cap, feature, MASK, mismatch) \
0094 do { \
0095     if ((intel_iommu_##cap##_sanity & (MASK)) > \
0096         (cap##_##feature((iommu)->cap))) \
0097         mismatch = true; \
0098     else \
0099         (iommu)->cap = ((iommu)->cap & ~(MASK)) | \
0100         (intel_iommu_##cap##_sanity & (MASK)); \
0101 } while (0)
0102 
0103 enum cap_audit_type {
0104     CAP_AUDIT_STATIC_DMAR,
0105     CAP_AUDIT_STATIC_IRQR,
0106     CAP_AUDIT_HOTPLUG_DMAR,
0107     CAP_AUDIT_HOTPLUG_IRQR,
0108 };
0109 
0110 bool intel_cap_smts_sanity(void);
0111 bool intel_cap_pasid_sanity(void);
0112 bool intel_cap_nest_sanity(void);
0113 bool intel_cap_flts_sanity(void);
0114 bool intel_cap_slts_sanity(void);
0115 
0116 static inline bool scalable_mode_support(void)
0117 {
0118     return (intel_iommu_sm && intel_cap_smts_sanity());
0119 }
0120 
0121 static inline bool pasid_mode_support(void)
0122 {
0123     return scalable_mode_support() && intel_cap_pasid_sanity();
0124 }
0125 
0126 static inline bool nested_mode_support(void)
0127 {
0128     return scalable_mode_support() && intel_cap_nest_sanity();
0129 }
0130 
0131 int intel_cap_audit(enum cap_audit_type type, struct intel_iommu *iommu);