include/linux/dma_remapping.h
changeset 0 aa628870c1d3
child 2 d1f6d8b6f81c
equal deleted inserted replaced
-1:000000000000 0:aa628870c1d3
       
     1 #ifndef _DMA_REMAPPING_H
       
     2 #define _DMA_REMAPPING_H
       
     3 
       
     4 /*
       
     5  * VT-d hardware uses 4KiB page size regardless of host page size.
       
     6  */
       
     7 #define VTD_PAGE_SHIFT		(12)
       
     8 #define VTD_PAGE_SIZE		(1UL << VTD_PAGE_SHIFT)
       
     9 #define VTD_PAGE_MASK		(((u64)-1) << VTD_PAGE_SHIFT)
       
    10 #define VTD_PAGE_ALIGN(addr)	(((addr) + VTD_PAGE_SIZE - 1) & VTD_PAGE_MASK)
       
    11 
       
    12 #define IOVA_PFN(addr)		((addr) >> PAGE_SHIFT)
       
    13 #define DMA_32BIT_PFN		IOVA_PFN(DMA_32BIT_MASK)
       
    14 #define DMA_64BIT_PFN		IOVA_PFN(DMA_64BIT_MASK)
       
    15 
       
    16 
       
    17 /*
       
    18  * 0: Present
       
    19  * 1-11: Reserved
       
    20  * 12-63: Context Ptr (12 - (haw-1))
       
    21  * 64-127: Reserved
       
    22  */
       
    23 struct root_entry {
       
    24 	u64	val;
       
    25 	u64	rsvd1;
       
    26 };
       
    27 #define ROOT_ENTRY_NR (VTD_PAGE_SIZE/sizeof(struct root_entry))
       
    28 static inline bool root_present(struct root_entry *root)
       
    29 {
       
    30 	return (root->val & 1);
       
    31 }
       
    32 static inline void set_root_present(struct root_entry *root)
       
    33 {
       
    34 	root->val |= 1;
       
    35 }
       
    36 static inline void set_root_value(struct root_entry *root, unsigned long value)
       
    37 {
       
    38 	root->val |= value & VTD_PAGE_MASK;
       
    39 }
       
    40 
       
    41 struct context_entry;
       
    42 static inline struct context_entry *
       
    43 get_context_addr_from_root(struct root_entry *root)
       
    44 {
       
    45 	return (struct context_entry *)
       
    46 		(root_present(root)?phys_to_virt(
       
    47 		root->val & VTD_PAGE_MASK) :
       
    48 		NULL);
       
    49 }
       
    50 
       
    51 /*
       
    52  * low 64 bits:
       
    53  * 0: present
       
    54  * 1: fault processing disable
       
    55  * 2-3: translation type
       
    56  * 12-63: address space root
       
    57  * high 64 bits:
       
    58  * 0-2: address width
       
    59  * 3-6: aval
       
    60  * 8-23: domain id
       
    61  */
       
    62 struct context_entry {
       
    63 	u64 lo;
       
    64 	u64 hi;
       
    65 };
       
    66 #define context_present(c) ((c).lo & 1)
       
    67 #define context_fault_disable(c) (((c).lo >> 1) & 1)
       
    68 #define context_translation_type(c) (((c).lo >> 2) & 3)
       
    69 #define context_address_root(c) ((c).lo & VTD_PAGE_MASK)
       
    70 #define context_address_width(c) ((c).hi &  7)
       
    71 #define context_domain_id(c) (((c).hi >> 8) & ((1 << 16) - 1))
       
    72 
       
    73 #define context_set_present(c) do {(c).lo |= 1;} while (0)
       
    74 #define context_set_fault_enable(c) \
       
    75 	do {(c).lo &= (((u64)-1) << 2) | 1;} while (0)
       
    76 #define context_set_translation_type(c, val) \
       
    77 	do { \
       
    78 		(c).lo &= (((u64)-1) << 4) | 3; \
       
    79 		(c).lo |= ((val) & 3) << 2; \
       
    80 	} while (0)
       
    81 #define CONTEXT_TT_MULTI_LEVEL 0
       
    82 #define context_set_address_root(c, val) \
       
    83 	do {(c).lo |= (val) & VTD_PAGE_MASK; } while (0)
       
    84 #define context_set_address_width(c, val) do {(c).hi |= (val) & 7;} while (0)
       
    85 #define context_set_domain_id(c, val) \
       
    86 	do {(c).hi |= ((val) & ((1 << 16) - 1)) << 8;} while (0)
       
    87 #define context_clear_entry(c) do {(c).lo = 0; (c).hi = 0;} while (0)
       
    88 
       
    89 /*
       
    90  * 0: readable
       
    91  * 1: writable
       
    92  * 2-6: reserved
       
    93  * 7: super page
       
    94  * 8-11: available
       
    95  * 12-63: Host physcial address
       
    96  */
       
    97 struct dma_pte {
       
    98 	u64 val;
       
    99 };
       
   100 #define dma_clear_pte(p)	do {(p).val = 0;} while (0)
       
   101 
       
   102 #define DMA_PTE_READ (1)
       
   103 #define DMA_PTE_WRITE (2)
       
   104 
       
   105 #define dma_set_pte_readable(p) do {(p).val |= DMA_PTE_READ;} while (0)
       
   106 #define dma_set_pte_writable(p) do {(p).val |= DMA_PTE_WRITE;} while (0)
       
   107 #define dma_set_pte_prot(p, prot) \
       
   108 		do {(p).val = ((p).val & ~3) | ((prot) & 3); } while (0)
       
   109 #define dma_pte_addr(p) ((p).val & VTD_PAGE_MASK)
       
   110 #define dma_set_pte_addr(p, addr) do {\
       
   111 		(p).val |= ((addr) & VTD_PAGE_MASK); } while (0)
       
   112 #define dma_pte_present(p) (((p).val & 3) != 0)
       
   113 
       
   114 struct intel_iommu;
       
   115 
       
   116 struct dmar_domain {
       
   117 	int	id;			/* domain id */
       
   118 	struct intel_iommu *iommu;	/* back pointer to owning iommu */
       
   119 
       
   120 	struct list_head devices; 	/* all devices' list */
       
   121 	struct iova_domain iovad;	/* iova's that belong to this domain */
       
   122 
       
   123 	struct dma_pte	*pgd;		/* virtual address */
       
   124 	spinlock_t	mapping_lock;	/* page table lock */
       
   125 	int		gaw;		/* max guest address width */
       
   126 
       
   127 	/* adjusted guest address width, 0 is level 2 30-bit */
       
   128 	int		agaw;
       
   129 
       
   130 #define DOMAIN_FLAG_MULTIPLE_DEVICES 1
       
   131 	int		flags;
       
   132 };
       
   133 
       
   134 /* PCI domain-device relationship */
       
   135 struct device_domain_info {
       
   136 	struct list_head link;	/* link to domain siblings */
       
   137 	struct list_head global; /* link to global list */
       
   138 	u8 bus;			/* PCI bus numer */
       
   139 	u8 devfn;		/* PCI devfn number */
       
   140 	struct pci_dev *dev; /* it's NULL for PCIE-to-PCI bridge */
       
   141 	struct dmar_domain *domain; /* pointer to domain */
       
   142 };
       
   143 
       
   144 extern int init_dmars(void);
       
   145 extern void free_dmar_iommu(struct intel_iommu *iommu);
       
   146 
       
   147 extern int dmar_disabled;
       
   148 
       
   149 #ifndef CONFIG_DMAR_GFX_WA
       
   150 static inline void iommu_prepare_gfx_mapping(void)
       
   151 {
       
   152 	return;
       
   153 }
       
   154 #endif /* !CONFIG_DMAR_GFX_WA */
       
   155 
       
   156 #endif