LCOV - code coverage report
Current view: top level - drivers/bus/fslmc - fslmc_vfio.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 10 449 2.2 %
Date: 2024-01-22 15:55:54 Functions: 2 20 10.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 3 251 1.2 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  *
       3                 :            :  *   Copyright (c) 2015-2016 Freescale Semiconductor, Inc. All rights reserved.
       4                 :            :  *   Copyright 2016-2021 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 <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 <dev_driver.h>
      32                 :            : #include <rte_eal_memconfig.h>
      33                 :            : 
      34                 :            : #include "private.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                 :            : #define FSLMC_CONTAINER_MAX_LEN 8 /**< Of the format dprc.XX */
      43                 :            : 
      44                 :            : /* Number of VFIO containers & groups with in */
      45                 :            : static struct fslmc_vfio_group vfio_group;
      46                 :            : static struct fslmc_vfio_container vfio_container;
      47                 :            : static int container_device_fd;
      48                 :            : char *fslmc_container;
      49                 :            : static int fslmc_iommu_type;
      50                 :            : static uint32_t *msi_intr_vaddr;
      51                 :            : void *(*rte_mcp_ptr_list);
      52                 :            : 
      53                 :            : void *
      54                 :          0 : dpaa2_get_mcp_ptr(int portal_idx)
      55                 :            : {
      56         [ #  # ]:          0 :         if (rte_mcp_ptr_list)
      57                 :          0 :                 return rte_mcp_ptr_list[portal_idx];
      58                 :            :         else
      59                 :            :                 return NULL;
      60                 :            : }
      61                 :            : 
      62                 :            : static struct rte_dpaa2_object_list dpaa2_obj_list =
      63                 :            :         TAILQ_HEAD_INITIALIZER(dpaa2_obj_list);
      64                 :            : 
      65                 :            : /*register a fslmc bus based dpaa2 driver */
      66                 :            : void
      67                 :       1410 : rte_fslmc_object_register(struct rte_dpaa2_object *object)
      68                 :            : {
      69         [ -  + ]:       1410 :         RTE_VERIFY(object);
      70                 :            : 
      71                 :       1410 :         TAILQ_INSERT_TAIL(&dpaa2_obj_list, object, next);
      72                 :       1410 : }
      73                 :            : 
      74                 :            : int
      75                 :        169 : fslmc_get_container_group(int *groupid)
      76                 :            : {
      77                 :            :         int ret;
      78                 :            :         char *container;
      79                 :            : 
      80         [ +  - ]:        169 :         if (!fslmc_container) {
      81                 :        169 :                 container = getenv("DPRC");
      82         [ +  - ]:        169 :                 if (container == NULL) {
      83                 :        169 :                         DPAA2_BUS_DEBUG("DPAA2: DPRC not available");
      84                 :        169 :                         return -EINVAL;
      85                 :            :                 }
      86                 :            : 
      87         [ #  # ]:          0 :                 if (strlen(container) >= FSLMC_CONTAINER_MAX_LEN) {
      88                 :          0 :                         DPAA2_BUS_ERR("Invalid container name: %s", container);
      89                 :          0 :                         return -1;
      90                 :            :                 }
      91                 :            : 
      92                 :          0 :                 fslmc_container = strdup(container);
      93         [ #  # ]:          0 :                 if (!fslmc_container) {
      94                 :          0 :                         DPAA2_BUS_ERR("Mem alloc failure; Container name");
      95                 :          0 :                         return -ENOMEM;
      96                 :            :                 }
      97                 :            :         }
      98                 :            : 
      99                 :          0 :         fslmc_iommu_type = (rte_vfio_noiommu_is_enabled() == 1) ?
     100         [ #  # ]:          0 :                 RTE_VFIO_NOIOMMU : VFIO_TYPE1_IOMMU;
     101                 :            : 
     102                 :            :         /* get group number */
     103                 :          0 :         ret = rte_vfio_get_group_num(SYSFS_FSL_MC_DEVICES,
     104                 :            :                                      fslmc_container, groupid);
     105         [ #  # ]:          0 :         if (ret <= 0) {
     106                 :          0 :                 DPAA2_BUS_ERR("Unable to find %s IOMMU group", fslmc_container);
     107                 :          0 :                 return -1;
     108                 :            :         }
     109                 :            : 
     110                 :          0 :         DPAA2_BUS_DEBUG("Container: %s has VFIO iommu group id = %d",
     111                 :            :                         fslmc_container, *groupid);
     112                 :            : 
     113                 :          0 :         return 0;
     114                 :            : }
     115                 :            : 
     116                 :            : static int
     117                 :          0 : vfio_connect_container(void)
     118                 :            : {
     119                 :            :         int fd, ret;
     120                 :            : 
     121         [ #  # ]:          0 :         if (vfio_container.used) {
     122                 :          0 :                 DPAA2_BUS_DEBUG("No container available");
     123                 :          0 :                 return -1;
     124                 :            :         }
     125                 :            : 
     126                 :            :         /* Try connecting to vfio container if already created */
     127         [ #  # ]:          0 :         if (!ioctl(vfio_group.fd, VFIO_GROUP_SET_CONTAINER,
     128                 :            :                 &vfio_container.fd)) {
     129                 :          0 :                 DPAA2_BUS_DEBUG(
     130                 :            :                     "Container pre-exists with FD[0x%x] for this group",
     131                 :            :                     vfio_container.fd);
     132                 :          0 :                 vfio_group.container = &vfio_container;
     133                 :          0 :                 return 0;
     134                 :            :         }
     135                 :            : 
     136                 :            :         /* Opens main vfio file descriptor which represents the "container" */
     137                 :          0 :         fd = rte_vfio_get_container_fd();
     138         [ #  # ]:          0 :         if (fd < 0) {
     139                 :          0 :                 DPAA2_BUS_ERR("Failed to open VFIO container");
     140                 :          0 :                 return -errno;
     141                 :            :         }
     142                 :            : 
     143                 :            :         /* Check whether support for SMMU type IOMMU present or not */
     144         [ #  # ]:          0 :         if (ioctl(fd, VFIO_CHECK_EXTENSION, fslmc_iommu_type)) {
     145                 :            :                 /* Connect group to container */
     146                 :          0 :                 ret = ioctl(vfio_group.fd, VFIO_GROUP_SET_CONTAINER, &fd);
     147         [ #  # ]:          0 :                 if (ret) {
     148                 :          0 :                         DPAA2_BUS_ERR("Failed to setup group container");
     149                 :          0 :                         close(fd);
     150                 :          0 :                         return -errno;
     151                 :            :                 }
     152                 :            : 
     153                 :          0 :                 ret = ioctl(fd, VFIO_SET_IOMMU, fslmc_iommu_type);
     154         [ #  # ]:          0 :                 if (ret) {
     155                 :          0 :                         DPAA2_BUS_ERR("Failed to setup VFIO iommu");
     156                 :          0 :                         close(fd);
     157                 :          0 :                         return -errno;
     158                 :            :                 }
     159                 :            :         } else {
     160                 :          0 :                 DPAA2_BUS_ERR("No supported IOMMU available");
     161                 :          0 :                 close(fd);
     162                 :          0 :                 return -EINVAL;
     163                 :            :         }
     164                 :            : 
     165                 :          0 :         vfio_container.used = 1;
     166                 :          0 :         vfio_container.fd = fd;
     167                 :          0 :         vfio_container.group = &vfio_group;
     168                 :          0 :         vfio_group.container = &vfio_container;
     169                 :            : 
     170                 :          0 :         return 0;
     171                 :            : }
     172                 :            : 
     173                 :          0 : static int vfio_map_irq_region(struct fslmc_vfio_group *group)
     174                 :            : {
     175                 :            :         int ret;
     176                 :            :         unsigned long *vaddr = NULL;
     177                 :          0 :         struct vfio_iommu_type1_dma_map map = {
     178                 :            :                 .argsz = sizeof(map),
     179                 :            :                 .flags = VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE,
     180                 :            :                 .vaddr = 0x6030000,
     181                 :            :                 .iova = 0x6030000,
     182                 :            :                 .size = 0x1000,
     183                 :            :         };
     184                 :            : 
     185                 :          0 :         vaddr = (unsigned long *)mmap(NULL, 0x1000, PROT_WRITE |
     186                 :            :                 PROT_READ, MAP_SHARED, container_device_fd, 0x6030000);
     187         [ #  # ]:          0 :         if (vaddr == MAP_FAILED) {
     188                 :          0 :                 DPAA2_BUS_INFO("Unable to map region (errno = %d)", errno);
     189                 :          0 :                 return -errno;
     190                 :            :         }
     191                 :            : 
     192                 :          0 :         msi_intr_vaddr = (uint32_t *)((char *)(vaddr) + 64);
     193                 :          0 :         map.vaddr = (unsigned long)vaddr;
     194                 :          0 :         ret = ioctl(group->container->fd, VFIO_IOMMU_MAP_DMA, &map);
     195         [ #  # ]:          0 :         if (ret == 0)
     196                 :            :                 return 0;
     197                 :            : 
     198                 :          0 :         DPAA2_BUS_ERR("Unable to map DMA address (errno = %d)", errno);
     199                 :          0 :         return -errno;
     200                 :            : }
     201                 :            : 
     202                 :            : static int fslmc_map_dma(uint64_t vaddr, rte_iova_t iovaddr, size_t len);
     203                 :            : static int fslmc_unmap_dma(uint64_t vaddr, rte_iova_t iovaddr, size_t len);
     204                 :            : 
     205                 :            : static void
     206                 :          0 : fslmc_memevent_cb(enum rte_mem_event type, const void *addr, size_t len,
     207                 :            :                 void *arg __rte_unused)
     208                 :            : {
     209                 :            :         struct rte_memseg_list *msl;
     210                 :            :         struct rte_memseg *ms;
     211                 :            :         size_t cur_len = 0, map_len = 0;
     212                 :            :         uint64_t virt_addr;
     213                 :            :         rte_iova_t iova_addr;
     214                 :            :         int ret;
     215                 :            : 
     216                 :          0 :         msl = rte_mem_virt2memseg_list(addr);
     217                 :            : 
     218         [ #  # ]:          0 :         while (cur_len < len) {
     219                 :          0 :                 const void *va = RTE_PTR_ADD(addr, cur_len);
     220                 :            : 
     221                 :          0 :                 ms = rte_mem_virt2memseg(va, msl);
     222                 :          0 :                 iova_addr = ms->iova;
     223                 :          0 :                 virt_addr = ms->addr_64;
     224                 :          0 :                 map_len = ms->len;
     225                 :            : 
     226         [ #  # ]:          0 :                 DPAA2_BUS_DEBUG("Request for %s, va=%p, "
     227                 :            :                                 "virt_addr=0x%" PRIx64 ", "
     228                 :            :                                 "iova=0x%" PRIx64 ", map_len=%zu",
     229                 :            :                                 type == RTE_MEM_EVENT_ALLOC ?
     230                 :            :                                         "alloc" : "dealloc",
     231                 :            :                                 va, virt_addr, iova_addr, map_len);
     232                 :            : 
     233                 :            :                 /* iova_addr may be set to RTE_BAD_IOVA */
     234         [ #  # ]:          0 :                 if (iova_addr == RTE_BAD_IOVA) {
     235                 :          0 :                         DPAA2_BUS_DEBUG("Segment has invalid iova, skipping\n");
     236                 :          0 :                         cur_len += map_len;
     237                 :          0 :                         continue;
     238                 :            :                 }
     239                 :            : 
     240         [ #  # ]:          0 :                 if (type == RTE_MEM_EVENT_ALLOC)
     241                 :          0 :                         ret = fslmc_map_dma(virt_addr, iova_addr, map_len);
     242                 :            :                 else
     243                 :          0 :                         ret = fslmc_unmap_dma(virt_addr, iova_addr, map_len);
     244                 :            : 
     245         [ #  # ]:          0 :                 if (ret != 0) {
     246                 :          0 :                         DPAA2_BUS_ERR("DMA Mapping/Unmapping failed. "
     247                 :            :                                         "Map=%d, addr=%p, len=%zu, err:(%d)",
     248                 :            :                                         type, va, map_len, ret);
     249                 :          0 :                         return;
     250                 :            :                 }
     251                 :            : 
     252                 :          0 :                 cur_len += map_len;
     253                 :            :         }
     254                 :            : 
     255         [ #  # ]:          0 :         if (type == RTE_MEM_EVENT_ALLOC)
     256                 :          0 :                 DPAA2_BUS_DEBUG("Total Mapped: addr=%p, len=%zu",
     257                 :            :                                 addr, len);
     258                 :            :         else
     259                 :          0 :                 DPAA2_BUS_DEBUG("Total Unmapped: addr=%p, len=%zu",
     260                 :            :                                 addr, len);
     261                 :            : }
     262                 :            : 
     263                 :            : static int
     264                 :          0 : fslmc_map_dma(uint64_t vaddr, rte_iova_t iovaddr __rte_unused, size_t len)
     265                 :            : {
     266                 :            :         struct fslmc_vfio_group *group;
     267                 :          0 :         struct vfio_iommu_type1_dma_map dma_map = {
     268                 :            :                 .argsz = sizeof(struct vfio_iommu_type1_dma_map),
     269                 :            :                 .flags = VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE,
     270                 :            :         };
     271                 :            :         int ret;
     272                 :            : 
     273         [ #  # ]:          0 :         if (fslmc_iommu_type == RTE_VFIO_NOIOMMU) {
     274                 :          0 :                 DPAA2_BUS_DEBUG("Running in NOIOMMU mode");
     275                 :          0 :                 return 0;
     276                 :            :         }
     277                 :            : 
     278                 :          0 :         dma_map.size = len;
     279                 :          0 :         dma_map.vaddr = vaddr;
     280                 :            : 
     281                 :            : #ifdef RTE_LIBRTE_DPAA2_USE_PHYS_IOVA
     282                 :          0 :         dma_map.iova = iovaddr;
     283                 :            : #else
     284                 :            :         dma_map.iova = dma_map.vaddr;
     285                 :            : #endif
     286                 :            : 
     287                 :            :         /* SET DMA MAP for IOMMU */
     288                 :            :         group = &vfio_group;
     289                 :            : 
     290         [ #  # ]:          0 :         if (!group->container) {
     291                 :          0 :                 DPAA2_BUS_ERR("Container is not connected ");
     292                 :          0 :                 return -1;
     293                 :            :         }
     294                 :            : 
     295                 :          0 :         DPAA2_BUS_DEBUG("--> Map address: 0x%"PRIx64", size: %"PRIu64"",
     296                 :            :                         (uint64_t)dma_map.vaddr, (uint64_t)dma_map.size);
     297                 :          0 :         ret = ioctl(group->container->fd, VFIO_IOMMU_MAP_DMA, &dma_map);
     298         [ #  # ]:          0 :         if (ret) {
     299                 :          0 :                 DPAA2_BUS_ERR("VFIO_IOMMU_MAP_DMA API(errno = %d)",
     300                 :            :                                 errno);
     301                 :          0 :                 return -1;
     302                 :            :         }
     303                 :            : 
     304                 :            :         return 0;
     305                 :            : }
     306                 :            : 
     307                 :            : static int
     308                 :          0 : fslmc_unmap_dma(uint64_t vaddr, uint64_t iovaddr __rte_unused, size_t len)
     309                 :            : {
     310                 :            :         struct fslmc_vfio_group *group;
     311                 :          0 :         struct vfio_iommu_type1_dma_unmap dma_unmap = {
     312                 :            :                 .argsz = sizeof(struct vfio_iommu_type1_dma_unmap),
     313                 :            :                 .flags = 0,
     314                 :            :         };
     315                 :            :         int ret;
     316                 :            : 
     317         [ #  # ]:          0 :         if (fslmc_iommu_type == RTE_VFIO_NOIOMMU) {
     318                 :          0 :                 DPAA2_BUS_DEBUG("Running in NOIOMMU mode");
     319                 :          0 :                 return 0;
     320                 :            :         }
     321                 :            : 
     322                 :          0 :         dma_unmap.size = len;
     323                 :          0 :         dma_unmap.iova = vaddr;
     324                 :            : 
     325                 :            :         /* SET DMA MAP for IOMMU */
     326                 :            :         group = &vfio_group;
     327                 :            : 
     328         [ #  # ]:          0 :         if (!group->container) {
     329                 :          0 :                 DPAA2_BUS_ERR("Container is not connected ");
     330                 :          0 :                 return -1;
     331                 :            :         }
     332                 :            : 
     333                 :          0 :         DPAA2_BUS_DEBUG("--> Unmap address: 0x%"PRIx64", size: %"PRIu64"",
     334                 :            :                         (uint64_t)dma_unmap.iova, (uint64_t)dma_unmap.size);
     335                 :          0 :         ret = ioctl(group->container->fd, VFIO_IOMMU_UNMAP_DMA, &dma_unmap);
     336         [ #  # ]:          0 :         if (ret) {
     337                 :          0 :                 DPAA2_BUS_ERR("VFIO_IOMMU_UNMAP_DMA API(errno = %d)",
     338                 :            :                                 errno);
     339                 :          0 :                 return -1;
     340                 :            :         }
     341                 :            : 
     342                 :            :         return 0;
     343                 :            : }
     344                 :            : 
     345                 :            : static int
     346                 :          0 : fslmc_dmamap_seg(const struct rte_memseg_list *msl __rte_unused,
     347                 :            :                 const struct rte_memseg *ms, void *arg)
     348                 :            : {
     349                 :            :         int *n_segs = arg;
     350                 :            :         int ret;
     351                 :            : 
     352                 :            :         /* if IOVA address is invalid, skip */
     353         [ #  # ]:          0 :         if (ms->iova == RTE_BAD_IOVA)
     354                 :            :                 return 0;
     355                 :            : 
     356                 :          0 :         ret = fslmc_map_dma(ms->addr_64, ms->iova, ms->len);
     357         [ #  # ]:          0 :         if (ret)
     358                 :          0 :                 DPAA2_BUS_ERR("Unable to VFIO map (addr=%p, len=%zu)",
     359                 :            :                                 ms->addr, ms->len);
     360                 :            :         else
     361                 :          0 :                 (*n_segs)++;
     362                 :            : 
     363                 :            :         return ret;
     364                 :            : }
     365                 :            : 
     366                 :            : int
     367                 :          0 : rte_fslmc_vfio_mem_dmamap(uint64_t vaddr, uint64_t iova, uint64_t size)
     368                 :            : {
     369                 :            :         int ret;
     370                 :            :         struct fslmc_vfio_group *group;
     371                 :          0 :         struct vfio_iommu_type1_dma_map dma_map = {
     372                 :            :                 .argsz = sizeof(struct vfio_iommu_type1_dma_map),
     373                 :            :                 .flags = VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE,
     374                 :            :         };
     375                 :            : 
     376         [ #  # ]:          0 :         if (fslmc_iommu_type == RTE_VFIO_NOIOMMU) {
     377                 :          0 :                 DPAA2_BUS_DEBUG("Running in NOIOMMU mode");
     378                 :          0 :                 return 0;
     379                 :            :         }
     380                 :            : 
     381                 :            :         /* SET DMA MAP for IOMMU */
     382                 :            :         group = &vfio_group;
     383         [ #  # ]:          0 :         if (!group->container) {
     384                 :          0 :                 DPAA2_BUS_ERR("Container is not connected");
     385                 :          0 :                 return -1;
     386                 :            :         }
     387                 :            : 
     388                 :          0 :         dma_map.size = size;
     389                 :          0 :         dma_map.vaddr = vaddr;
     390                 :          0 :         dma_map.iova = iova;
     391                 :            : 
     392                 :          0 :         DPAA2_BUS_DEBUG("VFIOdmamap 0x%"PRIx64":0x%"PRIx64",size 0x%"PRIx64"\n",
     393                 :            :                         (uint64_t)dma_map.vaddr, (uint64_t)dma_map.iova,
     394                 :            :                         (uint64_t)dma_map.size);
     395                 :          0 :         ret = ioctl(group->container->fd, VFIO_IOMMU_MAP_DMA,
     396                 :            :                     &dma_map);
     397         [ #  # ]:          0 :         if (ret) {
     398                 :          0 :                 printf("Unable to map DMA address (errno = %d)\n",
     399                 :          0 :                         errno);
     400                 :          0 :                 return ret;
     401                 :            :         }
     402                 :            : 
     403                 :            :         return 0;
     404                 :            : }
     405                 :            : 
     406                 :          0 : int rte_fslmc_vfio_dmamap(void)
     407                 :            : {
     408                 :          0 :         int i = 0, ret;
     409                 :            : 
     410                 :            :         /* Lock before parsing and registering callback to memory subsystem */
     411                 :          0 :         rte_mcfg_mem_read_lock();
     412                 :            : 
     413         [ #  # ]:          0 :         if (rte_memseg_walk(fslmc_dmamap_seg, &i) < 0) {
     414                 :          0 :                 rte_mcfg_mem_read_unlock();
     415                 :          0 :                 return -1;
     416                 :            :         }
     417                 :            : 
     418                 :          0 :         ret = rte_mem_event_callback_register("fslmc_memevent_clb",
     419                 :            :                         fslmc_memevent_cb, NULL);
     420   [ #  #  #  # ]:          0 :         if (ret && rte_errno == ENOTSUP)
     421                 :          0 :                 DPAA2_BUS_DEBUG("Memory event callbacks not supported");
     422         [ #  # ]:          0 :         else if (ret)
     423                 :          0 :                 DPAA2_BUS_DEBUG("Unable to install memory handler");
     424                 :            :         else
     425                 :          0 :                 DPAA2_BUS_DEBUG("Installed memory callback handler");
     426                 :            : 
     427                 :          0 :         DPAA2_BUS_DEBUG("Total %d segments found.", i);
     428                 :            : 
     429                 :            :         /* TODO - This is a W.A. as VFIO currently does not add the mapping of
     430                 :            :          * the interrupt region to SMMU. This should be removed once the
     431                 :            :          * support is added in the Kernel.
     432                 :            :          */
     433                 :          0 :         vfio_map_irq_region(&vfio_group);
     434                 :            : 
     435                 :            :         /* Existing segments have been mapped and memory callback for hotplug
     436                 :            :          * has been installed.
     437                 :            :          */
     438                 :          0 :         rte_mcfg_mem_read_unlock();
     439                 :            : 
     440                 :          0 :         return 0;
     441                 :            : }
     442                 :            : 
     443                 :            : static int
     444                 :          0 : fslmc_vfio_setup_device(const char *sysfs_base, const char *dev_addr,
     445                 :            :                 int *vfio_dev_fd, struct vfio_device_info *device_info)
     446                 :            : {
     447                 :          0 :         struct vfio_group_status group_status = {
     448                 :            :                         .argsz = sizeof(group_status)
     449                 :            :         };
     450                 :            :         int vfio_group_fd, vfio_container_fd, iommu_group_no, ret;
     451                 :            : 
     452                 :            :         /* get group number */
     453                 :          0 :         ret = rte_vfio_get_group_num(sysfs_base, dev_addr, &iommu_group_no);
     454         [ #  # ]:          0 :         if (ret < 0)
     455                 :            :                 return -1;
     456                 :            : 
     457                 :            :         /* get the actual group fd */
     458                 :          0 :         vfio_group_fd = rte_vfio_get_group_fd(iommu_group_no);
     459         [ #  # ]:          0 :         if (vfio_group_fd < 0 && vfio_group_fd != -ENOENT)
     460                 :            :                 return -1;
     461                 :            : 
     462                 :            :         /*
     463                 :            :          * if vfio_group_fd == -ENOENT, that means the device
     464                 :            :          * isn't managed by VFIO
     465                 :            :          */
     466         [ #  # ]:          0 :         if (vfio_group_fd == -ENOENT) {
     467                 :          0 :                 RTE_LOG(WARNING, EAL, " %s not managed by VFIO driver, skipping\n",
     468                 :            :                                 dev_addr);
     469                 :          0 :                 return 1;
     470                 :            :         }
     471                 :            : 
     472                 :            :         /* Opens main vfio file descriptor which represents the "container" */
     473                 :          0 :         vfio_container_fd = rte_vfio_get_container_fd();
     474         [ #  # ]:          0 :         if (vfio_container_fd < 0) {
     475                 :          0 :                 DPAA2_BUS_ERR("Failed to open VFIO container");
     476                 :          0 :                 return -errno;
     477                 :            :         }
     478                 :            : 
     479                 :            :         /* check if the group is viable */
     480                 :          0 :         ret = ioctl(vfio_group_fd, VFIO_GROUP_GET_STATUS, &group_status);
     481         [ #  # ]:          0 :         if (ret) {
     482                 :          0 :                 DPAA2_BUS_ERR("  %s cannot get group status, "
     483                 :            :                                 "error %i (%s)\n", dev_addr,
     484                 :            :                                 errno, strerror(errno));
     485                 :          0 :                 close(vfio_group_fd);
     486                 :          0 :                 rte_vfio_clear_group(vfio_group_fd);
     487                 :          0 :                 return -1;
     488         [ #  # ]:          0 :         } else if (!(group_status.flags & VFIO_GROUP_FLAGS_VIABLE)) {
     489                 :          0 :                 DPAA2_BUS_ERR("  %s VFIO group is not viable!\n", dev_addr);
     490                 :          0 :                 close(vfio_group_fd);
     491                 :          0 :                 rte_vfio_clear_group(vfio_group_fd);
     492                 :          0 :                 return -1;
     493                 :            :         }
     494                 :            :         /* At this point, we know that this group is viable (meaning,
     495                 :            :          * all devices are either bound to VFIO or not bound to anything)
     496                 :            :          */
     497                 :            : 
     498                 :            :         /* check if group does not have a container yet */
     499         [ #  # ]:          0 :         if (!(group_status.flags & VFIO_GROUP_FLAGS_CONTAINER_SET)) {
     500                 :            : 
     501                 :            :                 /* add group to a container */
     502                 :          0 :                 ret = ioctl(vfio_group_fd, VFIO_GROUP_SET_CONTAINER,
     503                 :            :                                 &vfio_container_fd);
     504         [ #  # ]:          0 :                 if (ret) {
     505                 :          0 :                         DPAA2_BUS_ERR("  %s cannot add VFIO group to container, "
     506                 :            :                                         "error %i (%s)\n", dev_addr,
     507                 :            :                                         errno, strerror(errno));
     508                 :          0 :                         close(vfio_group_fd);
     509                 :          0 :                         close(vfio_container_fd);
     510                 :          0 :                         rte_vfio_clear_group(vfio_group_fd);
     511                 :          0 :                         return -1;
     512                 :            :                 }
     513                 :            : 
     514                 :            :                 /*
     515                 :            :                  * set an IOMMU type for container
     516                 :            :                  *
     517                 :            :                  */
     518         [ #  # ]:          0 :                 if (ioctl(vfio_container_fd, VFIO_CHECK_EXTENSION,
     519                 :            :                           fslmc_iommu_type)) {
     520                 :          0 :                         ret = ioctl(vfio_container_fd, VFIO_SET_IOMMU,
     521                 :            :                                     fslmc_iommu_type);
     522         [ #  # ]:          0 :                         if (ret) {
     523                 :          0 :                                 DPAA2_BUS_ERR("Failed to setup VFIO iommu");
     524                 :          0 :                                 close(vfio_group_fd);
     525                 :          0 :                                 close(vfio_container_fd);
     526                 :          0 :                                 return -errno;
     527                 :            :                         }
     528                 :            :                 } else {
     529                 :          0 :                         DPAA2_BUS_ERR("No supported IOMMU available");
     530                 :          0 :                         close(vfio_group_fd);
     531                 :          0 :                         close(vfio_container_fd);
     532                 :          0 :                         return -EINVAL;
     533                 :            :                 }
     534                 :            :         }
     535                 :            : 
     536                 :            :         /* get a file descriptor for the device */
     537                 :          0 :         *vfio_dev_fd = ioctl(vfio_group_fd, VFIO_GROUP_GET_DEVICE_FD, dev_addr);
     538         [ #  # ]:          0 :         if (*vfio_dev_fd < 0) {
     539                 :            :                 /* if we cannot get a device fd, this implies a problem with
     540                 :            :                  * the VFIO group or the container not having IOMMU configured.
     541                 :            :                  */
     542                 :            : 
     543                 :          0 :                 DPAA2_BUS_WARN("Getting a vfio_dev_fd for %s failed", dev_addr);
     544                 :          0 :                 close(vfio_group_fd);
     545                 :          0 :                 close(vfio_container_fd);
     546                 :          0 :                 rte_vfio_clear_group(vfio_group_fd);
     547                 :          0 :                 return -1;
     548                 :            :         }
     549                 :            : 
     550                 :            :         /* test and setup the device */
     551                 :          0 :         ret = ioctl(*vfio_dev_fd, VFIO_DEVICE_GET_INFO, device_info);
     552         [ #  # ]:          0 :         if (ret) {
     553                 :          0 :                 DPAA2_BUS_ERR("  %s cannot get device info, error %i (%s)",
     554                 :            :                                 dev_addr, errno, strerror(errno));
     555                 :          0 :                 close(*vfio_dev_fd);
     556                 :          0 :                 close(vfio_group_fd);
     557                 :          0 :                 close(vfio_container_fd);
     558                 :          0 :                 rte_vfio_clear_group(vfio_group_fd);
     559                 :          0 :                 return -1;
     560                 :            :         }
     561                 :            : 
     562                 :            :         return 0;
     563                 :            : }
     564                 :            : 
     565                 :          0 : static intptr_t vfio_map_mcp_obj(const char *mcp_obj)
     566                 :            : {
     567                 :            :         intptr_t v_addr = (intptr_t)MAP_FAILED;
     568                 :            :         int32_t ret, mc_fd;
     569                 :            :         struct vfio_group_status status = { .argsz = sizeof(status) };
     570                 :            : 
     571                 :          0 :         struct vfio_device_info d_info = { .argsz = sizeof(d_info) };
     572                 :          0 :         struct vfio_region_info reg_info = { .argsz = sizeof(reg_info) };
     573                 :            : 
     574                 :          0 :         fslmc_vfio_setup_device(SYSFS_FSL_MC_DEVICES, mcp_obj,
     575                 :            :                         &mc_fd, &d_info);
     576                 :            : 
     577                 :            :         /* getting device region info*/
     578                 :          0 :         ret = ioctl(mc_fd, VFIO_DEVICE_GET_REGION_INFO, &reg_info);
     579         [ #  # ]:          0 :         if (ret < 0) {
     580                 :          0 :                 DPAA2_BUS_ERR("Error in VFIO getting REGION_INFO");
     581                 :          0 :                 goto MC_FAILURE;
     582                 :            :         }
     583                 :            : 
     584                 :          0 :         v_addr = (size_t)mmap(NULL, reg_info.size,
     585                 :            :                 PROT_WRITE | PROT_READ, MAP_SHARED,
     586                 :          0 :                 mc_fd, reg_info.offset);
     587                 :            : 
     588                 :          0 : MC_FAILURE:
     589                 :          0 :         close(mc_fd);
     590                 :            : 
     591                 :          0 :         return v_addr;
     592                 :            : }
     593                 :            : 
     594                 :            : #define IRQ_SET_BUF_LEN  (sizeof(struct vfio_irq_set) + sizeof(int))
     595                 :            : 
     596                 :          0 : int rte_dpaa2_intr_enable(struct rte_intr_handle *intr_handle, int index)
     597                 :            : {
     598                 :            :         int len, ret;
     599                 :            :         char irq_set_buf[IRQ_SET_BUF_LEN];
     600                 :            :         struct vfio_irq_set *irq_set;
     601                 :            :         int *fd_ptr, vfio_dev_fd;
     602                 :            : 
     603                 :            :         len = sizeof(irq_set_buf);
     604                 :            : 
     605                 :            :         irq_set = (struct vfio_irq_set *)irq_set_buf;
     606                 :          0 :         irq_set->argsz = len;
     607                 :          0 :         irq_set->count = 1;
     608                 :          0 :         irq_set->flags =
     609                 :            :                 VFIO_IRQ_SET_DATA_EVENTFD | VFIO_IRQ_SET_ACTION_TRIGGER;
     610                 :          0 :         irq_set->index = index;
     611                 :          0 :         irq_set->start = 0;
     612                 :            :         fd_ptr = (int *)&irq_set->data;
     613                 :          0 :         *fd_ptr = rte_intr_fd_get(intr_handle);
     614                 :            : 
     615                 :          0 :         vfio_dev_fd = rte_intr_dev_fd_get(intr_handle);
     616                 :          0 :         ret = ioctl(vfio_dev_fd, VFIO_DEVICE_SET_IRQS, irq_set);
     617         [ #  # ]:          0 :         if (ret) {
     618                 :          0 :                 DPAA2_BUS_ERR("Error:dpaa2 SET IRQs fd=%d, err = %d(%s)",
     619                 :            :                               rte_intr_fd_get(intr_handle), errno,
     620                 :            :                               strerror(errno));
     621                 :          0 :                 return ret;
     622                 :            :         }
     623                 :            : 
     624                 :            :         return ret;
     625                 :            : }
     626                 :            : 
     627                 :          0 : int rte_dpaa2_intr_disable(struct rte_intr_handle *intr_handle, int index)
     628                 :            : {
     629                 :            :         struct vfio_irq_set *irq_set;
     630                 :            :         char irq_set_buf[IRQ_SET_BUF_LEN];
     631                 :            :         int len, ret, vfio_dev_fd;
     632                 :            : 
     633                 :            :         len = sizeof(struct vfio_irq_set);
     634                 :            : 
     635                 :            :         irq_set = (struct vfio_irq_set *)irq_set_buf;
     636                 :          0 :         irq_set->argsz = len;
     637                 :          0 :         irq_set->flags = VFIO_IRQ_SET_DATA_NONE | VFIO_IRQ_SET_ACTION_TRIGGER;
     638                 :          0 :         irq_set->index = index;
     639                 :          0 :         irq_set->start = 0;
     640                 :          0 :         irq_set->count = 0;
     641                 :            : 
     642                 :          0 :         vfio_dev_fd = rte_intr_dev_fd_get(intr_handle);
     643                 :          0 :         ret = ioctl(vfio_dev_fd, VFIO_DEVICE_SET_IRQS, irq_set);
     644         [ #  # ]:          0 :         if (ret)
     645                 :          0 :                 DPAA2_BUS_ERR(
     646                 :            :                         "Error disabling dpaa2 interrupts for fd %d",
     647                 :            :                         rte_intr_fd_get(intr_handle));
     648                 :            : 
     649                 :          0 :         return ret;
     650                 :            : }
     651                 :            : 
     652                 :            : /* set up interrupt support (but not enable interrupts) */
     653                 :            : int
     654                 :          0 : rte_dpaa2_vfio_setup_intr(struct rte_intr_handle *intr_handle,
     655                 :            :                           int vfio_dev_fd,
     656                 :            :                           int num_irqs)
     657                 :            : {
     658                 :            :         int i, ret;
     659                 :            : 
     660                 :            :         /* start from MSI-X interrupt type */
     661         [ #  # ]:          0 :         for (i = 0; i < num_irqs; i++) {
     662                 :          0 :                 struct vfio_irq_info irq_info = { .argsz = sizeof(irq_info) };
     663                 :            :                 int fd = -1;
     664                 :            : 
     665                 :          0 :                 irq_info.index = i;
     666                 :            : 
     667                 :          0 :                 ret = ioctl(vfio_dev_fd, VFIO_DEVICE_GET_IRQ_INFO, &irq_info);
     668         [ #  # ]:          0 :                 if (ret < 0) {
     669                 :          0 :                         DPAA2_BUS_ERR("Cannot get IRQ(%d) info, error %i (%s)",
     670                 :            :                                       i, errno, strerror(errno));
     671                 :          0 :                         return -1;
     672                 :            :                 }
     673                 :            : 
     674                 :            :                 /* if this vector cannot be used with eventfd,
     675                 :            :                  * fail if we explicitly
     676                 :            :                  * specified interrupt type, otherwise continue
     677                 :            :                  */
     678         [ #  # ]:          0 :                 if ((irq_info.flags & VFIO_IRQ_INFO_EVENTFD) == 0)
     679                 :          0 :                         continue;
     680                 :            : 
     681                 :            :                 /* set up an eventfd for interrupts */
     682                 :          0 :                 fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
     683         [ #  # ]:          0 :                 if (fd < 0) {
     684                 :          0 :                         DPAA2_BUS_ERR("Cannot set up eventfd, error %i (%s)",
     685                 :            :                                       errno, strerror(errno));
     686                 :          0 :                         return -1;
     687                 :            :                 }
     688                 :            : 
     689         [ #  # ]:          0 :                 if (rte_intr_fd_set(intr_handle, fd))
     690                 :          0 :                         return -rte_errno;
     691                 :            : 
     692         [ #  # ]:          0 :                 if (rte_intr_type_set(intr_handle, RTE_INTR_HANDLE_VFIO_MSI))
     693                 :          0 :                         return -rte_errno;
     694                 :            : 
     695         [ #  # ]:          0 :                 if (rte_intr_dev_fd_set(intr_handle, vfio_dev_fd))
     696                 :          0 :                         return -rte_errno;
     697                 :            : 
     698                 :            :                 return 0;
     699                 :            :         }
     700                 :            : 
     701                 :            :         /* if we're here, we haven't found a suitable interrupt vector */
     702                 :            :         return -1;
     703                 :            : }
     704                 :            : 
     705                 :            : /*
     706                 :            :  * fslmc_process_iodevices for processing only IO (ETH, CRYPTO, and possibly
     707                 :            :  * EVENT) devices.
     708                 :            :  */
     709                 :            : static int
     710                 :          0 : fslmc_process_iodevices(struct rte_dpaa2_device *dev)
     711                 :            : {
     712                 :            :         int dev_fd;
     713                 :          0 :         struct vfio_device_info device_info = { .argsz = sizeof(device_info) };
     714                 :            :         struct rte_dpaa2_object *object = NULL;
     715                 :            : 
     716                 :          0 :         fslmc_vfio_setup_device(SYSFS_FSL_MC_DEVICES, dev->device.name,
     717                 :            :                         &dev_fd, &device_info);
     718                 :            : 
     719      [ #  #  # ]:          0 :         switch (dev->dev_type) {
     720                 :          0 :         case DPAA2_ETH:
     721                 :          0 :                 rte_dpaa2_vfio_setup_intr(dev->intr_handle, dev_fd,
     722                 :          0 :                                           device_info.num_irqs);
     723                 :          0 :                 break;
     724                 :          0 :         case DPAA2_CON:
     725                 :            :         case DPAA2_IO:
     726                 :            :         case DPAA2_CI:
     727                 :            :         case DPAA2_BPOOL:
     728                 :            :         case DPAA2_DPRTC:
     729                 :            :         case DPAA2_MUX:
     730                 :            :         case DPAA2_DPRC:
     731         [ #  # ]:          0 :                 TAILQ_FOREACH(object, &dpaa2_obj_list, next) {
     732         [ #  # ]:          0 :                         if (dev->dev_type == object->dev_type)
     733                 :          0 :                                 object->create(dev_fd, &device_info,
     734                 :          0 :                                                dev->object_id);
     735                 :            :                         else
     736                 :          0 :                                 continue;
     737                 :            :                 }
     738                 :            :                 break;
     739                 :            :         default:
     740                 :            :                 break;
     741                 :            :         }
     742                 :            : 
     743                 :          0 :         DPAA2_BUS_LOG(DEBUG, "Device (%s) abstracted from VFIO",
     744                 :            :                       dev->device.name);
     745                 :          0 :         return 0;
     746                 :            : }
     747                 :            : 
     748                 :            : static int
     749                 :          0 : fslmc_process_mcp(struct rte_dpaa2_device *dev)
     750                 :            : {
     751                 :            :         int ret;
     752                 :            :         intptr_t v_addr;
     753                 :          0 :         struct fsl_mc_io dpmng  = {0};
     754                 :          0 :         struct mc_version mc_ver_info = {0};
     755                 :            : 
     756                 :          0 :         rte_mcp_ptr_list = malloc(sizeof(void *) * (MC_PORTAL_INDEX + 1));
     757         [ #  # ]:          0 :         if (!rte_mcp_ptr_list) {
     758                 :          0 :                 DPAA2_BUS_ERR("Unable to allocate MC portal memory");
     759                 :            :                 ret = -ENOMEM;
     760                 :          0 :                 goto cleanup;
     761                 :            :         }
     762                 :            : 
     763                 :          0 :         v_addr = vfio_map_mcp_obj(dev->device.name);
     764         [ #  # ]:          0 :         if (v_addr == (intptr_t)MAP_FAILED) {
     765                 :          0 :                 DPAA2_BUS_ERR("Error mapping region (errno = %d)", errno);
     766                 :            :                 ret = -1;
     767                 :          0 :                 goto cleanup;
     768                 :            :         }
     769                 :            : 
     770                 :            :         /* check the MC version compatibility */
     771                 :          0 :         dpmng.regs = (void *)v_addr;
     772                 :            : 
     773                 :            :         /* In case of secondary processes, MC version check is no longer
     774                 :            :          * required.
     775                 :            :          */
     776         [ #  # ]:          0 :         if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
     777                 :          0 :                 rte_mcp_ptr_list[MC_PORTAL_INDEX] = (void *)v_addr;
     778                 :          0 :                 return 0;
     779                 :            :         }
     780                 :            : 
     781         [ #  # ]:          0 :         if (mc_get_version(&dpmng, CMD_PRI_LOW, &mc_ver_info)) {
     782                 :          0 :                 DPAA2_BUS_ERR("Unable to obtain MC version");
     783                 :            :                 ret = -1;
     784                 :          0 :                 goto cleanup;
     785                 :            :         }
     786                 :            : 
     787         [ #  # ]:          0 :         if ((mc_ver_info.major != MC_VER_MAJOR) ||
     788         [ #  # ]:          0 :             (mc_ver_info.minor < MC_VER_MINOR)) {
     789                 :          0 :                 DPAA2_BUS_ERR("DPAA2 MC version not compatible!"
     790                 :            :                               " Expected %d.%d.x, Detected %d.%d.%d",
     791                 :            :                               MC_VER_MAJOR, MC_VER_MINOR,
     792                 :            :                               mc_ver_info.major, mc_ver_info.minor,
     793                 :            :                               mc_ver_info.revision);
     794                 :            :                 ret = -1;
     795                 :          0 :                 goto cleanup;
     796                 :            :         }
     797                 :          0 :         rte_mcp_ptr_list[MC_PORTAL_INDEX] = (void *)v_addr;
     798                 :            : 
     799                 :          0 :         return 0;
     800                 :            : 
     801                 :          0 : cleanup:
     802         [ #  # ]:          0 :         if (rte_mcp_ptr_list) {
     803                 :          0 :                 free(rte_mcp_ptr_list);
     804                 :          0 :                 rte_mcp_ptr_list = NULL;
     805                 :            :         }
     806                 :            : 
     807                 :            :         return ret;
     808                 :            : }
     809                 :            : 
     810                 :            : int
     811                 :          0 : fslmc_vfio_process_group(void)
     812                 :            : {
     813                 :            :         int ret;
     814                 :            :         int found_mportal = 0;
     815                 :            :         struct rte_dpaa2_device *dev, *dev_temp;
     816                 :            :         bool is_dpmcp_in_blocklist = false, is_dpio_in_blocklist = false;
     817                 :            :         int dpmcp_count = 0, dpio_count = 0, current_device;
     818                 :            : 
     819         [ #  # ]:          0 :         RTE_TAILQ_FOREACH_SAFE(dev, &rte_fslmc_bus.device_list, next,
     820                 :            :                 dev_temp) {
     821         [ #  # ]:          0 :                 if (dev->dev_type == DPAA2_MPORTAL) {
     822                 :          0 :                         dpmcp_count++;
     823         [ #  # ]:          0 :                         if (dev->device.devargs &&
     824         [ #  # ]:          0 :                             dev->device.devargs->policy == RTE_DEV_BLOCKED)
     825                 :            :                                 is_dpmcp_in_blocklist = true;
     826                 :            :                 }
     827         [ #  # ]:          0 :                 if (dev->dev_type == DPAA2_IO) {
     828                 :          0 :                         dpio_count++;
     829         [ #  # ]:          0 :                         if (dev->device.devargs &&
     830         [ #  # ]:          0 :                             dev->device.devargs->policy == RTE_DEV_BLOCKED)
     831                 :            :                                 is_dpio_in_blocklist = true;
     832                 :            :                 }
     833                 :            :         }
     834                 :            : 
     835                 :            :         /* Search the MCP as that should be initialized first. */
     836                 :            :         current_device = 0;
     837         [ #  # ]:          0 :         RTE_TAILQ_FOREACH_SAFE(dev, &rte_fslmc_bus.device_list, next,
     838                 :            :                 dev_temp) {
     839         [ #  # ]:          0 :                 if (dev->dev_type == DPAA2_MPORTAL) {
     840                 :          0 :                         current_device++;
     841         [ #  # ]:          0 :                         if (dev->device.devargs &&
     842         [ #  # ]:          0 :                             dev->device.devargs->policy == RTE_DEV_BLOCKED) {
     843                 :          0 :                                 DPAA2_BUS_LOG(DEBUG, "%s Blocked, skipping",
     844                 :            :                                               dev->device.name);
     845         [ #  # ]:          0 :                                 TAILQ_REMOVE(&rte_fslmc_bus.device_list,
     846                 :            :                                                 dev, next);
     847                 :          0 :                                 continue;
     848                 :            :                         }
     849                 :            : 
     850   [ #  #  #  # ]:          0 :                         if (rte_eal_process_type() == RTE_PROC_SECONDARY &&
     851                 :            :                             !is_dpmcp_in_blocklist) {
     852                 :          0 :                                 if (dpmcp_count == 1 ||
     853         [ #  # ]:          0 :                                     current_device != dpmcp_count) {
     854         [ #  # ]:          0 :                                         TAILQ_REMOVE(&rte_fslmc_bus.device_list,
     855                 :            :                                                      dev, next);
     856                 :          0 :                                         continue;
     857                 :            :                                 }
     858                 :            :                         }
     859                 :            : 
     860         [ #  # ]:          0 :                         if (!found_mportal) {
     861                 :          0 :                                 ret = fslmc_process_mcp(dev);
     862         [ #  # ]:          0 :                                 if (ret) {
     863                 :          0 :                                         DPAA2_BUS_ERR("Unable to map MC Portal");
     864                 :          0 :                                         return -1;
     865                 :            :                                 }
     866                 :            :                                 found_mportal = 1;
     867                 :            :                         }
     868                 :            : 
     869         [ #  # ]:          0 :                         TAILQ_REMOVE(&rte_fslmc_bus.device_list, dev, next);
     870                 :          0 :                         free(dev);
     871                 :            :                         dev = NULL;
     872                 :            :                         /* Ideally there is only a single dpmcp, but in case
     873                 :            :                          * multiple exists, looping on remaining devices.
     874                 :            :                          */
     875                 :            :                 }
     876                 :            :         }
     877                 :            : 
     878                 :            :         /* Cannot continue if there is not even a single mportal */
     879         [ #  # ]:          0 :         if (!found_mportal) {
     880                 :          0 :                 DPAA2_BUS_ERR("No MC Portal device found. Not continuing");
     881                 :          0 :                 return -1;
     882                 :            :         }
     883                 :            : 
     884                 :            :         /* Search for DPRC device next as it updates endpoint of
     885                 :            :          * other devices.
     886                 :            :          */
     887                 :            :         current_device = 0;
     888         [ #  # ]:          0 :         RTE_TAILQ_FOREACH_SAFE(dev, &rte_fslmc_bus.device_list, next, dev_temp) {
     889         [ #  # ]:          0 :                 if (dev->dev_type == DPAA2_DPRC) {
     890                 :          0 :                         ret = fslmc_process_iodevices(dev);
     891         [ #  # ]:          0 :                         if (ret) {
     892                 :          0 :                                 DPAA2_BUS_ERR("Unable to process dprc");
     893                 :          0 :                                 return -1;
     894                 :            :                         }
     895         [ #  # ]:          0 :                         TAILQ_REMOVE(&rte_fslmc_bus.device_list, dev, next);
     896                 :            :                 }
     897                 :            :         }
     898                 :            : 
     899                 :            :         current_device = 0;
     900         [ #  # ]:          0 :         RTE_TAILQ_FOREACH_SAFE(dev, &rte_fslmc_bus.device_list, next,
     901                 :            :                 dev_temp) {
     902         [ #  # ]:          0 :                 if (dev->dev_type == DPAA2_IO)
     903                 :          0 :                         current_device++;
     904         [ #  # ]:          0 :                 if (dev->device.devargs &&
     905         [ #  # ]:          0 :                     dev->device.devargs->policy == RTE_DEV_BLOCKED) {
     906                 :          0 :                         DPAA2_BUS_LOG(DEBUG, "%s Blocked, skipping",
     907                 :            :                                       dev->device.name);
     908         [ #  # ]:          0 :                         TAILQ_REMOVE(&rte_fslmc_bus.device_list, dev, next);
     909                 :          0 :                         continue;
     910                 :            :                 }
     911         [ #  # ]:          0 :                 if (rte_eal_process_type() == RTE_PROC_SECONDARY &&
     912         [ #  # ]:          0 :                     dev->dev_type != DPAA2_ETH &&
     913                 :            :                     dev->dev_type != DPAA2_CRYPTO &&
     914                 :          0 :                     dev->dev_type != DPAA2_QDMA &&
     915                 :            :                     dev->dev_type != DPAA2_IO) {
     916         [ #  # ]:          0 :                         TAILQ_REMOVE(&rte_fslmc_bus.device_list, dev, next);
     917                 :          0 :                         continue;
     918                 :            :                 }
     919   [ #  #  #  # ]:          0 :                 switch (dev->dev_type) {
     920                 :          0 :                 case DPAA2_ETH:
     921                 :            :                 case DPAA2_CRYPTO:
     922                 :            :                 case DPAA2_QDMA:
     923                 :          0 :                         ret = fslmc_process_iodevices(dev);
     924         [ #  # ]:          0 :                         if (ret) {
     925                 :          0 :                                 DPAA2_BUS_DEBUG("Dev (%s) init failed",
     926                 :            :                                                 dev->device.name);
     927                 :          0 :                                 return ret;
     928                 :            :                         }
     929                 :            :                         break;
     930                 :          0 :                 case DPAA2_CON:
     931                 :            :                 case DPAA2_CI:
     932                 :            :                 case DPAA2_BPOOL:
     933                 :            :                 case DPAA2_DPRTC:
     934                 :            :                 case DPAA2_MUX:
     935                 :            :                         /* IN case of secondary processes, all control objects
     936                 :            :                          * like dpbp, dpcon, dpci are not initialized/required
     937                 :            :                          * - all of these are assumed to be initialized and made
     938                 :            :                          *   available by primary.
     939                 :            :                          */
     940         [ #  # ]:          0 :                         if (rte_eal_process_type() == RTE_PROC_SECONDARY)
     941                 :          0 :                                 continue;
     942                 :            : 
     943                 :            :                         /* Call the object creation routine and remove the
     944                 :            :                          * device entry from device list
     945                 :            :                          */
     946                 :          0 :                         ret = fslmc_process_iodevices(dev);
     947         [ #  # ]:          0 :                         if (ret) {
     948                 :          0 :                                 DPAA2_BUS_DEBUG("Dev (%s) init failed",
     949                 :            :                                                 dev->device.name);
     950                 :          0 :                                 return -1;
     951                 :            :                         }
     952                 :            : 
     953                 :            :                         break;
     954                 :          0 :                 case DPAA2_IO:
     955         [ #  # ]:          0 :                         if (!is_dpio_in_blocklist && dpio_count > 1) {
     956         [ #  # ]:          0 :                                 if (rte_eal_process_type() == RTE_PROC_SECONDARY
     957         [ #  # ]:          0 :                                     && current_device != dpio_count) {
     958         [ #  # ]:          0 :                                         TAILQ_REMOVE(&rte_fslmc_bus.device_list,
     959                 :            :                                                      dev, next);
     960                 :          0 :                                         break;
     961                 :            :                                 }
     962         [ #  # ]:          0 :                                 if (rte_eal_process_type() == RTE_PROC_PRIMARY
     963         [ #  # ]:          0 :                                     && current_device == dpio_count) {
     964         [ #  # ]:          0 :                                         TAILQ_REMOVE(&rte_fslmc_bus.device_list,
     965                 :            :                                                      dev, next);
     966                 :          0 :                                         break;
     967                 :            :                                 }
     968                 :            :                         }
     969                 :            : 
     970                 :          0 :                         ret = fslmc_process_iodevices(dev);
     971         [ #  # ]:          0 :                         if (ret) {
     972                 :          0 :                                 DPAA2_BUS_DEBUG("Dev (%s) init failed",
     973                 :            :                                                 dev->device.name);
     974                 :          0 :                                 return -1;
     975                 :            :                         }
     976                 :            : 
     977                 :            :                         break;
     978                 :          0 :                 case DPAA2_UNKNOWN:
     979                 :            :                 default:
     980                 :            :                         /* Unknown - ignore */
     981                 :          0 :                         DPAA2_BUS_DEBUG("Found unknown device (%s)",
     982                 :            :                                         dev->device.name);
     983         [ #  # ]:          0 :                         TAILQ_REMOVE(&rte_fslmc_bus.device_list, dev, next);
     984                 :          0 :                         free(dev);
     985                 :            :                         dev = NULL;
     986                 :            :                 }
     987                 :            :         }
     988                 :            : 
     989                 :            :         return 0;
     990                 :            : }
     991                 :            : 
     992                 :            : int
     993                 :          0 : fslmc_vfio_setup_group(void)
     994                 :            : {
     995                 :            :         int groupid;
     996                 :            :         int ret;
     997                 :            :         int vfio_container_fd;
     998                 :          0 :         struct vfio_group_status status = { .argsz = sizeof(status) };
     999                 :            : 
    1000                 :            :         /* if already done once */
    1001         [ #  # ]:          0 :         if (container_device_fd)
    1002                 :            :                 return 0;
    1003                 :            : 
    1004                 :          0 :         ret = fslmc_get_container_group(&groupid);
    1005         [ #  # ]:          0 :         if (ret)
    1006                 :            :                 return ret;
    1007                 :            : 
    1008                 :            :         /* In case this group was already opened, continue without any
    1009                 :            :          * processing.
    1010                 :            :          */
    1011         [ #  # ]:          0 :         if (vfio_group.groupid == groupid) {
    1012                 :          0 :                 DPAA2_BUS_ERR("groupid already exists %d", groupid);
    1013                 :          0 :                 return 0;
    1014                 :            :         }
    1015                 :            : 
    1016                 :          0 :         ret = rte_vfio_container_create();
    1017         [ #  # ]:          0 :         if (ret < 0) {
    1018                 :          0 :                 DPAA2_BUS_ERR("Failed to open VFIO container");
    1019                 :          0 :                 return ret;
    1020                 :            :         }
    1021                 :            :         vfio_container_fd = ret;
    1022                 :            : 
    1023                 :            :         /* Get the actual group fd */
    1024                 :          0 :         ret = rte_vfio_container_group_bind(vfio_container_fd, groupid);
    1025         [ #  # ]:          0 :         if (ret < 0)
    1026                 :            :                 return ret;
    1027                 :          0 :         vfio_group.fd = ret;
    1028                 :            : 
    1029                 :            :         /* Check group viability */
    1030                 :          0 :         ret = ioctl(vfio_group.fd, VFIO_GROUP_GET_STATUS, &status);
    1031         [ #  # ]:          0 :         if (ret) {
    1032                 :          0 :                 DPAA2_BUS_ERR("VFIO error getting group status");
    1033                 :          0 :                 close(vfio_group.fd);
    1034                 :          0 :                 rte_vfio_clear_group(vfio_group.fd);
    1035                 :          0 :                 return ret;
    1036                 :            :         }
    1037                 :            : 
    1038         [ #  # ]:          0 :         if (!(status.flags & VFIO_GROUP_FLAGS_VIABLE)) {
    1039                 :          0 :                 DPAA2_BUS_ERR("VFIO group not viable");
    1040                 :          0 :                 close(vfio_group.fd);
    1041                 :          0 :                 rte_vfio_clear_group(vfio_group.fd);
    1042                 :          0 :                 return -EPERM;
    1043                 :            :         }
    1044                 :            :         /* Since Group is VIABLE, Store the groupid */
    1045                 :          0 :         vfio_group.groupid = groupid;
    1046                 :            : 
    1047                 :            :         /* check if group does not have a container yet */
    1048         [ #  # ]:          0 :         if (!(status.flags & VFIO_GROUP_FLAGS_CONTAINER_SET)) {
    1049                 :            :                 /* Now connect this IOMMU group to given container */
    1050                 :          0 :                 ret = vfio_connect_container();
    1051         [ #  # ]:          0 :                 if (ret) {
    1052                 :          0 :                         DPAA2_BUS_ERR(
    1053                 :            :                                 "Error connecting container with groupid %d",
    1054                 :            :                                 groupid);
    1055                 :          0 :                         close(vfio_group.fd);
    1056                 :          0 :                         rte_vfio_clear_group(vfio_group.fd);
    1057                 :          0 :                         return ret;
    1058                 :            :                 }
    1059                 :            :         }
    1060                 :            : 
    1061                 :            :         /* Get Device information */
    1062                 :          0 :         ret = ioctl(vfio_group.fd, VFIO_GROUP_GET_DEVICE_FD, fslmc_container);
    1063         [ #  # ]:          0 :         if (ret < 0) {
    1064                 :          0 :                 DPAA2_BUS_ERR("Error getting device %s fd from group %d",
    1065                 :            :                               fslmc_container, vfio_group.groupid);
    1066                 :          0 :                 close(vfio_group.fd);
    1067                 :          0 :                 rte_vfio_clear_group(vfio_group.fd);
    1068                 :          0 :                 return ret;
    1069                 :            :         }
    1070                 :          0 :         container_device_fd = ret;
    1071                 :          0 :         DPAA2_BUS_DEBUG("VFIO Container FD is [0x%X]",
    1072                 :            :                         container_device_fd);
    1073                 :            : 
    1074                 :          0 :         return 0;
    1075                 :            : }

Generated by: LCOV version 1.14