^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * pasid.h - PASID idr, table and entry header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (C) 2018 Intel Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Author: Lu Baolu <baolu.lu@linux.intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #ifndef __INTEL_PASID_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #define __INTEL_PASID_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #define PASID_RID2PASID			0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #define PASID_MIN			0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #define PASID_MAX			0x100000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #define PASID_PTE_MASK			0x3F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #define PASID_PTE_PRESENT		1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #define PASID_PTE_FPD			2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #define PDE_PFN_MASK			PAGE_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #define PASID_PDE_SHIFT			6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #define MAX_NR_PASID_BITS		20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #define PASID_TBL_ENTRIES		BIT(PASID_PDE_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define is_pasid_enabled(entry)		(((entry)->lo >> 3) & 0x1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define get_pasid_dir_size(entry)	(1 << ((((entry)->lo >> 9) & 0x7) + 7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) /* Virtual command interface for enlightened pasid management. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #define VCMD_CMD_ALLOC			0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #define VCMD_CMD_FREE			0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #define VCMD_VRSP_IP			0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #define VCMD_VRSP_SC(e)			(((e) & 0xff) >> 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define VCMD_VRSP_SC_SUCCESS		0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #define VCMD_VRSP_SC_NO_PASID_AVAIL	16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #define VCMD_VRSP_SC_INVALID_PASID	16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #define VCMD_VRSP_RESULT_PASID(e)	(((e) >> 16) & 0xfffff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #define VCMD_CMD_OPERAND(e)		((e) << 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)  * Domain ID reserved for pasid entries programmed for first-level
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  * only and pass-through transfer modes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #define FLPT_DEFAULT_DID		1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44)  * The SUPERVISOR_MODE flag indicates a first level translation which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45)  * can be used for access to kernel addresses. It is valid only for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46)  * access to the kernel's static 1:1 mapping of physical memory — not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47)  * to vmalloc or even module mappings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) #define PASID_FLAG_SUPERVISOR_MODE	BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) #define PASID_FLAG_NESTED		BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) #define PASID_FLAG_PAGE_SNOOP		BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54)  * The PASID_FLAG_FL5LP flag Indicates using 5-level paging for first-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)  * level translation, otherwise, 4-level paging will be used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) #define PASID_FLAG_FL5LP		BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) struct pasid_dir_entry {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	u64 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) struct pasid_entry {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	u64 val[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) #define PASID_ENTRY_PGTT_FL_ONLY	(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) #define PASID_ENTRY_PGTT_SL_ONLY	(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) #define PASID_ENTRY_PGTT_NESTED		(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) #define PASID_ENTRY_PGTT_PT		(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) /* The representative of a PASID table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) struct pasid_table {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	void			*table;		/* pasid table pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	int			order;		/* page order of pasid table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	u32			max_pasid;	/* max pasid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	struct list_head	dev;		/* device list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) /* Get PRESENT bit of a PASID directory entry. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) static inline bool pasid_pde_is_present(struct pasid_dir_entry *pde)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	return READ_ONCE(pde->val) & PASID_PTE_PRESENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) /* Get PASID table from a PASID directory entry. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) static inline struct pasid_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) get_pasid_table_from_pde(struct pasid_dir_entry *pde)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	if (!pasid_pde_is_present(pde))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	return phys_to_virt(READ_ONCE(pde->val) & PDE_PFN_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) /* Get PRESENT bit of a PASID table entry. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) static inline bool pasid_pte_is_present(struct pasid_entry *pte)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	return READ_ONCE(pte->val[0]) & PASID_PTE_PRESENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) /* Get PGTT field of a PASID table entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) static inline u16 pasid_pte_get_pgtt(struct pasid_entry *pte)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	return (u16)((READ_ONCE(pte->val[0]) >> 6) & 0x7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) extern unsigned int intel_pasid_max_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) int intel_pasid_alloc_id(void *ptr, int start, int end, gfp_t gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) void intel_pasid_free_id(u32 pasid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) void *intel_pasid_lookup_id(u32 pasid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) int intel_pasid_alloc_table(struct device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) void intel_pasid_free_table(struct device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) struct pasid_table *intel_pasid_get_table(struct device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) int intel_pasid_get_dev_max_id(struct device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) struct pasid_entry *intel_pasid_get_entry(struct device *dev, u32 pasid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) int intel_pasid_setup_first_level(struct intel_iommu *iommu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 				  struct device *dev, pgd_t *pgd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 				  u32 pasid, u16 did, int flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) int intel_pasid_setup_second_level(struct intel_iommu *iommu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 				   struct dmar_domain *domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 				   struct device *dev, u32 pasid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) int intel_pasid_setup_pass_through(struct intel_iommu *iommu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 				   struct dmar_domain *domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 				   struct device *dev, u32 pasid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) int intel_pasid_setup_nested(struct intel_iommu *iommu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 			     struct device *dev, pgd_t *pgd, u32 pasid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 			     struct iommu_gpasid_bind_data_vtd *pasid_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 			     struct dmar_domain *domain, int addr_width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) void intel_pasid_tear_down_entry(struct intel_iommu *iommu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 				 struct device *dev, u32 pasid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 				 bool fault_ignore);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) int vcmd_alloc_pasid(struct intel_iommu *iommu, u32 *pasid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) void vcmd_free_pasid(struct intel_iommu *iommu, u32 pasid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #endif /* __INTEL_PASID_H */