Merge branches 'fixes' and 'misc' into for-linus
[sfrench/cifs-2.6.git] / include / linux / iova.h
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Copyright (c) 2006, Intel Corporation.
4  *
5  * Copyright (C) 2006-2008 Intel Corporation
6  * Author: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
7  */
8
9 #ifndef _IOVA_H_
10 #define _IOVA_H_
11
12 #include <linux/types.h>
13 #include <linux/kernel.h>
14 #include <linux/rbtree.h>
15 #include <linux/dma-mapping.h>
16
17 /* iova structure */
18 struct iova {
19         struct rb_node  node;
20         unsigned long   pfn_hi; /* Highest allocated pfn */
21         unsigned long   pfn_lo; /* Lowest allocated pfn */
22 };
23
24 struct iova_magazine;
25 struct iova_cpu_rcache;
26
27 #define IOVA_RANGE_CACHE_MAX_SIZE 6     /* log of max cached IOVA range size (in pages) */
28 #define MAX_GLOBAL_MAGS 32      /* magazines per bin */
29
30 struct iova_rcache {
31         spinlock_t lock;
32         unsigned long depot_size;
33         struct iova_magazine *depot[MAX_GLOBAL_MAGS];
34         struct iova_cpu_rcache __percpu *cpu_rcaches;
35 };
36
37 /* holds all the iova translations for a domain */
38 struct iova_domain {
39         spinlock_t      iova_rbtree_lock; /* Lock to protect update of rbtree */
40         struct rb_root  rbroot;         /* iova domain rbtree root */
41         struct rb_node  *cached_node;   /* Save last alloced node */
42         struct rb_node  *cached32_node; /* Save last 32-bit alloced node */
43         unsigned long   granule;        /* pfn granularity for this domain */
44         unsigned long   start_pfn;      /* Lower limit for this domain */
45         unsigned long   dma_32bit_pfn;
46         unsigned long   max32_alloc_size; /* Size of last failed allocation */
47         struct iova     anchor;         /* rbtree lookup anchor */
48
49         struct iova_rcache rcaches[IOVA_RANGE_CACHE_MAX_SIZE];  /* IOVA range caches */
50         struct hlist_node       cpuhp_dead;
51 };
52
53 static inline unsigned long iova_size(struct iova *iova)
54 {
55         return iova->pfn_hi - iova->pfn_lo + 1;
56 }
57
58 static inline unsigned long iova_shift(struct iova_domain *iovad)
59 {
60         return __ffs(iovad->granule);
61 }
62
63 static inline unsigned long iova_mask(struct iova_domain *iovad)
64 {
65         return iovad->granule - 1;
66 }
67
68 static inline size_t iova_offset(struct iova_domain *iovad, dma_addr_t iova)
69 {
70         return iova & iova_mask(iovad);
71 }
72
73 static inline size_t iova_align(struct iova_domain *iovad, size_t size)
74 {
75         return ALIGN(size, iovad->granule);
76 }
77
78 static inline dma_addr_t iova_dma_addr(struct iova_domain *iovad, struct iova *iova)
79 {
80         return (dma_addr_t)iova->pfn_lo << iova_shift(iovad);
81 }
82
83 static inline unsigned long iova_pfn(struct iova_domain *iovad, dma_addr_t iova)
84 {
85         return iova >> iova_shift(iovad);
86 }
87
88 #if IS_ENABLED(CONFIG_IOMMU_IOVA)
89 int iova_cache_get(void);
90 void iova_cache_put(void);
91
92 void free_iova(struct iova_domain *iovad, unsigned long pfn);
93 void __free_iova(struct iova_domain *iovad, struct iova *iova);
94 struct iova *alloc_iova(struct iova_domain *iovad, unsigned long size,
95         unsigned long limit_pfn,
96         bool size_aligned);
97 void free_iova_fast(struct iova_domain *iovad, unsigned long pfn,
98                     unsigned long size);
99 unsigned long alloc_iova_fast(struct iova_domain *iovad, unsigned long size,
100                               unsigned long limit_pfn, bool flush_rcache);
101 struct iova *reserve_iova(struct iova_domain *iovad, unsigned long pfn_lo,
102         unsigned long pfn_hi);
103 void init_iova_domain(struct iova_domain *iovad, unsigned long granule,
104         unsigned long start_pfn);
105 struct iova *find_iova(struct iova_domain *iovad, unsigned long pfn);
106 void put_iova_domain(struct iova_domain *iovad);
107 #else
108 static inline int iova_cache_get(void)
109 {
110         return -ENOTSUPP;
111 }
112
113 static inline void iova_cache_put(void)
114 {
115 }
116
117 static inline void free_iova(struct iova_domain *iovad, unsigned long pfn)
118 {
119 }
120
121 static inline void __free_iova(struct iova_domain *iovad, struct iova *iova)
122 {
123 }
124
125 static inline struct iova *alloc_iova(struct iova_domain *iovad,
126                                       unsigned long size,
127                                       unsigned long limit_pfn,
128                                       bool size_aligned)
129 {
130         return NULL;
131 }
132
133 static inline void free_iova_fast(struct iova_domain *iovad,
134                                   unsigned long pfn,
135                                   unsigned long size)
136 {
137 }
138
139 static inline unsigned long alloc_iova_fast(struct iova_domain *iovad,
140                                             unsigned long size,
141                                             unsigned long limit_pfn,
142                                             bool flush_rcache)
143 {
144         return 0;
145 }
146
147 static inline struct iova *reserve_iova(struct iova_domain *iovad,
148                                         unsigned long pfn_lo,
149                                         unsigned long pfn_hi)
150 {
151         return NULL;
152 }
153
154 static inline void init_iova_domain(struct iova_domain *iovad,
155                                     unsigned long granule,
156                                     unsigned long start_pfn)
157 {
158 }
159
160 static inline struct iova *find_iova(struct iova_domain *iovad,
161                                      unsigned long pfn)
162 {
163         return NULL;
164 }
165
166 static inline void put_iova_domain(struct iova_domain *iovad)
167 {
168 }
169
170 #endif
171
172 #endif