aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/iova.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/iova.h')
-rw-r--r--include/linux/iova.h41
1 files changed, 37 insertions, 4 deletions
diff --git a/include/linux/iova.h b/include/linux/iova.h
index 19e81d5ccb6d..3920a19d8194 100644
--- a/include/linux/iova.h
+++ b/include/linux/iova.h
@@ -16,9 +16,6 @@
16#include <linux/rbtree.h> 16#include <linux/rbtree.h>
17#include <linux/dma-mapping.h> 17#include <linux/dma-mapping.h>
18 18
19/* IO virtual address start page frame number */
20#define IOVA_START_PFN (1)
21
22/* iova structure */ 19/* iova structure */
23struct iova { 20struct iova {
24 struct rb_node node; 21 struct rb_node node;
@@ -31,6 +28,8 @@ struct iova_domain {
31 spinlock_t iova_rbtree_lock; /* Lock to protect update of rbtree */ 28 spinlock_t iova_rbtree_lock; /* Lock to protect update of rbtree */
32 struct rb_root rbroot; /* iova domain rbtree root */ 29 struct rb_root rbroot; /* iova domain rbtree root */
33 struct rb_node *cached32_node; /* Save last alloced node */ 30 struct rb_node *cached32_node; /* Save last alloced node */
31 unsigned long granule; /* pfn granularity for this domain */
32 unsigned long start_pfn; /* Lower limit for this domain */
34 unsigned long dma_32bit_pfn; 33 unsigned long dma_32bit_pfn;
35}; 34};
36 35
@@ -39,6 +38,39 @@ static inline unsigned long iova_size(struct iova *iova)
39 return iova->pfn_hi - iova->pfn_lo + 1; 38 return iova->pfn_hi - iova->pfn_lo + 1;
40} 39}
41 40
41static inline unsigned long iova_shift(struct iova_domain *iovad)
42{
43 return __ffs(iovad->granule);
44}
45
46static inline unsigned long iova_mask(struct iova_domain *iovad)
47{
48 return iovad->granule - 1;
49}
50
51static inline size_t iova_offset(struct iova_domain *iovad, dma_addr_t iova)
52{
53 return iova & iova_mask(iovad);
54}
55
56static inline size_t iova_align(struct iova_domain *iovad, size_t size)
57{
58 return ALIGN(size, iovad->granule);
59}
60
61static inline dma_addr_t iova_dma_addr(struct iova_domain *iovad, struct iova *iova)
62{
63 return (dma_addr_t)iova->pfn_lo << iova_shift(iovad);
64}
65
66static inline unsigned long iova_pfn(struct iova_domain *iovad, dma_addr_t iova)
67{
68 return iova >> iova_shift(iovad);
69}
70
71int iommu_iova_cache_init(void);
72void iommu_iova_cache_destroy(void);
73
42struct iova *alloc_iova_mem(void); 74struct iova *alloc_iova_mem(void);
43void free_iova_mem(struct iova *iova); 75void free_iova_mem(struct iova *iova);
44void free_iova(struct iova_domain *iovad, unsigned long pfn); 76void free_iova(struct iova_domain *iovad, unsigned long pfn);
@@ -49,7 +81,8 @@ struct iova *alloc_iova(struct iova_domain *iovad, unsigned long size,
49struct iova *reserve_iova(struct iova_domain *iovad, unsigned long pfn_lo, 81struct iova *reserve_iova(struct iova_domain *iovad, unsigned long pfn_lo,
50 unsigned long pfn_hi); 82 unsigned long pfn_hi);
51void copy_reserved_iova(struct iova_domain *from, struct iova_domain *to); 83void copy_reserved_iova(struct iova_domain *from, struct iova_domain *to);
52void init_iova_domain(struct iova_domain *iovad, unsigned long pfn_32bit); 84void init_iova_domain(struct iova_domain *iovad, unsigned long granule,
85 unsigned long start_pfn, unsigned long pfn_32bit);
53struct iova *find_iova(struct iova_domain *iovad, unsigned long pfn); 86struct iova *find_iova(struct iova_domain *iovad, unsigned long pfn);
54void put_iova_domain(struct iova_domain *iovad); 87void put_iova_domain(struct iova_domain *iovad);
55struct iova *split_and_remove_iova(struct iova_domain *iovad, 88struct iova *split_and_remove_iova(struct iova_domain *iovad,