fb41e829bd65e1a0c35acd177acf243f7ac0dcbc
[dpdk.git] / lib / librte_eal / linuxapp / eal / eal_vfio.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2014 Intel Corporation
3  */
4
5 #include <string.h>
6 #include <fcntl.h>
7 #include <unistd.h>
8 #include <sys/ioctl.h>
9
10 #include <rte_log.h>
11 #include <rte_memory.h>
12 #include <rte_eal_memconfig.h>
13 #include <rte_vfio.h>
14
15 #include "eal_filesystem.h"
16 #include "eal_vfio.h"
17 #include "eal_private.h"
18
19 #ifdef VFIO_PRESENT
20
21 /* per-process VFIO config */
22 static struct vfio_config vfio_cfg;
23
24 static int vfio_type1_dma_map(int);
25 static int vfio_spapr_dma_map(int);
26 static int vfio_noiommu_dma_map(int);
27
28 /* IOMMU types we support */
29 static const struct vfio_iommu_type iommu_types[] = {
30         /* x86 IOMMU, otherwise known as type 1 */
31         { RTE_VFIO_TYPE1, "Type 1", &vfio_type1_dma_map},
32         /* ppc64 IOMMU, otherwise known as spapr */
33         { RTE_VFIO_SPAPR, "sPAPR", &vfio_spapr_dma_map},
34         /* IOMMU-less mode */
35         { RTE_VFIO_NOIOMMU, "No-IOMMU", &vfio_noiommu_dma_map},
36 };
37
38 int
39 vfio_get_group_fd(int iommu_group_no)
40 {
41         int i;
42         int vfio_group_fd;
43         char filename[PATH_MAX];
44         struct vfio_group *cur_grp;
45
46         /* check if we already have the group descriptor open */
47         for (i = 0; i < VFIO_MAX_GROUPS; i++)
48                 if (vfio_cfg.vfio_groups[i].group_no == iommu_group_no)
49                         return vfio_cfg.vfio_groups[i].fd;
50
51         /* Lets see first if there is room for a new group */
52         if (vfio_cfg.vfio_active_groups == VFIO_MAX_GROUPS) {
53                 RTE_LOG(ERR, EAL, "Maximum number of VFIO groups reached!\n");
54                 return -1;
55         }
56
57         /* Now lets get an index for the new group */
58         for (i = 0; i < VFIO_MAX_GROUPS; i++)
59                 if (vfio_cfg.vfio_groups[i].group_no == -1) {
60                         cur_grp = &vfio_cfg.vfio_groups[i];
61                         break;
62                 }
63
64         /* This should not happen */
65         if (i == VFIO_MAX_GROUPS) {
66                 RTE_LOG(ERR, EAL, "No VFIO group free slot found\n");
67                 return -1;
68         }
69         /* if primary, try to open the group */
70         if (internal_config.process_type == RTE_PROC_PRIMARY) {
71                 /* try regular group format */
72                 snprintf(filename, sizeof(filename),
73                                  VFIO_GROUP_FMT, iommu_group_no);
74                 vfio_group_fd = open(filename, O_RDWR);
75                 if (vfio_group_fd < 0) {
76                         /* if file not found, it's not an error */
77                         if (errno != ENOENT) {
78                                 RTE_LOG(ERR, EAL, "Cannot open %s: %s\n", filename,
79                                                 strerror(errno));
80                                 return -1;
81                         }
82
83                         /* special case: try no-IOMMU path as well */
84                         snprintf(filename, sizeof(filename),
85                                         VFIO_NOIOMMU_GROUP_FMT, iommu_group_no);
86                         vfio_group_fd = open(filename, O_RDWR);
87                         if (vfio_group_fd < 0) {
88                                 if (errno != ENOENT) {
89                                         RTE_LOG(ERR, EAL, "Cannot open %s: %s\n", filename,
90                                                         strerror(errno));
91                                         return -1;
92                                 }
93                                 return 0;
94                         }
95                         /* noiommu group found */
96                 }
97
98                 cur_grp->group_no = iommu_group_no;
99                 cur_grp->fd = vfio_group_fd;
100                 vfio_cfg.vfio_active_groups++;
101                 return vfio_group_fd;
102         }
103         /* if we're in a secondary process, request group fd from the primary
104          * process via our socket
105          */
106         else {
107                 int socket_fd, ret;
108
109                 socket_fd = vfio_mp_sync_connect_to_primary();
110
111                 if (socket_fd < 0) {
112                         RTE_LOG(ERR, EAL, "  cannot connect to primary process!\n");
113                         return -1;
114                 }
115                 if (vfio_mp_sync_send_request(socket_fd, SOCKET_REQ_GROUP) < 0) {
116                         RTE_LOG(ERR, EAL, "  cannot request container fd!\n");
117                         close(socket_fd);
118                         return -1;
119                 }
120                 if (vfio_mp_sync_send_request(socket_fd, iommu_group_no) < 0) {
121                         RTE_LOG(ERR, EAL, "  cannot send group number!\n");
122                         close(socket_fd);
123                         return -1;
124                 }
125                 ret = vfio_mp_sync_receive_request(socket_fd);
126                 switch (ret) {
127                 case SOCKET_NO_FD:
128                         close(socket_fd);
129                         return 0;
130                 case SOCKET_OK:
131                         vfio_group_fd = vfio_mp_sync_receive_fd(socket_fd);
132                         /* if we got the fd, store it and return it */
133                         if (vfio_group_fd > 0) {
134                                 close(socket_fd);
135                                 cur_grp->group_no = iommu_group_no;
136                                 cur_grp->fd = vfio_group_fd;
137                                 vfio_cfg.vfio_active_groups++;
138                                 return vfio_group_fd;
139                         }
140                         /* fall-through on error */
141                 default:
142                         RTE_LOG(ERR, EAL, "  cannot get container fd!\n");
143                         close(socket_fd);
144                         return -1;
145                 }
146         }
147         return -1;
148 }
149
150
151 static int
152 get_vfio_group_idx(int vfio_group_fd)
153 {
154         int i;
155         for (i = 0; i < VFIO_MAX_GROUPS; i++)
156                 if (vfio_cfg.vfio_groups[i].fd == vfio_group_fd)
157                         return i;
158         return -1;
159 }
160
161 static void
162 vfio_group_device_get(int vfio_group_fd)
163 {
164         int i;
165
166         i = get_vfio_group_idx(vfio_group_fd);
167         if (i < 0 || i > (VFIO_MAX_GROUPS - 1))
168                 RTE_LOG(ERR, EAL, "  wrong vfio_group index (%d)\n", i);
169         else
170                 vfio_cfg.vfio_groups[i].devices++;
171 }
172
173 static void
174 vfio_group_device_put(int vfio_group_fd)
175 {
176         int i;
177
178         i = get_vfio_group_idx(vfio_group_fd);
179         if (i < 0 || i > (VFIO_MAX_GROUPS - 1))
180                 RTE_LOG(ERR, EAL, "  wrong vfio_group index (%d)\n", i);
181         else
182                 vfio_cfg.vfio_groups[i].devices--;
183 }
184
185 static int
186 vfio_group_device_count(int vfio_group_fd)
187 {
188         int i;
189
190         i = get_vfio_group_idx(vfio_group_fd);
191         if (i < 0 || i > (VFIO_MAX_GROUPS - 1)) {
192                 RTE_LOG(ERR, EAL, "  wrong vfio_group index (%d)\n", i);
193                 return -1;
194         }
195
196         return vfio_cfg.vfio_groups[i].devices;
197 }
198
199 int
200 rte_vfio_clear_group(int vfio_group_fd)
201 {
202         int i;
203         int socket_fd, ret;
204
205         if (internal_config.process_type == RTE_PROC_PRIMARY) {
206
207                 i = get_vfio_group_idx(vfio_group_fd);
208                 if (i < 0)
209                         return -1;
210                 vfio_cfg.vfio_groups[i].group_no = -1;
211                 vfio_cfg.vfio_groups[i].fd = -1;
212                 vfio_cfg.vfio_groups[i].devices = 0;
213                 vfio_cfg.vfio_active_groups--;
214                 return 0;
215         }
216
217         /* This is just for SECONDARY processes */
218         socket_fd = vfio_mp_sync_connect_to_primary();
219
220         if (socket_fd < 0) {
221                 RTE_LOG(ERR, EAL, "  cannot connect to primary process!\n");
222                 return -1;
223         }
224
225         if (vfio_mp_sync_send_request(socket_fd, SOCKET_CLR_GROUP) < 0) {
226                 RTE_LOG(ERR, EAL, "  cannot request container fd!\n");
227                 close(socket_fd);
228                 return -1;
229         }
230
231         if (vfio_mp_sync_send_request(socket_fd, vfio_group_fd) < 0) {
232                 RTE_LOG(ERR, EAL, "  cannot send group fd!\n");
233                 close(socket_fd);
234                 return -1;
235         }
236
237         ret = vfio_mp_sync_receive_request(socket_fd);
238         switch (ret) {
239         case SOCKET_NO_FD:
240                 RTE_LOG(ERR, EAL, "  BAD VFIO group fd!\n");
241                 close(socket_fd);
242                 break;
243         case SOCKET_OK:
244                 close(socket_fd);
245                 return 0;
246         case SOCKET_ERR:
247                 RTE_LOG(ERR, EAL, "  Socket error\n");
248                 close(socket_fd);
249                 break;
250         default:
251                 RTE_LOG(ERR, EAL, "  UNKNOWN reply, %d\n", ret);
252                 close(socket_fd);
253         }
254         return -1;
255 }
256
257 int
258 rte_vfio_setup_device(const char *sysfs_base, const char *dev_addr,
259                 int *vfio_dev_fd, struct vfio_device_info *device_info)
260 {
261         struct vfio_group_status group_status = {
262                         .argsz = sizeof(group_status)
263         };
264         int vfio_group_fd;
265         int iommu_group_no;
266         int ret;
267
268         /* get group number */
269         ret = vfio_get_group_no(sysfs_base, dev_addr, &iommu_group_no);
270         if (ret == 0) {
271                 RTE_LOG(WARNING, EAL, "  %s not managed by VFIO driver, skipping\n",
272                         dev_addr);
273                 return 1;
274         }
275
276         /* if negative, something failed */
277         if (ret < 0)
278                 return -1;
279
280         /* get the actual group fd */
281         vfio_group_fd = vfio_get_group_fd(iommu_group_no);
282         if (vfio_group_fd < 0)
283                 return -1;
284
285         /* if group_fd == 0, that means the device isn't managed by VFIO */
286         if (vfio_group_fd == 0) {
287                 RTE_LOG(WARNING, EAL, " %s not managed by VFIO driver, skipping\n",
288                                 dev_addr);
289                 return 1;
290         }
291
292         /*
293          * at this point, we know that this group is viable (meaning, all devices
294          * are either bound to VFIO or not bound to anything)
295          */
296
297         /* check if the group is viable */
298         ret = ioctl(vfio_group_fd, VFIO_GROUP_GET_STATUS, &group_status);
299         if (ret) {
300                 RTE_LOG(ERR, EAL, "  %s cannot get group status, "
301                                 "error %i (%s)\n", dev_addr, errno, strerror(errno));
302                 close(vfio_group_fd);
303                 rte_vfio_clear_group(vfio_group_fd);
304                 return -1;
305         } else if (!(group_status.flags & VFIO_GROUP_FLAGS_VIABLE)) {
306                 RTE_LOG(ERR, EAL, "  %s VFIO group is not viable!\n", dev_addr);
307                 close(vfio_group_fd);
308                 rte_vfio_clear_group(vfio_group_fd);
309                 return -1;
310         }
311
312         /* check if group does not have a container yet */
313         if (!(group_status.flags & VFIO_GROUP_FLAGS_CONTAINER_SET)) {
314
315                 /* add group to a container */
316                 ret = ioctl(vfio_group_fd, VFIO_GROUP_SET_CONTAINER,
317                                 &vfio_cfg.vfio_container_fd);
318                 if (ret) {
319                         RTE_LOG(ERR, EAL, "  %s cannot add VFIO group to container, "
320                                         "error %i (%s)\n", dev_addr, errno, strerror(errno));
321                         close(vfio_group_fd);
322                         rte_vfio_clear_group(vfio_group_fd);
323                         return -1;
324                 }
325
326                 /*
327                  * pick an IOMMU type and set up DMA mappings for container
328                  *
329                  * needs to be done only once, only when first group is
330                  * assigned to a container and only in primary process.
331                  * Note this can happen several times with the hotplug
332                  * functionality.
333                  */
334                 if (internal_config.process_type == RTE_PROC_PRIMARY &&
335                                 vfio_cfg.vfio_active_groups == 1) {
336                         /* select an IOMMU type which we will be using */
337                         const struct vfio_iommu_type *t =
338                                 vfio_set_iommu_type(vfio_cfg.vfio_container_fd);
339                         if (!t) {
340                                 RTE_LOG(ERR, EAL,
341                                         "  %s failed to select IOMMU type\n",
342                                         dev_addr);
343                                 close(vfio_group_fd);
344                                 rte_vfio_clear_group(vfio_group_fd);
345                                 return -1;
346                         }
347                         ret = t->dma_map_func(vfio_cfg.vfio_container_fd);
348                         if (ret) {
349                                 RTE_LOG(ERR, EAL,
350                                         "  %s DMA remapping failed, error %i (%s)\n",
351                                         dev_addr, errno, strerror(errno));
352                                 close(vfio_group_fd);
353                                 rte_vfio_clear_group(vfio_group_fd);
354                                 return -1;
355                         }
356                 }
357         }
358
359         /* get a file descriptor for the device */
360         *vfio_dev_fd = ioctl(vfio_group_fd, VFIO_GROUP_GET_DEVICE_FD, dev_addr);
361         if (*vfio_dev_fd < 0) {
362                 /* if we cannot get a device fd, this implies a problem with
363                  * the VFIO group or the container not having IOMMU configured.
364                  */
365
366                 RTE_LOG(WARNING, EAL, "Getting a vfio_dev_fd for %s failed\n",
367                                 dev_addr);
368                 close(vfio_group_fd);
369                 rte_vfio_clear_group(vfio_group_fd);
370                 return -1;
371         }
372
373         /* test and setup the device */
374         ret = ioctl(*vfio_dev_fd, VFIO_DEVICE_GET_INFO, device_info);
375         if (ret) {
376                 RTE_LOG(ERR, EAL, "  %s cannot get device info, "
377                                 "error %i (%s)\n", dev_addr, errno,
378                                 strerror(errno));
379                 close(*vfio_dev_fd);
380                 close(vfio_group_fd);
381                 rte_vfio_clear_group(vfio_group_fd);
382                 return -1;
383         }
384         vfio_group_device_get(vfio_group_fd);
385
386         return 0;
387 }
388
389 int
390 rte_vfio_release_device(const char *sysfs_base, const char *dev_addr,
391                     int vfio_dev_fd)
392 {
393         struct vfio_group_status group_status = {
394                         .argsz = sizeof(group_status)
395         };
396         int vfio_group_fd;
397         int iommu_group_no;
398         int ret;
399
400         /* get group number */
401         ret = vfio_get_group_no(sysfs_base, dev_addr, &iommu_group_no);
402         if (ret <= 0) {
403                 RTE_LOG(WARNING, EAL, "  %s not managed by VFIO driver\n",
404                         dev_addr);
405                 /* This is an error at this point. */
406                 return -1;
407         }
408
409         /* get the actual group fd */
410         vfio_group_fd = vfio_get_group_fd(iommu_group_no);
411         if (vfio_group_fd <= 0) {
412                 RTE_LOG(INFO, EAL, "vfio_get_group_fd failed for %s\n",
413                                    dev_addr);
414                 return -1;
415         }
416
417         /* At this point we got an active group. Closing it will make the
418          * container detachment. If this is the last active group, VFIO kernel
419          * code will unset the container and the IOMMU mappings.
420          */
421
422         /* Closing a device */
423         if (close(vfio_dev_fd) < 0) {
424                 RTE_LOG(INFO, EAL, "Error when closing vfio_dev_fd for %s\n",
425                                    dev_addr);
426                 return -1;
427         }
428
429         /* An VFIO group can have several devices attached. Just when there is
430          * no devices remaining should the group be closed.
431          */
432         vfio_group_device_put(vfio_group_fd);
433         if (!vfio_group_device_count(vfio_group_fd)) {
434
435                 if (close(vfio_group_fd) < 0) {
436                         RTE_LOG(INFO, EAL, "Error when closing vfio_group_fd for %s\n",
437                                 dev_addr);
438                         return -1;
439                 }
440
441                 if (rte_vfio_clear_group(vfio_group_fd) < 0) {
442                         RTE_LOG(INFO, EAL, "Error when clearing group for %s\n",
443                                            dev_addr);
444                         return -1;
445                 }
446         }
447
448         return 0;
449 }
450
451 int
452 rte_vfio_enable(const char *modname)
453 {
454         /* initialize group list */
455         int i;
456         int vfio_available;
457
458         for (i = 0; i < VFIO_MAX_GROUPS; i++) {
459                 vfio_cfg.vfio_groups[i].fd = -1;
460                 vfio_cfg.vfio_groups[i].group_no = -1;
461                 vfio_cfg.vfio_groups[i].devices = 0;
462         }
463
464         /* inform the user that we are probing for VFIO */
465         RTE_LOG(INFO, EAL, "Probing VFIO support...\n");
466
467         /* check if vfio module is loaded */
468         vfio_available = rte_eal_check_module(modname);
469
470         /* return error directly */
471         if (vfio_available == -1) {
472                 RTE_LOG(INFO, EAL, "Could not get loaded module details!\n");
473                 return -1;
474         }
475
476         /* return 0 if VFIO modules not loaded */
477         if (vfio_available == 0) {
478                 RTE_LOG(DEBUG, EAL, "VFIO modules not loaded, "
479                         "skipping VFIO support...\n");
480                 return 0;
481         }
482
483         vfio_cfg.vfio_container_fd = vfio_get_container_fd();
484
485         /* check if we have VFIO driver enabled */
486         if (vfio_cfg.vfio_container_fd != -1) {
487                 RTE_LOG(NOTICE, EAL, "VFIO support initialized\n");
488                 vfio_cfg.vfio_enabled = 1;
489         } else {
490                 RTE_LOG(NOTICE, EAL, "VFIO support could not be initialized\n");
491         }
492
493         return 0;
494 }
495
496 int
497 rte_vfio_is_enabled(const char *modname)
498 {
499         const int mod_available = rte_eal_check_module(modname) > 0;
500         return vfio_cfg.vfio_enabled && mod_available;
501 }
502
503 const struct vfio_iommu_type *
504 vfio_set_iommu_type(int vfio_container_fd)
505 {
506         unsigned idx;
507         for (idx = 0; idx < RTE_DIM(iommu_types); idx++) {
508                 const struct vfio_iommu_type *t = &iommu_types[idx];
509
510                 int ret = ioctl(vfio_container_fd, VFIO_SET_IOMMU,
511                                 t->type_id);
512                 if (!ret) {
513                         RTE_LOG(NOTICE, EAL, "  using IOMMU type %d (%s)\n",
514                                         t->type_id, t->name);
515                         return t;
516                 }
517                 /* not an error, there may be more supported IOMMU types */
518                 RTE_LOG(DEBUG, EAL, "  set IOMMU type %d (%s) failed, "
519                                 "error %i (%s)\n", t->type_id, t->name, errno,
520                                 strerror(errno));
521         }
522         /* if we didn't find a suitable IOMMU type, fail */
523         return NULL;
524 }
525
526 int
527 vfio_has_supported_extensions(int vfio_container_fd)
528 {
529         int ret;
530         unsigned idx, n_extensions = 0;
531         for (idx = 0; idx < RTE_DIM(iommu_types); idx++) {
532                 const struct vfio_iommu_type *t = &iommu_types[idx];
533
534                 ret = ioctl(vfio_container_fd, VFIO_CHECK_EXTENSION,
535                                 t->type_id);
536                 if (ret < 0) {
537                         RTE_LOG(ERR, EAL, "  could not get IOMMU type, "
538                                 "error %i (%s)\n", errno,
539                                 strerror(errno));
540                         close(vfio_container_fd);
541                         return -1;
542                 } else if (ret == 1) {
543                         /* we found a supported extension */
544                         n_extensions++;
545                 }
546                 RTE_LOG(DEBUG, EAL, "  IOMMU type %d (%s) is %s\n",
547                                 t->type_id, t->name,
548                                 ret ? "supported" : "not supported");
549         }
550
551         /* if we didn't find any supported IOMMU types, fail */
552         if (!n_extensions) {
553                 close(vfio_container_fd);
554                 return -1;
555         }
556
557         return 0;
558 }
559
560 int
561 vfio_get_container_fd(void)
562 {
563         int ret, vfio_container_fd;
564
565         /* if we're in a primary process, try to open the container */
566         if (internal_config.process_type == RTE_PROC_PRIMARY) {
567                 vfio_container_fd = open(VFIO_CONTAINER_PATH, O_RDWR);
568                 if (vfio_container_fd < 0) {
569                         RTE_LOG(ERR, EAL, "  cannot open VFIO container, "
570                                         "error %i (%s)\n", errno, strerror(errno));
571                         return -1;
572                 }
573
574                 /* check VFIO API version */
575                 ret = ioctl(vfio_container_fd, VFIO_GET_API_VERSION);
576                 if (ret != VFIO_API_VERSION) {
577                         if (ret < 0)
578                                 RTE_LOG(ERR, EAL, "  could not get VFIO API version, "
579                                                 "error %i (%s)\n", errno, strerror(errno));
580                         else
581                                 RTE_LOG(ERR, EAL, "  unsupported VFIO API version!\n");
582                         close(vfio_container_fd);
583                         return -1;
584                 }
585
586                 ret = vfio_has_supported_extensions(vfio_container_fd);
587                 if (ret) {
588                         RTE_LOG(ERR, EAL, "  no supported IOMMU "
589                                         "extensions found!\n");
590                         return -1;
591                 }
592
593                 return vfio_container_fd;
594         } else {
595                 /*
596                  * if we're in a secondary process, request container fd from the
597                  * primary process via our socket
598                  */
599                 int socket_fd;
600
601                 socket_fd = vfio_mp_sync_connect_to_primary();
602                 if (socket_fd < 0) {
603                         RTE_LOG(ERR, EAL, "  cannot connect to primary process!\n");
604                         return -1;
605                 }
606                 if (vfio_mp_sync_send_request(socket_fd, SOCKET_REQ_CONTAINER) < 0) {
607                         RTE_LOG(ERR, EAL, "  cannot request container fd!\n");
608                         close(socket_fd);
609                         return -1;
610                 }
611                 vfio_container_fd = vfio_mp_sync_receive_fd(socket_fd);
612                 if (vfio_container_fd < 0) {
613                         RTE_LOG(ERR, EAL, "  cannot get container fd!\n");
614                         close(socket_fd);
615                         return -1;
616                 }
617                 close(socket_fd);
618                 return vfio_container_fd;
619         }
620
621         return -1;
622 }
623
624 int
625 vfio_get_group_no(const char *sysfs_base,
626                 const char *dev_addr, int *iommu_group_no)
627 {
628         char linkname[PATH_MAX];
629         char filename[PATH_MAX];
630         char *tok[16], *group_tok, *end;
631         int ret;
632
633         memset(linkname, 0, sizeof(linkname));
634         memset(filename, 0, sizeof(filename));
635
636         /* try to find out IOMMU group for this device */
637         snprintf(linkname, sizeof(linkname),
638                          "%s/%s/iommu_group", sysfs_base, dev_addr);
639
640         ret = readlink(linkname, filename, sizeof(filename));
641
642         /* if the link doesn't exist, no VFIO for us */
643         if (ret < 0)
644                 return 0;
645
646         ret = rte_strsplit(filename, sizeof(filename),
647                         tok, RTE_DIM(tok), '/');
648
649         if (ret <= 0) {
650                 RTE_LOG(ERR, EAL, "  %s cannot get IOMMU group\n", dev_addr);
651                 return -1;
652         }
653
654         /* IOMMU group is always the last token */
655         errno = 0;
656         group_tok = tok[ret - 1];
657         end = group_tok;
658         *iommu_group_no = strtol(group_tok, &end, 10);
659         if ((end != group_tok && *end != '\0') || errno != 0) {
660                 RTE_LOG(ERR, EAL, "  %s error parsing IOMMU number!\n", dev_addr);
661                 return -1;
662         }
663
664         return 1;
665 }
666
667 static int
668 type1_map(const struct rte_memseg *ms, void *arg)
669 {
670         int *vfio_container_fd = arg;
671         struct vfio_iommu_type1_dma_map dma_map;
672         int ret;
673
674         memset(&dma_map, 0, sizeof(dma_map));
675         dma_map.argsz = sizeof(struct vfio_iommu_type1_dma_map);
676         dma_map.vaddr = ms->addr_64;
677         dma_map.size = ms->len;
678         dma_map.iova = ms->iova;
679         dma_map.flags = VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE;
680
681         ret = ioctl(*vfio_container_fd, VFIO_IOMMU_MAP_DMA, &dma_map);
682
683         if (ret) {
684                 RTE_LOG(ERR, EAL, "  cannot set up DMA remapping, error %i (%s)\n",
685                                 errno, strerror(errno));
686                 return -1;
687         }
688         return 0;
689 }
690
691 static int
692 vfio_type1_dma_map(int vfio_container_fd)
693 {
694         return rte_memseg_walk(type1_map, &vfio_container_fd);
695 }
696
697 struct spapr_walk_param {
698         uint64_t window_size;
699         uint64_t hugepage_sz;
700 };
701 static int
702 spapr_window_size(const struct rte_memseg *ms, void *arg)
703 {
704         struct spapr_walk_param *param = arg;
705         uint64_t max = ms->iova + ms->len;
706
707         if (max > param->window_size) {
708                 param->hugepage_sz = ms->hugepage_sz;
709                 param->window_size = max;
710         }
711
712         return 0;
713 }
714
715 static int
716 spapr_map(const struct rte_memseg *ms, void *arg)
717 {
718         struct vfio_iommu_type1_dma_map dma_map;
719         struct vfio_iommu_spapr_register_memory reg = {
720                 .argsz = sizeof(reg),
721                 .flags = 0
722         };
723         int *vfio_container_fd = arg;
724         int ret;
725
726         reg.vaddr = (uintptr_t) ms->addr;
727         reg.size = ms->len;
728         ret = ioctl(*vfio_container_fd,
729                 VFIO_IOMMU_SPAPR_REGISTER_MEMORY, &reg);
730         if (ret) {
731                 RTE_LOG(ERR, EAL, "  cannot register vaddr for IOMMU, error %i (%s)\n",
732                                 errno, strerror(errno));
733                 return -1;
734         }
735
736         memset(&dma_map, 0, sizeof(dma_map));
737         dma_map.argsz = sizeof(struct vfio_iommu_type1_dma_map);
738         dma_map.vaddr = ms->addr_64;
739         dma_map.size = ms->len;
740         dma_map.iova = ms->iova;
741         dma_map.flags = VFIO_DMA_MAP_FLAG_READ |
742                          VFIO_DMA_MAP_FLAG_WRITE;
743
744         ret = ioctl(*vfio_container_fd, VFIO_IOMMU_MAP_DMA, &dma_map);
745
746         if (ret) {
747                 RTE_LOG(ERR, EAL, "  cannot set up DMA remapping, error %i (%s)\n",
748                                 errno, strerror(errno));
749                 return -1;
750         }
751
752         return 0;
753 }
754
755 static int
756 vfio_spapr_dma_map(int vfio_container_fd)
757 {
758         struct spapr_walk_param param;
759         int ret;
760         struct vfio_iommu_spapr_tce_info info = {
761                 .argsz = sizeof(info),
762         };
763         struct vfio_iommu_spapr_tce_create create = {
764                 .argsz = sizeof(create),
765         };
766         struct vfio_iommu_spapr_tce_remove remove = {
767                 .argsz = sizeof(remove),
768         };
769
770         memset(&param, 0, sizeof(param));
771
772         /* query spapr iommu info */
773         ret = ioctl(vfio_container_fd, VFIO_IOMMU_SPAPR_TCE_GET_INFO, &info);
774         if (ret) {
775                 RTE_LOG(ERR, EAL, "  cannot get iommu info, "
776                                 "error %i (%s)\n", errno, strerror(errno));
777                 return -1;
778         }
779
780         /* remove default DMA of 32 bit window */
781         remove.start_addr = info.dma32_window_start;
782         ret = ioctl(vfio_container_fd, VFIO_IOMMU_SPAPR_TCE_REMOVE, &remove);
783         if (ret) {
784                 RTE_LOG(ERR, EAL, "  cannot remove default DMA window, "
785                                 "error %i (%s)\n", errno, strerror(errno));
786                 return -1;
787         }
788
789         /* create DMA window from 0 to max(phys_addr + len) */
790         rte_memseg_walk(spapr_window_size, &param);
791
792         /* sPAPR requires window size to be a power of 2 */
793         create.window_size = rte_align64pow2(param.window_size);
794         create.page_shift = __builtin_ctzll(param.hugepage_sz);
795         create.levels = 1;
796
797         ret = ioctl(vfio_container_fd, VFIO_IOMMU_SPAPR_TCE_CREATE, &create);
798         if (ret) {
799                 RTE_LOG(ERR, EAL, "  cannot create new DMA window, "
800                                 "error %i (%s)\n", errno, strerror(errno));
801                 return -1;
802         }
803
804         if (create.start_addr != 0) {
805                 RTE_LOG(ERR, EAL, "  DMA window start address != 0\n");
806                 return -1;
807         }
808
809         /* map all DPDK segments for DMA. use 1:1 PA to IOVA mapping */
810         if (rte_memseg_walk(spapr_map, &vfio_container_fd) < 0)
811                 return -1;
812
813         return 0;
814 }
815
816 static int
817 vfio_noiommu_dma_map(int __rte_unused vfio_container_fd)
818 {
819         /* No-IOMMU mode does not need DMA mapping */
820         return 0;
821 }
822
823 int
824 rte_vfio_noiommu_is_enabled(void)
825 {
826         int fd;
827         ssize_t cnt;
828         char c;
829
830         fd = open(VFIO_NOIOMMU_MODE, O_RDONLY);
831         if (fd < 0) {
832                 if (errno != ENOENT) {
833                         RTE_LOG(ERR, EAL, "  cannot open vfio noiommu file %i (%s)\n",
834                                         errno, strerror(errno));
835                         return -1;
836                 }
837                 /*
838                  * else the file does not exists
839                  * i.e. noiommu is not enabled
840                  */
841                 return 0;
842         }
843
844         cnt = read(fd, &c, 1);
845         close(fd);
846         if (cnt != 1) {
847                 RTE_LOG(ERR, EAL, "  unable to read from vfio noiommu "
848                                 "file %i (%s)\n", errno, strerror(errno));
849                 return -1;
850         }
851
852         return c == 'Y';
853 }
854
855 #endif