1 /* SPDX-License-Identifier: GPL-2.0-only */
3 * Copyright (c) 2006, Intel Corporation.
5 * Copyright (C) 2006-2008 Intel Corporation
6 * Author: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
12 #include <linux/types.h>
13 #include <linux/kernel.h>
14 #include <linux/rbtree.h>
15 #include <linux/dma-mapping.h>
20 unsigned long pfn_hi
; /* Highest allocated pfn */
21 unsigned long pfn_lo
; /* Lowest allocated pfn */
27 /* holds all the iova translations for a domain */
29 spinlock_t iova_rbtree_lock
; /* Lock to protect update of rbtree */
30 struct rb_root rbroot
; /* iova domain rbtree root */
31 struct rb_node
*cached_node
; /* Save last alloced node */
32 struct rb_node
*cached32_node
; /* Save last 32-bit alloced node */
33 unsigned long granule
; /* pfn granularity for this domain */
34 unsigned long start_pfn
; /* Lower limit for this domain */
35 unsigned long dma_32bit_pfn
;
36 unsigned long max32_alloc_size
; /* Size of last failed allocation */
37 struct iova anchor
; /* rbtree lookup anchor */
39 struct iova_rcache
*rcaches
;
40 struct hlist_node cpuhp_dead
;
43 static inline unsigned long iova_size(struct iova
*iova
)
45 return iova
->pfn_hi
- iova
->pfn_lo
+ 1;
48 static inline unsigned long iova_shift(struct iova_domain
*iovad
)
50 return __ffs(iovad
->granule
);
53 static inline unsigned long iova_mask(struct iova_domain
*iovad
)
55 return iovad
->granule
- 1;
58 static inline size_t iova_offset(struct iova_domain
*iovad
, dma_addr_t iova
)
60 return iova
& iova_mask(iovad
);
63 static inline size_t iova_align(struct iova_domain
*iovad
, size_t size
)
65 return ALIGN(size
, iovad
->granule
);
68 static inline size_t iova_align_down(struct iova_domain
*iovad
, size_t size
)
70 return ALIGN_DOWN(size
, iovad
->granule
);
73 static inline dma_addr_t
iova_dma_addr(struct iova_domain
*iovad
, struct iova
*iova
)
75 return (dma_addr_t
)iova
->pfn_lo
<< iova_shift(iovad
);
78 static inline unsigned long iova_pfn(struct iova_domain
*iovad
, dma_addr_t iova
)
80 return iova
>> iova_shift(iovad
);
83 #if IS_REACHABLE(CONFIG_IOMMU_IOVA)
84 int iova_cache_get(void);
85 void iova_cache_put(void);
87 unsigned long iova_rcache_range(void);
89 void free_iova(struct iova_domain
*iovad
, unsigned long pfn
);
90 void __free_iova(struct iova_domain
*iovad
, struct iova
*iova
);
91 struct iova
*alloc_iova(struct iova_domain
*iovad
, unsigned long size
,
92 unsigned long limit_pfn
,
94 void free_iova_fast(struct iova_domain
*iovad
, unsigned long pfn
,
96 unsigned long alloc_iova_fast(struct iova_domain
*iovad
, unsigned long size
,
97 unsigned long limit_pfn
, bool flush_rcache
);
98 struct iova
*reserve_iova(struct iova_domain
*iovad
, unsigned long pfn_lo
,
99 unsigned long pfn_hi
);
100 void init_iova_domain(struct iova_domain
*iovad
, unsigned long granule
,
101 unsigned long start_pfn
);
102 int iova_domain_init_rcaches(struct iova_domain
*iovad
);
103 struct iova
*find_iova(struct iova_domain
*iovad
, unsigned long pfn
);
104 void put_iova_domain(struct iova_domain
*iovad
);
106 static inline int iova_cache_get(void)
111 static inline void iova_cache_put(void)
115 static inline void free_iova(struct iova_domain
*iovad
, unsigned long pfn
)
119 static inline void __free_iova(struct iova_domain
*iovad
, struct iova
*iova
)
123 static inline struct iova
*alloc_iova(struct iova_domain
*iovad
,
125 unsigned long limit_pfn
,
131 static inline void free_iova_fast(struct iova_domain
*iovad
,
137 static inline unsigned long alloc_iova_fast(struct iova_domain
*iovad
,
139 unsigned long limit_pfn
,
145 static inline struct iova
*reserve_iova(struct iova_domain
*iovad
,
146 unsigned long pfn_lo
,
147 unsigned long pfn_hi
)
152 static inline void init_iova_domain(struct iova_domain
*iovad
,
153 unsigned long granule
,
154 unsigned long start_pfn
)
158 static inline struct iova
*find_iova(struct iova_domain
*iovad
,
164 static inline void put_iova_domain(struct iova_domain
*iovad
)