Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * pasid.h - PASID idr, table and entry header
0004  *
0005  * Copyright (C) 2018 Intel Corporation
0006  *
0007  * Author: Lu Baolu <baolu.lu@linux.intel.com>
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 /* Virtual command interface for enlightened pasid management. */
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  * Domain ID reserved for pasid entries programmed for first-level
0039  * only and pass-through transfer modes.
0040  */
0041 #define FLPT_DEFAULT_DID        1
0042 #define NUM_RESERVED_DID        2
0043 
0044 /*
0045  * The SUPERVISOR_MODE flag indicates a first level translation which
0046  * can be used for access to kernel addresses. It is valid only for
0047  * access to the kernel's static 1:1 mapping of physical memory — not
0048  * to vmalloc or even module mappings.
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  * The PASID_FLAG_FL5LP flag Indicates using 5-level paging for first-
0056  * level translation, otherwise, 4-level paging will be used.
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 /* The representative of a PASID table */
0074 struct pasid_table {
0075     void            *table;     /* pasid table pointer */
0076     int         order;      /* page order of pasid table */
0077     u32         max_pasid;  /* max pasid */
0078 };
0079 
0080 /* Get PRESENT bit of a PASID directory entry. */
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 /* Get PASID table from a PASID directory entry. */
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 /* Get PRESENT bit of a PASID table entry. */
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 /* Get PGTT field of a PASID table entry */
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 /* __INTEL_PASID_H */