0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef __INTEL_PASID_H
0011 #define __INTEL_PASID_H
0012
0013 #define PASID_RID2PASID 0x0
0014 #define PASID_MIN 0x1
0015 #define PASID_MAX 0x100000
0016 #define PASID_PTE_MASK 0x3F
0017 #define PASID_PTE_PRESENT 1
0018 #define PASID_PTE_FPD 2
0019 #define PDE_PFN_MASK PAGE_MASK
0020 #define PASID_PDE_SHIFT 6
0021 #define MAX_NR_PASID_BITS 20
0022 #define PASID_TBL_ENTRIES BIT(PASID_PDE_SHIFT)
0023
0024 #define is_pasid_enabled(entry) (((entry)->lo >> 3) & 0x1)
0025 #define get_pasid_dir_size(entry) (1 << ((((entry)->lo >> 9) & 0x7) + 7))
0026
0027
0028 #define VCMD_CMD_ALLOC 0x1
0029 #define VCMD_CMD_FREE 0x2
0030 #define VCMD_VRSP_IP 0x1
0031 #define VCMD_VRSP_SC(e) (((e) & 0xff) >> 1)
0032 #define VCMD_VRSP_SC_SUCCESS 0
0033 #define VCMD_VRSP_SC_NO_PASID_AVAIL 16
0034 #define VCMD_VRSP_SC_INVALID_PASID 16
0035 #define VCMD_VRSP_RESULT_PASID(e) (((e) >> 16) & 0xfffff)
0036 #define VCMD_CMD_OPERAND(e) ((e) << 16)
0037
0038
0039
0040
0041 #define FLPT_DEFAULT_DID 1
0042 #define NUM_RESERVED_DID 2
0043
0044
0045
0046
0047
0048
0049
0050 #define PASID_FLAG_SUPERVISOR_MODE BIT(0)
0051 #define PASID_FLAG_NESTED BIT(1)
0052 #define PASID_FLAG_PAGE_SNOOP BIT(2)
0053
0054
0055
0056
0057
0058 #define PASID_FLAG_FL5LP BIT(1)
0059
0060 struct pasid_dir_entry {
0061 u64 val;
0062 };
0063
0064 struct pasid_entry {
0065 u64 val[8];
0066 };
0067
0068 #define PASID_ENTRY_PGTT_FL_ONLY (1)
0069 #define PASID_ENTRY_PGTT_SL_ONLY (2)
0070 #define PASID_ENTRY_PGTT_NESTED (3)
0071 #define PASID_ENTRY_PGTT_PT (4)
0072
0073
0074 struct pasid_table {
0075 void *table;
0076 int order;
0077 u32 max_pasid;
0078 };
0079
0080
0081 static inline bool pasid_pde_is_present(struct pasid_dir_entry *pde)
0082 {
0083 return READ_ONCE(pde->val) & PASID_PTE_PRESENT;
0084 }
0085
0086
0087 static inline struct pasid_entry *
0088 get_pasid_table_from_pde(struct pasid_dir_entry *pde)
0089 {
0090 if (!pasid_pde_is_present(pde))
0091 return NULL;
0092
0093 return phys_to_virt(READ_ONCE(pde->val) & PDE_PFN_MASK);
0094 }
0095
0096
0097 static inline bool pasid_pte_is_present(struct pasid_entry *pte)
0098 {
0099 return READ_ONCE(pte->val[0]) & PASID_PTE_PRESENT;
0100 }
0101
0102
0103 static inline u16 pasid_pte_get_pgtt(struct pasid_entry *pte)
0104 {
0105 return (u16)((READ_ONCE(pte->val[0]) >> 6) & 0x7);
0106 }
0107
0108 extern unsigned int intel_pasid_max_id;
0109 int intel_pasid_alloc_table(struct device *dev);
0110 void intel_pasid_free_table(struct device *dev);
0111 struct pasid_table *intel_pasid_get_table(struct device *dev);
0112 int intel_pasid_setup_first_level(struct intel_iommu *iommu,
0113 struct device *dev, pgd_t *pgd,
0114 u32 pasid, u16 did, int flags);
0115 int intel_pasid_setup_second_level(struct intel_iommu *iommu,
0116 struct dmar_domain *domain,
0117 struct device *dev, u32 pasid);
0118 int intel_pasid_setup_pass_through(struct intel_iommu *iommu,
0119 struct dmar_domain *domain,
0120 struct device *dev, u32 pasid);
0121 void intel_pasid_tear_down_entry(struct intel_iommu *iommu,
0122 struct device *dev, u32 pasid,
0123 bool fault_ignore);
0124 int vcmd_alloc_pasid(struct intel_iommu *iommu, u32 *pasid);
0125 void vcmd_free_pasid(struct intel_iommu *iommu, u32 pasid);
0126 void intel_pasid_setup_page_snoop_control(struct intel_iommu *iommu,
0127 struct device *dev, u32 pasid);
0128 #endif