8b15312099c7776065e1e09a3b6ee6cc68bbccb2
[dpdk.git] / drivers / bus / fslmc / fslmc_vfio.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  *   Copyright (c) 2015-2016 Freescale Semiconductor, Inc. All rights reserved.
4  *   Copyright 2016 NXP
5  *
6  */
7
8 #include <unistd.h>
9 #include <stdio.h>
10 #include <sys/types.h>
11 #include <string.h>
12 #include <stdlib.h>
13 #include <fcntl.h>
14 #include <errno.h>
15 #include <sys/ioctl.h>
16 #include <sys/stat.h>
17 #include <sys/mman.h>
18 #include <sys/vfs.h>
19 #include <libgen.h>
20 #include <dirent.h>
21 #include <sys/eventfd.h>
22
23 #include <eal_filesystem.h>
24 #include <rte_mbuf.h>
25 #include <rte_ethdev_driver.h>
26 #include <rte_malloc.h>
27 #include <rte_memcpy.h>
28 #include <rte_string_fns.h>
29 #include <rte_cycles.h>
30 #include <rte_kvargs.h>
31 #include <rte_dev.h>
32 #include <rte_bus.h>
33
34 #include "rte_fslmc.h"
35 #include "fslmc_vfio.h"
36 #include "fslmc_logs.h"
37 #include <mc/fsl_dpmng.h>
38
39 #include "portal/dpaa2_hw_pvt.h"
40 #include "portal/dpaa2_hw_dpio.h"
41
42 /** Pathname of FSL-MC devices directory. */
43 #define SYSFS_FSL_MC_DEVICES "/sys/bus/fsl-mc/devices"
44
45 #define FSLMC_CONTAINER_MAX_LEN 8 /**< Of the format dprc.XX */
46
47 /* Number of VFIO containers & groups with in */
48 static struct fslmc_vfio_group vfio_group;
49 static struct fslmc_vfio_container vfio_container;
50 static int container_device_fd;
51 static char *g_container;
52 static uint32_t *msi_intr_vaddr;
53 void *(*rte_mcp_ptr_list);
54 static int is_dma_done;
55
56 static struct rte_dpaa2_object_list dpaa2_obj_list =
57         TAILQ_HEAD_INITIALIZER(dpaa2_obj_list);
58
59 /*register a fslmc bus based dpaa2 driver */
60 void
61 rte_fslmc_object_register(struct rte_dpaa2_object *object)
62 {
63         RTE_VERIFY(object);
64
65         TAILQ_INSERT_TAIL(&dpaa2_obj_list, object, next);
66 }
67
68 int
69 fslmc_get_container_group(int *groupid)
70 {
71         int ret;
72         char *container;
73
74         if (!g_container) {
75                 container = getenv("DPRC");
76                 if (container == NULL) {
77                         DPAA2_BUS_INFO("DPAA2: DPRC not available");
78                         return -EINVAL;
79                 }
80
81                 if (strlen(container) >= FSLMC_CONTAINER_MAX_LEN) {
82                         DPAA2_BUS_ERR("Invalid container name: %s", container);
83                         return -1;
84                 }
85
86                 g_container = strdup(container);
87                 if (!g_container) {
88                         DPAA2_BUS_ERR("Mem alloc failure; Container name");
89                         return -ENOMEM;
90                 }
91         }
92
93         /* get group number */
94         ret = vfio_get_group_no(SYSFS_FSL_MC_DEVICES, g_container, groupid);
95         if (ret <= 0) {
96                 DPAA2_BUS_ERR("Unable to find %s IOMMU group", g_container);
97                 return -1;
98         }
99
100         DPAA2_BUS_DEBUG("Container: %s has VFIO iommu group id = %d",
101                         g_container, *groupid);
102
103         return 0;
104 }
105
106 static int
107 vfio_connect_container(void)
108 {
109         int fd, ret;
110
111         if (vfio_container.used) {
112                 DPAA2_BUS_DEBUG("No container available");
113                 return -1;
114         }
115
116         /* Try connecting to vfio container if already created */
117         if (!ioctl(vfio_group.fd, VFIO_GROUP_SET_CONTAINER,
118                 &vfio_container.fd)) {
119                 DPAA2_BUS_DEBUG(
120                     "Container pre-exists with FD[0x%x] for this group",
121                     vfio_container.fd);
122                 vfio_group.container = &vfio_container;
123                 return 0;
124         }
125
126         /* Opens main vfio file descriptor which represents the "container" */
127         fd = vfio_get_container_fd();
128         if (fd < 0) {
129                 DPAA2_BUS_ERR("Failed to open VFIO container");
130                 return -errno;
131         }
132
133         /* Check whether support for SMMU type IOMMU present or not */
134         if (ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_TYPE1_IOMMU)) {
135                 /* Connect group to container */
136                 ret = ioctl(vfio_group.fd, VFIO_GROUP_SET_CONTAINER, &fd);
137                 if (ret) {
138                         DPAA2_BUS_ERR("Failed to setup group container");
139                         close(fd);
140                         return -errno;
141                 }
142
143                 ret = ioctl(fd, VFIO_SET_IOMMU, VFIO_TYPE1_IOMMU);
144                 if (ret) {
145                         DPAA2_BUS_ERR("Failed to setup VFIO iommu");
146                         close(fd);
147                         return -errno;
148                 }
149         } else {
150                 DPAA2_BUS_ERR("No supported IOMMU available");
151                 close(fd);
152                 return -EINVAL;
153         }
154
155         vfio_container.used = 1;
156         vfio_container.fd = fd;
157         vfio_container.group = &vfio_group;
158         vfio_group.container = &vfio_container;
159
160         return 0;
161 }
162
163 static int vfio_map_irq_region(struct fslmc_vfio_group *group)
164 {
165         int ret;
166         unsigned long *vaddr = NULL;
167         struct vfio_iommu_type1_dma_map map = {
168                 .argsz = sizeof(map),
169                 .flags = VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE,
170                 .vaddr = 0x6030000,
171                 .iova = 0x6030000,
172                 .size = 0x1000,
173         };
174
175         vaddr = (unsigned long *)mmap(NULL, 0x1000, PROT_WRITE |
176                 PROT_READ, MAP_SHARED, container_device_fd, 0x6030000);
177         if (vaddr == MAP_FAILED) {
178                 DPAA2_BUS_ERR("Unable to map region (errno = %d)", errno);
179                 return -errno;
180         }
181
182         msi_intr_vaddr = (uint32_t *)((char *)(vaddr) + 64);
183         map.vaddr = (unsigned long)vaddr;
184         ret = ioctl(group->container->fd, VFIO_IOMMU_MAP_DMA, &map);
185         if (ret == 0)
186                 return 0;
187
188         DPAA2_BUS_ERR("Unable to map DMA address (errno = %d)", errno);
189         return -errno;
190 }
191
192 static int
193 fslmc_vfio_map(const struct rte_memseg_list *msl __rte_unused,
194                 const struct rte_memseg *ms, void *arg)
195 {
196         int *n_segs = arg;
197         struct fslmc_vfio_group *group;
198         struct vfio_iommu_type1_dma_map dma_map = {
199                 .argsz = sizeof(struct vfio_iommu_type1_dma_map),
200                 .flags = VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE,
201         };
202         int ret;
203
204         dma_map.size = ms->len;
205         dma_map.vaddr = ms->addr_64;
206 #ifdef RTE_LIBRTE_DPAA2_USE_PHYS_IOVA
207         dma_map.iova = ms->iova;
208 #else
209         dma_map.iova = dma_map.vaddr;
210 #endif
211
212         /* SET DMA MAP for IOMMU */
213         group = &vfio_group;
214
215         if (!group->container) {
216                 DPAA2_BUS_ERR("Container is not connected ");
217                 return -1;
218         }
219
220         DPAA2_BUS_DEBUG("-->Initial SHM Virtual ADDR %llX",
221                         dma_map.vaddr);
222         DPAA2_BUS_DEBUG("-----> DMA size 0x%llX", dma_map.size);
223         ret = ioctl(group->container->fd, VFIO_IOMMU_MAP_DMA,
224                         &dma_map);
225         if (ret) {
226                 DPAA2_BUS_ERR("VFIO_IOMMU_MAP_DMA API(errno = %d)",
227                                 errno);
228                 return -1;
229         }
230         (*n_segs)++;
231         return 0;
232 }
233
234 int rte_fslmc_vfio_dmamap(void)
235 {
236         int i = 0;
237
238         if (is_dma_done)
239                 return 0;
240
241         if (rte_memseg_walk(fslmc_vfio_map, &i) < 0)
242                 return -1;
243
244         /* Verifying that at least single segment is available */
245         if (i <= 0) {
246                 DPAA2_BUS_ERR("No Segments found for VFIO Mapping");
247                 return -1;
248         }
249         DPAA2_BUS_DEBUG("Total %d segments found.", i);
250
251         /* TODO - This is a W.A. as VFIO currently does not add the mapping of
252          * the interrupt region to SMMU. This should be removed once the
253          * support is added in the Kernel.
254          */
255         vfio_map_irq_region(&vfio_group);
256
257         is_dma_done = 1;
258
259         return 0;
260 }
261
262 static int64_t vfio_map_mcp_obj(struct fslmc_vfio_group *group, char *mcp_obj)
263 {
264         intptr_t v_addr = (intptr_t)MAP_FAILED;
265         int32_t ret, mc_fd;
266
267         struct vfio_device_info d_info = { .argsz = sizeof(d_info) };
268         struct vfio_region_info reg_info = { .argsz = sizeof(reg_info) };
269
270         /* getting the mcp object's fd*/
271         mc_fd = ioctl(group->fd, VFIO_GROUP_GET_DEVICE_FD, mcp_obj);
272         if (mc_fd < 0) {
273                 DPAA2_BUS_ERR("Error in VFIO get dev %s fd from group %d",
274                               mcp_obj, group->fd);
275                 return v_addr;
276         }
277
278         /* getting device info*/
279         ret = ioctl(mc_fd, VFIO_DEVICE_GET_INFO, &d_info);
280         if (ret < 0) {
281                 DPAA2_BUS_ERR("Error in VFIO getting DEVICE_INFO");
282                 goto MC_FAILURE;
283         }
284
285         /* getting device region info*/
286         ret = ioctl(mc_fd, VFIO_DEVICE_GET_REGION_INFO, &reg_info);
287         if (ret < 0) {
288                 DPAA2_BUS_ERR("Error in VFIO getting REGION_INFO");
289                 goto MC_FAILURE;
290         }
291
292         DPAA2_BUS_DEBUG("Region offset = %llx  , region size = %llx",
293                         reg_info.offset, reg_info.size);
294
295         v_addr = (size_t)mmap(NULL, reg_info.size,
296                 PROT_WRITE | PROT_READ, MAP_SHARED,
297                 mc_fd, reg_info.offset);
298
299 MC_FAILURE:
300         close(mc_fd);
301
302         return v_addr;
303 }
304
305 #define IRQ_SET_BUF_LEN  (sizeof(struct vfio_irq_set) + sizeof(int))
306
307 int rte_dpaa2_intr_enable(struct rte_intr_handle *intr_handle, int index)
308 {
309         int len, ret;
310         char irq_set_buf[IRQ_SET_BUF_LEN];
311         struct vfio_irq_set *irq_set;
312         int *fd_ptr;
313
314         len = sizeof(irq_set_buf);
315
316         irq_set = (struct vfio_irq_set *)irq_set_buf;
317         irq_set->argsz = len;
318         irq_set->count = 1;
319         irq_set->flags =
320                 VFIO_IRQ_SET_DATA_EVENTFD | VFIO_IRQ_SET_ACTION_TRIGGER;
321         irq_set->index = index;
322         irq_set->start = 0;
323         fd_ptr = (int *)&irq_set->data;
324         *fd_ptr = intr_handle->fd;
325
326         ret = ioctl(intr_handle->vfio_dev_fd, VFIO_DEVICE_SET_IRQS, irq_set);
327         if (ret) {
328                 DPAA2_BUS_ERR("Error:dpaa2 SET IRQs fd=%d, err = %d(%s)",
329                               intr_handle->fd, errno, strerror(errno));
330                 return ret;
331         }
332
333         return ret;
334 }
335
336 int rte_dpaa2_intr_disable(struct rte_intr_handle *intr_handle, int index)
337 {
338         struct vfio_irq_set *irq_set;
339         char irq_set_buf[IRQ_SET_BUF_LEN];
340         int len, ret;
341
342         len = sizeof(struct vfio_irq_set);
343
344         irq_set = (struct vfio_irq_set *)irq_set_buf;
345         irq_set->argsz = len;
346         irq_set->flags = VFIO_IRQ_SET_DATA_NONE | VFIO_IRQ_SET_ACTION_TRIGGER;
347         irq_set->index = index;
348         irq_set->start = 0;
349         irq_set->count = 0;
350
351         ret = ioctl(intr_handle->vfio_dev_fd, VFIO_DEVICE_SET_IRQS, irq_set);
352         if (ret)
353                 DPAA2_BUS_ERR(
354                         "Error disabling dpaa2 interrupts for fd %d",
355                         intr_handle->fd);
356
357         return ret;
358 }
359
360 /* set up interrupt support (but not enable interrupts) */
361 int
362 rte_dpaa2_vfio_setup_intr(struct rte_intr_handle *intr_handle,
363                           int vfio_dev_fd,
364                           int num_irqs)
365 {
366         int i, ret;
367
368         /* start from MSI-X interrupt type */
369         for (i = 0; i < num_irqs; i++) {
370                 struct vfio_irq_info irq_info = { .argsz = sizeof(irq_info) };
371                 int fd = -1;
372
373                 irq_info.index = i;
374
375                 ret = ioctl(vfio_dev_fd, VFIO_DEVICE_GET_IRQ_INFO, &irq_info);
376                 if (ret < 0) {
377                         DPAA2_BUS_ERR("Cannot get IRQ(%d) info, error %i (%s)",
378                                       i, errno, strerror(errno));
379                         return -1;
380                 }
381
382                 /* if this vector cannot be used with eventfd,
383                  * fail if we explicitly
384                  * specified interrupt type, otherwise continue
385                  */
386                 if ((irq_info.flags & VFIO_IRQ_INFO_EVENTFD) == 0)
387                         continue;
388
389                 /* set up an eventfd for interrupts */
390                 fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
391                 if (fd < 0) {
392                         DPAA2_BUS_ERR("Cannot set up eventfd, error %i (%s)",
393                                       errno, strerror(errno));
394                         return -1;
395                 }
396
397                 intr_handle->fd = fd;
398                 intr_handle->type = RTE_INTR_HANDLE_VFIO_MSI;
399                 intr_handle->vfio_dev_fd = vfio_dev_fd;
400
401                 return 0;
402         }
403
404         /* if we're here, we haven't found a suitable interrupt vector */
405         return -1;
406 }
407
408 /*
409  * fslmc_process_iodevices for processing only IO (ETH, CRYPTO, and possibly
410  * EVENT) devices.
411  */
412 static int
413 fslmc_process_iodevices(struct rte_dpaa2_device *dev)
414 {
415         int dev_fd;
416         struct vfio_device_info device_info = { .argsz = sizeof(device_info) };
417         struct rte_dpaa2_object *object = NULL;
418
419         dev_fd = ioctl(vfio_group.fd, VFIO_GROUP_GET_DEVICE_FD,
420                        dev->device.name);
421         if (dev_fd <= 0) {
422                 DPAA2_BUS_ERR("Unable to obtain device FD for device:%s",
423                               dev->device.name);
424                 return -1;
425         }
426
427         if (ioctl(dev_fd, VFIO_DEVICE_GET_INFO, &device_info)) {
428                 DPAA2_BUS_ERR("Unable to obtain information for device:%s",
429                               dev->device.name);
430                 return -1;
431         }
432
433         switch (dev->dev_type) {
434         case DPAA2_ETH:
435                 rte_dpaa2_vfio_setup_intr(&dev->intr_handle, dev_fd,
436                                           device_info.num_irqs);
437                 break;
438         case DPAA2_CON:
439         case DPAA2_IO:
440         case DPAA2_CI:
441         case DPAA2_BPOOL:
442                 TAILQ_FOREACH(object, &dpaa2_obj_list, next) {
443                         if (dev->dev_type == object->dev_type)
444                                 object->create(dev_fd, &device_info,
445                                                dev->object_id);
446                         else
447                                 continue;
448                 }
449                 break;
450         default:
451                 break;
452         }
453
454         DPAA2_BUS_DEBUG("Device (%s) abstracted from VFIO",
455                         dev->device.name);
456         return 0;
457 }
458
459 static int
460 fslmc_process_mcp(struct rte_dpaa2_device *dev)
461 {
462         intptr_t v_addr;
463         char *dev_name;
464         struct fsl_mc_io dpmng  = {0};
465         struct mc_version mc_ver_info = {0};
466
467         rte_mcp_ptr_list = malloc(sizeof(void *) * 1);
468         if (!rte_mcp_ptr_list) {
469                 DPAA2_BUS_ERR("Unable to allocate MC portal memory");
470                 return -ENOMEM;
471         }
472
473         dev_name = strdup(dev->device.name);
474         if (!dev_name) {
475                 DPAA2_BUS_ERR("Unable to allocate MC device name memory");
476                 free(rte_mcp_ptr_list);
477                 rte_mcp_ptr_list = NULL;
478                 return -ENOMEM;
479         }
480
481         v_addr = vfio_map_mcp_obj(&vfio_group, dev_name);
482         if (v_addr == (intptr_t)MAP_FAILED) {
483                 DPAA2_BUS_ERR("Error mapping region (errno = %d)", errno);
484                 free(rte_mcp_ptr_list);
485                 rte_mcp_ptr_list = NULL;
486                 return -1;
487         }
488
489         /* check the MC version compatibility */
490         dpmng.regs = (void *)v_addr;
491         if (mc_get_version(&dpmng, CMD_PRI_LOW, &mc_ver_info)) {
492                 DPAA2_BUS_ERR("Unable to obtain MC version");
493                 return -1;
494         }
495
496         if ((mc_ver_info.major != MC_VER_MAJOR) ||
497             (mc_ver_info.minor < MC_VER_MINOR)) {
498                 DPAA2_BUS_ERR("DPAA2 MC version not compatible!"
499                               " Expected %d.%d.x, Detected %d.%d.%d",
500                               MC_VER_MAJOR, MC_VER_MINOR,
501                               mc_ver_info.major, mc_ver_info.minor,
502                               mc_ver_info.revision);
503                 free(rte_mcp_ptr_list);
504                 rte_mcp_ptr_list = NULL;
505                 return -1;
506         }
507         rte_mcp_ptr_list[0] = (void *)v_addr;
508
509         return 0;
510 }
511
512 int
513 fslmc_vfio_process_group(void)
514 {
515         int ret;
516         int found_mportal = 0;
517         struct rte_dpaa2_device *dev, *dev_temp;
518
519         /* Search the MCP as that should be initialized first. */
520         TAILQ_FOREACH_SAFE(dev, &rte_fslmc_bus.device_list, next, dev_temp) {
521                 if (dev->dev_type == DPAA2_MPORTAL) {
522                         ret = fslmc_process_mcp(dev);
523                         if (ret) {
524                                 DPAA2_BUS_ERR("Unable to map MC Portal");
525                                 return -1;
526                         }
527                         if (!found_mportal)
528                                 found_mportal = 1;
529
530                         TAILQ_REMOVE(&rte_fslmc_bus.device_list, dev, next);
531                         free(dev);
532                         dev = NULL;
533                         /* Ideally there is only a single dpmcp, but in case
534                          * multiple exists, looping on remaining devices.
535                          */
536                 }
537         }
538
539         /* Cannot continue if there is not even a single mportal */
540         if (!found_mportal) {
541                 DPAA2_BUS_ERR("No MC Portal device found. Not continuing");
542                 return -1;
543         }
544
545         TAILQ_FOREACH_SAFE(dev, &rte_fslmc_bus.device_list, next, dev_temp) {
546                 if (!dev)
547                         break;
548
549                 switch (dev->dev_type) {
550                 case DPAA2_ETH:
551                 case DPAA2_CRYPTO:
552                         ret = fslmc_process_iodevices(dev);
553                         if (ret) {
554                                 DPAA2_BUS_DEBUG("Dev (%s) init failed",
555                                                 dev->device.name);
556                                 return ret;
557                         }
558                         break;
559                 case DPAA2_CON:
560                 case DPAA2_IO:
561                 case DPAA2_CI:
562                 case DPAA2_BPOOL:
563                         /* Call the object creation routine and remove the
564                          * device entry from device list
565                          */
566                         ret = fslmc_process_iodevices(dev);
567                         if (ret) {
568                                 DPAA2_BUS_DEBUG("Dev (%s) init failed",
569                                                 dev->device.name);
570                                 return -1;
571                         }
572
573                         /* This device is not required to be in the DPDK
574                          * exposed device list.
575                          */
576                         TAILQ_REMOVE(&rte_fslmc_bus.device_list, dev, next);
577                         free(dev);
578                         dev = NULL;
579                         break;
580                 case DPAA2_UNKNOWN:
581                 default:
582                         /* Unknown - ignore */
583                         DPAA2_BUS_DEBUG("Found unknown device (%s)",
584                                         dev->device.name);
585                         TAILQ_REMOVE(&rte_fslmc_bus.device_list, dev, next);
586                         free(dev);
587                         dev = NULL;
588                 }
589         }
590
591         return 0;
592 }
593
594 int
595 fslmc_vfio_setup_group(void)
596 {
597         int groupid;
598         int ret;
599         struct vfio_group_status status = { .argsz = sizeof(status) };
600
601         /* if already done once */
602         if (container_device_fd)
603                 return 0;
604
605         ret = fslmc_get_container_group(&groupid);
606         if (ret)
607                 return ret;
608
609         /* In case this group was already opened, continue without any
610          * processing.
611          */
612         if (vfio_group.groupid == groupid) {
613                 DPAA2_BUS_ERR("groupid already exists %d", groupid);
614                 return 0;
615         }
616
617         /* Get the actual group fd */
618         ret = vfio_get_group_fd(groupid);
619         if (ret < 0)
620                 return ret;
621         vfio_group.fd = ret;
622
623         /* Check group viability */
624         ret = ioctl(vfio_group.fd, VFIO_GROUP_GET_STATUS, &status);
625         if (ret) {
626                 DPAA2_BUS_ERR("VFIO error getting group status");
627                 close(vfio_group.fd);
628                 rte_vfio_clear_group(vfio_group.fd);
629                 return ret;
630         }
631
632         if (!(status.flags & VFIO_GROUP_FLAGS_VIABLE)) {
633                 DPAA2_BUS_ERR("VFIO group not viable");
634                 close(vfio_group.fd);
635                 rte_vfio_clear_group(vfio_group.fd);
636                 return -EPERM;
637         }
638         /* Since Group is VIABLE, Store the groupid */
639         vfio_group.groupid = groupid;
640
641         /* check if group does not have a container yet */
642         if (!(status.flags & VFIO_GROUP_FLAGS_CONTAINER_SET)) {
643                 /* Now connect this IOMMU group to given container */
644                 ret = vfio_connect_container();
645                 if (ret) {
646                         DPAA2_BUS_ERR(
647                                 "Error connecting container with groupid %d",
648                                 groupid);
649                         close(vfio_group.fd);
650                         rte_vfio_clear_group(vfio_group.fd);
651                         return ret;
652                 }
653         }
654
655         /* Get Device information */
656         ret = ioctl(vfio_group.fd, VFIO_GROUP_GET_DEVICE_FD, g_container);
657         if (ret < 0) {
658                 DPAA2_BUS_ERR("Error getting device %s fd from group %d",
659                               g_container, vfio_group.groupid);
660                 close(vfio_group.fd);
661                 rte_vfio_clear_group(vfio_group.fd);
662                 return ret;
663         }
664         container_device_fd = ret;
665         DPAA2_BUS_DEBUG("VFIO Container FD is [0x%X]",
666                         container_device_fd);
667
668         return 0;
669 }