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