]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
1 | /* SPDX-License-Identifier: BSD-3-Clause |
2 | * Copyright(c) 2017 6WIND S.A. | |
3 | */ | |
4 | ||
5 | #ifndef _RTE_VFIO_H_ | |
6 | #define _RTE_VFIO_H_ | |
7 | ||
8 | /** | |
9 | * @file | |
10 | * RTE VFIO. This library provides various VFIO related utility functions. | |
11 | */ | |
12 | ||
13 | #ifdef __cplusplus | |
14 | extern "C" { | |
15 | #endif | |
16 | ||
9f95a23c TL |
17 | #include <stdint.h> |
18 | ||
11fdf7f2 TL |
19 | /* |
20 | * determine if VFIO is present on the system | |
21 | */ | |
22 | #if !defined(VFIO_PRESENT) && defined(RTE_EAL_VFIO) | |
23 | #include <linux/version.h> | |
24 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0) | |
25 | #define VFIO_PRESENT | |
26 | #endif /* kernel version >= 3.6.0 */ | |
9f95a23c TL |
27 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) |
28 | #define HAVE_VFIO_DEV_REQ_INTERFACE | |
29 | #endif /* kernel version >= 4.0.0 */ | |
11fdf7f2 TL |
30 | #endif /* RTE_EAL_VFIO */ |
31 | ||
32 | #ifdef VFIO_PRESENT | |
33 | ||
34 | #include <linux/vfio.h> | |
35 | ||
36 | #define VFIO_DIR "/dev/vfio" | |
37 | #define VFIO_CONTAINER_PATH "/dev/vfio/vfio" | |
38 | #define VFIO_GROUP_FMT "/dev/vfio/%u" | |
39 | #define VFIO_NOIOMMU_GROUP_FMT "/dev/vfio/noiommu-%u" | |
40 | #define VFIO_GET_REGION_ADDR(x) ((uint64_t) x << 40ULL) | |
41 | #define VFIO_GET_REGION_IDX(x) (x >> 40) | |
42 | #define VFIO_NOIOMMU_MODE \ | |
43 | "/sys/module/vfio/parameters/enable_unsafe_noiommu_mode" | |
44 | ||
45 | /* NOIOMMU is defined from kernel version 4.5 onwards */ | |
46 | #ifdef VFIO_NOIOMMU_IOMMU | |
47 | #define RTE_VFIO_NOIOMMU VFIO_NOIOMMU_IOMMU | |
48 | #else | |
49 | #define RTE_VFIO_NOIOMMU 8 | |
50 | #endif | |
51 | ||
9f95a23c TL |
52 | /* |
53 | * capabilities are only supported on kernel 4.6+. there were also some API | |
54 | * changes as well, so add a macro to get cap offset. | |
55 | */ | |
56 | #ifdef VFIO_REGION_INFO_FLAG_CAPS | |
57 | #define RTE_VFIO_INFO_FLAG_CAPS VFIO_REGION_INFO_FLAG_CAPS | |
58 | #define VFIO_CAP_OFFSET(x) (x->cap_offset) | |
59 | #else | |
60 | #define RTE_VFIO_INFO_FLAG_CAPS (1 << 3) | |
61 | #define VFIO_CAP_OFFSET(x) (x->resv) | |
62 | struct vfio_info_cap_header { | |
63 | uint16_t id; | |
64 | uint16_t version; | |
65 | uint32_t next; | |
66 | }; | |
67 | #endif | |
68 | ||
69 | /* kernels 4.16+ can map BAR containing MSI-X table */ | |
70 | #ifdef VFIO_REGION_INFO_CAP_MSIX_MAPPABLE | |
71 | #define RTE_VFIO_CAP_MSIX_MAPPABLE VFIO_REGION_INFO_CAP_MSIX_MAPPABLE | |
72 | #else | |
73 | #define RTE_VFIO_CAP_MSIX_MAPPABLE 3 | |
74 | #endif | |
75 | ||
11fdf7f2 TL |
76 | #else /* not VFIO_PRESENT */ |
77 | ||
78 | /* we don't need an actual definition, only pointer is used */ | |
79 | struct vfio_device_info; | |
80 | ||
81 | #endif /* VFIO_PRESENT */ | |
82 | ||
9f95a23c TL |
83 | #define RTE_VFIO_DEFAULT_CONTAINER_FD (-1) |
84 | ||
11fdf7f2 TL |
85 | /** |
86 | * Setup vfio_cfg for the device identified by its address. | |
87 | * It discovers the configured I/O MMU groups or sets a new one for the device. | |
88 | * If a new groups is assigned, the DMA mapping is performed. | |
89 | * | |
90 | * This function is only relevant to linux and will return | |
91 | * an error on BSD. | |
92 | * | |
93 | * @param sysfs_base | |
94 | * sysfs path prefix. | |
95 | * | |
96 | * @param dev_addr | |
97 | * device location. | |
98 | * | |
99 | * @param vfio_dev_fd | |
100 | * VFIO fd. | |
101 | * | |
102 | * @param device_info | |
103 | * Device information. | |
104 | * | |
105 | * @return | |
106 | * 0 on success. | |
107 | * <0 on failure. | |
108 | * >1 if the device cannot be managed this way. | |
109 | */ | |
110 | int rte_vfio_setup_device(const char *sysfs_base, const char *dev_addr, | |
111 | int *vfio_dev_fd, struct vfio_device_info *device_info); | |
112 | ||
113 | /** | |
114 | * Release a device mapped to a VFIO-managed I/O MMU group. | |
115 | * | |
116 | * This function is only relevant to linux and will return | |
117 | * an error on BSD. | |
118 | * | |
119 | * @param sysfs_base | |
120 | * sysfs path prefix. | |
121 | * | |
122 | * @param dev_addr | |
123 | * device location. | |
124 | * | |
125 | * @param fd | |
126 | * VFIO fd. | |
127 | * | |
128 | * @return | |
129 | * 0 on success. | |
130 | * <0 on failure. | |
131 | */ | |
132 | int rte_vfio_release_device(const char *sysfs_base, const char *dev_addr, int fd); | |
133 | ||
134 | /** | |
135 | * Enable a VFIO-related kmod. | |
136 | * | |
137 | * This function is only relevant to linux and will return | |
138 | * an error on BSD. | |
139 | * | |
140 | * @param modname | |
141 | * kernel module name. | |
142 | * | |
143 | * @return | |
144 | * 0 on success. | |
145 | * <0 on failure. | |
146 | */ | |
147 | int rte_vfio_enable(const char *modname); | |
148 | ||
149 | /** | |
150 | * Check whether a VFIO-related kmod is enabled. | |
151 | * | |
152 | * This function is only relevant to linux and will return | |
153 | * an error on BSD. | |
154 | * | |
155 | * @param modname | |
156 | * kernel module name. | |
157 | * | |
158 | * @return | |
159 | * !0 if true. | |
160 | * 0 otherwise. | |
161 | */ | |
162 | int rte_vfio_is_enabled(const char *modname); | |
163 | ||
164 | /** | |
165 | * Whether VFIO NOIOMMU mode is enabled. | |
166 | * | |
167 | * This function is only relevant to linux and will return | |
168 | * an error on BSD. | |
169 | * | |
170 | * @return | |
171 | * !0 if true. | |
172 | * 0 otherwise. | |
173 | */ | |
174 | int rte_vfio_noiommu_is_enabled(void); | |
175 | ||
176 | /** | |
177 | * Remove group fd from internal VFIO group fd array/ | |
178 | * | |
179 | * This function is only relevant to linux and will return | |
180 | * an error on BSD. | |
181 | * | |
182 | * @param vfio_group_fd | |
9f95a23c | 183 | * VFIO Group FD. |
11fdf7f2 TL |
184 | * |
185 | * @return | |
186 | * 0 on success. | |
187 | * <0 on failure. | |
188 | */ | |
189 | int | |
190 | rte_vfio_clear_group(int vfio_group_fd); | |
191 | ||
11fdf7f2 TL |
192 | /** |
193 | * Parse IOMMU group number for a device | |
194 | * | |
195 | * This function is only relevant to linux and will return | |
196 | * an error on BSD. | |
197 | * | |
198 | * @param sysfs_base | |
199 | * sysfs path prefix. | |
200 | * | |
201 | * @param dev_addr | |
202 | * device location. | |
203 | * | |
204 | * @param iommu_group_num | |
205 | * iommu group number | |
206 | * | |
207 | * @return | |
208 | * >0 on success | |
209 | * 0 for non-existent group or VFIO | |
210 | * <0 for errors | |
211 | */ | |
212 | int | |
213 | rte_vfio_get_group_num(const char *sysfs_base, | |
214 | const char *dev_addr, int *iommu_group_num); | |
215 | ||
216 | /** | |
9f95a23c | 217 | * Open a new VFIO container fd |
11fdf7f2 TL |
218 | * |
219 | * This function is only relevant to linux and will return | |
220 | * an error on BSD. | |
221 | * | |
222 | * @return | |
223 | * > 0 container fd | |
224 | * < 0 for errors | |
225 | */ | |
226 | int | |
227 | rte_vfio_get_container_fd(void); | |
228 | ||
229 | /** | |
230 | * Open VFIO group fd or get an existing one | |
231 | * | |
232 | * This function is only relevant to linux and will return | |
233 | * an error on BSD. | |
234 | * | |
235 | * @param iommu_group_num | |
236 | * iommu group number | |
237 | * | |
238 | * @return | |
239 | * > 0 group fd | |
240 | * < 0 for errors | |
241 | */ | |
242 | int | |
243 | rte_vfio_get_group_fd(int iommu_group_num); | |
244 | ||
245 | /** | |
246 | * Create a new container for device binding. | |
247 | * | |
248 | * @note Any newly allocated DPDK memory will not be mapped into these | |
249 | * containers by default, user needs to manage DMA mappings for | |
250 | * any container created by this API. | |
251 | * | |
9f95a23c TL |
252 | * @note When creating containers using this API, the container will only be |
253 | * available in the process that has created it. Sharing containers and | |
254 | * devices between multiple processes is not supported. | |
255 | * | |
11fdf7f2 TL |
256 | * @return |
257 | * the container fd if successful | |
258 | * <0 if failed | |
259 | */ | |
260 | int | |
261 | rte_vfio_container_create(void); | |
262 | ||
263 | /** | |
264 | * Destroy the container, unbind all vfio groups within it. | |
265 | * | |
266 | * @param container_fd | |
267 | * the container fd to destroy | |
268 | * | |
269 | * @return | |
270 | * 0 if successful | |
271 | * <0 if failed | |
272 | */ | |
273 | int | |
274 | rte_vfio_container_destroy(int container_fd); | |
275 | ||
276 | /** | |
277 | * Bind a IOMMU group to a container. | |
278 | * | |
279 | * @param container_fd | |
280 | * the container's fd | |
281 | * | |
282 | * @param iommu_group_num | |
283 | * the iommu group number to bind to container | |
284 | * | |
285 | * @return | |
286 | * group fd if successful | |
287 | * <0 if failed | |
288 | */ | |
289 | int | |
290 | rte_vfio_container_group_bind(int container_fd, int iommu_group_num); | |
291 | ||
292 | /** | |
293 | * Unbind a IOMMU group from a container. | |
294 | * | |
295 | * @param container_fd | |
296 | * the container fd of container | |
297 | * | |
298 | * @param iommu_group_num | |
299 | * the iommu group number to delete from container | |
300 | * | |
301 | * @return | |
302 | * 0 if successful | |
303 | * <0 if failed | |
304 | */ | |
305 | int | |
306 | rte_vfio_container_group_unbind(int container_fd, int iommu_group_num); | |
307 | ||
308 | /** | |
309 | * Perform DMA mapping for devices in a container. | |
310 | * | |
311 | * @param container_fd | |
9f95a23c TL |
312 | * the specified container fd. Use RTE_VFIO_DEFAULT_CONTAINER_FD to |
313 | * use the default container. | |
11fdf7f2 TL |
314 | * |
315 | * @param vaddr | |
316 | * Starting virtual address of memory to be mapped. | |
317 | * | |
318 | * @param iova | |
319 | * Starting IOVA address of memory to be mapped. | |
320 | * | |
321 | * @param len | |
322 | * Length of memory segment being mapped. | |
323 | * | |
324 | * @return | |
325 | * 0 if successful | |
326 | * <0 if failed | |
327 | */ | |
328 | int | |
329 | rte_vfio_container_dma_map(int container_fd, uint64_t vaddr, | |
330 | uint64_t iova, uint64_t len); | |
331 | ||
332 | /** | |
333 | * Perform DMA unmapping for devices in a container. | |
334 | * | |
335 | * @param container_fd | |
9f95a23c TL |
336 | * the specified container fd. Use RTE_VFIO_DEFAULT_CONTAINER_FD to |
337 | * use the default container. | |
11fdf7f2 TL |
338 | * |
339 | * @param vaddr | |
340 | * Starting virtual address of memory to be unmapped. | |
341 | * | |
342 | * @param iova | |
343 | * Starting IOVA address of memory to be unmapped. | |
344 | * | |
345 | * @param len | |
346 | * Length of memory segment being unmapped. | |
347 | * | |
348 | * @return | |
349 | * 0 if successful | |
350 | * <0 if failed | |
351 | */ | |
352 | int | |
353 | rte_vfio_container_dma_unmap(int container_fd, uint64_t vaddr, | |
354 | uint64_t iova, uint64_t len); | |
355 | ||
356 | #ifdef __cplusplus | |
357 | } | |
358 | #endif | |
359 | ||
360 | #endif /* _RTE_VFIO_H_ */ |