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