0c048dc04a640707edcd9d2c8800224b8b7be419
[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 *ms, void *arg)
194 {
195         int *n_segs = arg;
196         struct fslmc_vfio_group *group;
197         struct vfio_iommu_type1_dma_map dma_map = {
198                 .argsz = sizeof(struct vfio_iommu_type1_dma_map),
199                 .flags = VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE,
200         };
201         int ret;
202
203         dma_map.size = ms->len;
204         dma_map.vaddr = ms->addr_64;
205 #ifdef RTE_LIBRTE_DPAA2_USE_PHYS_IOVA
206         dma_map.iova = ms->iova;
207 #else
208         dma_map.iova = dma_map.vaddr;
209 #endif
210
211         /* SET DMA MAP for IOMMU */
212         group = &vfio_group;
213
214         if (!group->container) {
215                 DPAA2_BUS_ERR("Container is not connected ");
216                 return -1;
217         }
218
219         DPAA2_BUS_DEBUG("-->Initial SHM Virtual ADDR %llX",
220                         dma_map.vaddr);
221         DPAA2_BUS_DEBUG("-----> DMA size 0x%llX", dma_map.size);
222         ret = ioctl(group->container->fd, VFIO_IOMMU_MAP_DMA,
223                         &dma_map);
224         if (ret) {
225                 DPAA2_BUS_ERR("VFIO_IOMMU_MAP_DMA API(errno = %d)",
226                                 errno);
227                 return -1;
228         }
229         (*n_segs)++;
230         return 0;
231 }
232
233 int rte_fslmc_vfio_dmamap(void)
234 {
235         const struct rte_memseg *memseg;
236         int i = 0;
237
238         if (is_dma_done)
239                 return 0;
240
241         memseg = rte_eal_get_physmem_layout();
242         if (memseg == NULL) {
243                 DPAA2_BUS_ERR("Cannot get physical layout");
244                 return -ENODEV;
245         }
246
247         if (rte_memseg_walk(fslmc_vfio_map, &i) < 0)
248                 return -1;
249
250         /* Verifying that at least single segment is available */
251         if (i <= 0) {
252                 DPAA2_BUS_ERR("No Segments found for VFIO Mapping");
253                 return -1;
254         }
255         DPAA2_BUS_DEBUG("Total %d segments found.", i);
256
257         /* TODO - This is a W.A. as VFIO currently does not add the mapping of
258          * the interrupt region to SMMU. This should be removed once the
259          * support is added in the Kernel.
260          */
261         vfio_map_irq_region(&vfio_group);
262
263         is_dma_done = 1;
264
265         return 0;
266 }
267
268 static int64_t vfio_map_mcp_obj(struct fslmc_vfio_group *group, char *mcp_obj)
269 {
270         intptr_t v_addr = (intptr_t)MAP_FAILED;
271         int32_t ret, mc_fd;
272
273         struct vfio_device_info d_info = { .argsz = sizeof(d_info) };
274         struct vfio_region_info reg_info = { .argsz = sizeof(reg_info) };
275
276         /* getting the mcp object's fd*/
277         mc_fd = ioctl(group->fd, VFIO_GROUP_GET_DEVICE_FD, mcp_obj);
278         if (mc_fd < 0) {
279                 DPAA2_BUS_ERR("Error in VFIO get dev %s fd from group %d",
280                               mcp_obj, group->fd);
281                 return v_addr;
282         }
283
284         /* getting device info*/
285         ret = ioctl(mc_fd, VFIO_DEVICE_GET_INFO, &d_info);
286         if (ret < 0) {
287                 DPAA2_BUS_ERR("Error in VFIO getting DEVICE_INFO");
288                 goto MC_FAILURE;
289         }
290
291         /* getting device region info*/
292         ret = ioctl(mc_fd, VFIO_DEVICE_GET_REGION_INFO, &reg_info);
293         if (ret < 0) {
294                 DPAA2_BUS_ERR("Error in VFIO getting REGION_INFO");
295                 goto MC_FAILURE;
296         }
297
298         DPAA2_BUS_DEBUG("Region offset = %llx  , region size = %llx",
299                         reg_info.offset, reg_info.size);
300
301         v_addr = (size_t)mmap(NULL, reg_info.size,
302                 PROT_WRITE | PROT_READ, MAP_SHARED,
303                 mc_fd, reg_info.offset);
304
305 MC_FAILURE:
306         close(mc_fd);
307
308         return v_addr;
309 }
310
311 #define IRQ_SET_BUF_LEN  (sizeof(struct vfio_irq_set) + sizeof(int))
312
313 int rte_dpaa2_intr_enable(struct rte_intr_handle *intr_handle, int index)
314 {
315         int len, ret;
316         char irq_set_buf[IRQ_SET_BUF_LEN];
317         struct vfio_irq_set *irq_set;
318         int *fd_ptr;
319
320         len = sizeof(irq_set_buf);
321
322         irq_set = (struct vfio_irq_set *)irq_set_buf;
323         irq_set->argsz = len;
324         irq_set->count = 1;
325         irq_set->flags =
326                 VFIO_IRQ_SET_DATA_EVENTFD | VFIO_IRQ_SET_ACTION_TRIGGER;
327         irq_set->index = index;
328         irq_set->start = 0;
329         fd_ptr = (int *)&irq_set->data;
330         *fd_ptr = intr_handle->fd;
331
332         ret = ioctl(intr_handle->vfio_dev_fd, VFIO_DEVICE_SET_IRQS, irq_set);
333         if (ret) {
334                 DPAA2_BUS_ERR("Error:dpaa2 SET IRQs fd=%d, err = %d(%s)",
335                               intr_handle->fd, errno, strerror(errno));
336                 return ret;
337         }
338
339         return ret;
340 }
341
342 int rte_dpaa2_intr_disable(struct rte_intr_handle *intr_handle, int index)
343 {
344         struct vfio_irq_set *irq_set;
345         char irq_set_buf[IRQ_SET_BUF_LEN];
346         int len, ret;
347
348         len = sizeof(struct vfio_irq_set);
349
350         irq_set = (struct vfio_irq_set *)irq_set_buf;
351         irq_set->argsz = len;
352         irq_set->flags = VFIO_IRQ_SET_DATA_NONE | VFIO_IRQ_SET_ACTION_TRIGGER;
353         irq_set->index = index;
354         irq_set->start = 0;
355         irq_set->count = 0;
356
357         ret = ioctl(intr_handle->vfio_dev_fd, VFIO_DEVICE_SET_IRQS, irq_set);
358         if (ret)
359                 DPAA2_BUS_ERR(
360                         "Error disabling dpaa2 interrupts for fd %d",
361                         intr_handle->fd);
362
363         return ret;
364 }
365
366 /* set up interrupt support (but not enable interrupts) */
367 int
368 rte_dpaa2_vfio_setup_intr(struct rte_intr_handle *intr_handle,
369                           int vfio_dev_fd,
370                           int num_irqs)
371 {
372         int i, ret;
373
374         /* start from MSI-X interrupt type */
375         for (i = 0; i < num_irqs; i++) {
376                 struct vfio_irq_info irq_info = { .argsz = sizeof(irq_info) };
377                 int fd = -1;
378
379                 irq_info.index = i;
380
381                 ret = ioctl(vfio_dev_fd, VFIO_DEVICE_GET_IRQ_INFO, &irq_info);
382                 if (ret < 0) {
383                         DPAA2_BUS_ERR("Cannot get IRQ(%d) info, error %i (%s)",
384                                       i, errno, strerror(errno));
385                         return -1;
386                 }
387
388                 /* if this vector cannot be used with eventfd,
389                  * fail if we explicitly
390                  * specified interrupt type, otherwise continue
391                  */
392                 if ((irq_info.flags & VFIO_IRQ_INFO_EVENTFD) == 0)
393                         continue;
394
395                 /* set up an eventfd for interrupts */
396                 fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
397                 if (fd < 0) {
398                         DPAA2_BUS_ERR("Cannot set up eventfd, error %i (%s)",
399                                       errno, strerror(errno));
400                         return -1;
401                 }
402
403                 intr_handle->fd = fd;
404                 intr_handle->type = RTE_INTR_HANDLE_VFIO_MSI;
405                 intr_handle->vfio_dev_fd = vfio_dev_fd;
406
407                 return 0;
408         }
409
410         /* if we're here, we haven't found a suitable interrupt vector */
411         return -1;
412 }
413
414 /*
415  * fslmc_process_iodevices for processing only IO (ETH, CRYPTO, and possibly
416  * EVENT) devices.
417  */
418 static int
419 fslmc_process_iodevices(struct rte_dpaa2_device *dev)
420 {
421         int dev_fd;
422         struct vfio_device_info device_info = { .argsz = sizeof(device_info) };
423         struct rte_dpaa2_object *object = NULL;
424
425         dev_fd = ioctl(vfio_group.fd, VFIO_GROUP_GET_DEVICE_FD,
426                        dev->device.name);
427         if (dev_fd <= 0) {
428                 DPAA2_BUS_ERR("Unable to obtain device FD for device:%s",
429                               dev->device.name);
430                 return -1;
431         }
432
433         if (ioctl(dev_fd, VFIO_DEVICE_GET_INFO, &device_info)) {
434                 DPAA2_BUS_ERR("Unable to obtain information for device:%s",
435                               dev->device.name);
436                 return -1;
437         }
438
439         switch (dev->dev_type) {
440         case DPAA2_ETH:
441                 rte_dpaa2_vfio_setup_intr(&dev->intr_handle, dev_fd,
442                                           device_info.num_irqs);
443                 break;
444         case DPAA2_CON:
445         case DPAA2_IO:
446         case DPAA2_CI:
447         case DPAA2_BPOOL:
448                 TAILQ_FOREACH(object, &dpaa2_obj_list, next) {
449                         if (dev->dev_type == object->dev_type)
450                                 object->create(dev_fd, &device_info,
451                                                dev->object_id);
452                         else
453                                 continue;
454                 }
455                 break;
456         default:
457                 break;
458         }
459
460         DPAA2_BUS_DEBUG("Device (%s) abstracted from VFIO",
461                         dev->device.name);
462         return 0;
463 }
464
465 static int
466 fslmc_process_mcp(struct rte_dpaa2_device *dev)
467 {
468         intptr_t v_addr;
469         char *dev_name;
470         struct fsl_mc_io dpmng  = {0};
471         struct mc_version mc_ver_info = {0};
472
473         rte_mcp_ptr_list = malloc(sizeof(void *) * 1);
474         if (!rte_mcp_ptr_list) {
475                 DPAA2_BUS_ERR("Unable to allocate MC portal memory");
476                 return -ENOMEM;
477         }
478
479         dev_name = strdup(dev->device.name);
480         if (!dev_name) {
481                 DPAA2_BUS_ERR("Unable to allocate MC device name memory");
482                 free(rte_mcp_ptr_list);
483                 rte_mcp_ptr_list = NULL;
484                 return -ENOMEM;
485         }
486
487         v_addr = vfio_map_mcp_obj(&vfio_group, dev_name);
488         if (v_addr == (intptr_t)MAP_FAILED) {
489                 DPAA2_BUS_ERR("Error mapping region (errno = %d)", errno);
490                 free(rte_mcp_ptr_list);
491                 rte_mcp_ptr_list = NULL;
492                 return -1;
493         }
494
495         /* check the MC version compatibility */
496         dpmng.regs = (void *)v_addr;
497         if (mc_get_version(&dpmng, CMD_PRI_LOW, &mc_ver_info)) {
498                 DPAA2_BUS_ERR("Unable to obtain MC version");
499                 return -1;
500         }
501
502         if ((mc_ver_info.major != MC_VER_MAJOR) ||
503             (mc_ver_info.minor < MC_VER_MINOR)) {
504                 DPAA2_BUS_ERR("DPAA2 MC version not compatible!"
505                               " Expected %d.%d.x, Detected %d.%d.%d",
506                               MC_VER_MAJOR, MC_VER_MINOR,
507                               mc_ver_info.major, mc_ver_info.minor,
508                               mc_ver_info.revision);
509                 free(rte_mcp_ptr_list);
510                 rte_mcp_ptr_list = NULL;
511                 return -1;
512         }
513         rte_mcp_ptr_list[0] = (void *)v_addr;
514
515         return 0;
516 }
517
518 int
519 fslmc_vfio_process_group(void)
520 {
521         int ret;
522         int found_mportal = 0;
523         struct rte_dpaa2_device *dev, *dev_temp;
524
525         /* Search the MCP as that should be initialized first. */
526         TAILQ_FOREACH_SAFE(dev, &rte_fslmc_bus.device_list, next, dev_temp) {
527                 if (dev->dev_type == DPAA2_MPORTAL) {
528                         ret = fslmc_process_mcp(dev);
529                         if (ret) {
530                                 DPAA2_BUS_ERR("Unable to map MC Portal");
531                                 return -1;
532                         }
533                         if (!found_mportal)
534                                 found_mportal = 1;
535
536                         TAILQ_REMOVE(&rte_fslmc_bus.device_list, dev, next);
537                         free(dev);
538                         dev = NULL;
539                         /* Ideally there is only a single dpmcp, but in case
540                          * multiple exists, looping on remaining devices.
541                          */
542                 }
543         }
544
545         /* Cannot continue if there is not even a single mportal */
546         if (!found_mportal) {
547                 DPAA2_BUS_ERR("No MC Portal device found. Not continuing");
548                 return -1;
549         }
550
551         TAILQ_FOREACH_SAFE(dev, &rte_fslmc_bus.device_list, next, dev_temp) {
552                 if (!dev)
553                         break;
554
555                 switch (dev->dev_type) {
556                 case DPAA2_ETH:
557                 case DPAA2_CRYPTO:
558                         ret = fslmc_process_iodevices(dev);
559                         if (ret) {
560                                 DPAA2_BUS_DEBUG("Dev (%s) init failed",
561                                                 dev->device.name);
562                                 return ret;
563                         }
564                         break;
565                 case DPAA2_CON:
566                 case DPAA2_IO:
567                 case DPAA2_CI:
568                 case DPAA2_BPOOL:
569                         /* Call the object creation routine and remove the
570                          * device entry from device list
571                          */
572                         ret = fslmc_process_iodevices(dev);
573                         if (ret) {
574                                 DPAA2_BUS_DEBUG("Dev (%s) init failed",
575                                                 dev->device.name);
576                                 return -1;
577                         }
578
579                         /* This device is not required to be in the DPDK
580                          * exposed device list.
581                          */
582                         TAILQ_REMOVE(&rte_fslmc_bus.device_list, dev, next);
583                         free(dev);
584                         dev = NULL;
585                         break;
586                 case DPAA2_UNKNOWN:
587                 default:
588                         /* Unknown - ignore */
589                         DPAA2_BUS_DEBUG("Found unknown device (%s)",
590                                         dev->device.name);
591                         TAILQ_REMOVE(&rte_fslmc_bus.device_list, dev, next);
592                         free(dev);
593                         dev = NULL;
594                 }
595         }
596
597         return 0;
598 }
599
600 int
601 fslmc_vfio_setup_group(void)
602 {
603         int groupid;
604         int ret;
605         struct vfio_group_status status = { .argsz = sizeof(status) };
606
607         /* if already done once */
608         if (container_device_fd)
609                 return 0;
610
611         ret = fslmc_get_container_group(&groupid);
612         if (ret)
613                 return ret;
614
615         /* In case this group was already opened, continue without any
616          * processing.
617          */
618         if (vfio_group.groupid == groupid) {
619                 DPAA2_BUS_ERR("groupid already exists %d", groupid);
620                 return 0;
621         }
622
623         /* Get the actual group fd */
624         ret = vfio_get_group_fd(groupid);
625         if (ret < 0)
626                 return ret;
627         vfio_group.fd = ret;
628
629         /* Check group viability */
630         ret = ioctl(vfio_group.fd, VFIO_GROUP_GET_STATUS, &status);
631         if (ret) {
632                 DPAA2_BUS_ERR("VFIO error getting group status");
633                 close(vfio_group.fd);
634                 rte_vfio_clear_group(vfio_group.fd);
635                 return ret;
636         }
637
638         if (!(status.flags & VFIO_GROUP_FLAGS_VIABLE)) {
639                 DPAA2_BUS_ERR("VFIO group not viable");
640                 close(vfio_group.fd);
641                 rte_vfio_clear_group(vfio_group.fd);
642                 return -EPERM;
643         }
644         /* Since Group is VIABLE, Store the groupid */
645         vfio_group.groupid = groupid;
646
647         /* check if group does not have a container yet */
648         if (!(status.flags & VFIO_GROUP_FLAGS_CONTAINER_SET)) {
649                 /* Now connect this IOMMU group to given container */
650                 ret = vfio_connect_container();
651                 if (ret) {
652                         DPAA2_BUS_ERR(
653                                 "Error connecting container with groupid %d",
654                                 groupid);
655                         close(vfio_group.fd);
656                         rte_vfio_clear_group(vfio_group.fd);
657                         return ret;
658                 }
659         }
660
661         /* Get Device information */
662         ret = ioctl(vfio_group.fd, VFIO_GROUP_GET_DEVICE_FD, g_container);
663         if (ret < 0) {
664                 DPAA2_BUS_ERR("Error getting device %s fd from group %d",
665                               g_container, vfio_group.groupid);
666                 close(vfio_group.fd);
667                 rte_vfio_clear_group(vfio_group.fd);
668                 return ret;
669         }
670         container_device_fd = ret;
671         DPAA2_BUS_DEBUG("VFIO Container FD is [0x%X]",
672                         container_device_fd);
673
674         return 0;
675 }