All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jan Viktorin <viktorin@rehivetech.com>
To: dev@dpdk.org
Cc: Jan Viktorin <viktorin@rehivetech.com>,
	Anatoly Burakov <anatoly.burakov@intel.com>,
	David Marchand <david.marchand@6wind.com>,
	Keith Wiles <keith.wiles@intel.com>,
	Santosh Shukla <sshukla@mvista.com>,
	Stephen Hemminger <stephen@networkplumber.org>,
	Shreyansh Jain <shreyansh.jain@nxp.com>
Subject: [PATCH v3 11/16] vfio: move global vfio_cfg to eal_vfio.c
Date: Mon,  4 Jul 2016 17:16:46 +0200	[thread overview]
Message-ID: <1467645411-15494-12-git-send-email-viktorin@rehivetech.com> (raw)
In-Reply-To: <1467645411-15494-1-git-send-email-viktorin@rehivetech.com>

The vfio_cfg is a module-global variable and so together with this
variable, it is necessary to move functions:

* pci_vfio_get_group_fd
  - renamed to vfio_get_group_fd
  - pci_* version removed (no other call in EAL)

* pci_vfio_setup_device
  - renamed as vfio_setup_device

* pci_vfio_enable
  - renamed as vfio_enable
  - generalized to check for a specific vfio driver presence
  - pci_* specialization preserved as a wrapper

* pci_vfio_is_enabled
  - renamed as vfio_is_enabled
  - generalized to check for a specific vfio driver presence
    to preserve the semantics of VFIO + PCI
  - pci_* specialization preserved as a wrapper

* clear_current_group
  - private function, just moved

To stop GCC complaining about "defined but not used", the private
function pci_vfio_get_group_no has been removed entirely.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
---
 lib/librte_eal/linuxapp/eal/eal_pci_init.h         |   1 -
 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c         | 297 +--------------------
 lib/librte_eal/linuxapp/eal/eal_pci_vfio_mp_sync.c |   2 +-
 lib/librte_eal/linuxapp/eal/eal_vfio.c             | 287 ++++++++++++++++++++
 lib/librte_eal/linuxapp/eal/eal_vfio.h             |  17 ++
 5 files changed, 309 insertions(+), 295 deletions(-)

diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_init.h b/lib/librte_eal/linuxapp/eal/eal_pci_init.h
index d34212b..d00bf7d 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci_init.h
+++ b/lib/librte_eal/linuxapp/eal/eal_pci_init.h
@@ -94,7 +94,6 @@ int pci_vfio_ioport_unmap(struct rte_pci_ioport *p);
 
 /* map VFIO resource prototype */
 int pci_vfio_map_resource(struct rte_pci_device *dev);
-int pci_vfio_get_group_fd(int iommu_group_fd);
 
 #endif
 
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
index 2792c23..46cd683 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
@@ -69,9 +69,6 @@ static struct rte_tailq_elem rte_vfio_tailq = {
 };
 EAL_REGISTER_TAILQ(rte_vfio_tailq)
 
-/* per-process VFIO config */
-static struct vfio_config vfio_cfg;
-
 int
 pci_vfio_read_config(const struct rte_intr_handle *intr_handle,
 		    void *buf, size_t len, off_t offs)
@@ -299,255 +296,6 @@ pci_vfio_setup_interrupts(struct rte_pci_device *dev, int vfio_dev_fd)
 	return -1;
 }
 
-/* open group fd or get an existing one */
-int
-pci_vfio_get_group_fd(int iommu_group_no)
-{
-	int i;
-	int vfio_group_fd;
-	char filename[PATH_MAX];
-
-	/* check if we already have the group descriptor open */
-	for (i = 0; i < vfio_cfg.vfio_group_idx; i++)
-		if (vfio_cfg.vfio_groups[i].group_no == iommu_group_no)
-			return vfio_cfg.vfio_groups[i].fd;
-
-	/* if primary, try to open the group */
-	if (internal_config.process_type == RTE_PROC_PRIMARY) {
-		/* try regular group format */
-		snprintf(filename, sizeof(filename),
-				 VFIO_GROUP_FMT, iommu_group_no);
-		vfio_group_fd = open(filename, O_RDWR);
-		if (vfio_group_fd < 0) {
-			/* if file not found, it's not an error */
-			if (errno != ENOENT) {
-				RTE_LOG(ERR, EAL, "Cannot open %s: %s\n", filename,
-						strerror(errno));
-				return -1;
-			}
-
-			/* special case: try no-IOMMU path as well */
-			snprintf(filename, sizeof(filename),
-					VFIO_NOIOMMU_GROUP_FMT, iommu_group_no);
-			vfio_group_fd = open(filename, O_RDWR);
-			if (vfio_group_fd < 0) {
-				if (errno != ENOENT) {
-					RTE_LOG(ERR, EAL, "Cannot open %s: %s\n", filename,
-							strerror(errno));
-					return -1;
-				}
-				return 0;
-			}
-			/* noiommu group found */
-		}
-
-		/* if the fd is valid, create a new group for it */
-		if (vfio_cfg.vfio_group_idx == VFIO_MAX_GROUPS) {
-			RTE_LOG(ERR, EAL, "Maximum number of VFIO groups reached!\n");
-			close(vfio_group_fd);
-			return -1;
-		}
-		vfio_cfg.vfio_groups[vfio_cfg.vfio_group_idx].group_no = iommu_group_no;
-		vfio_cfg.vfio_groups[vfio_cfg.vfio_group_idx].fd = vfio_group_fd;
-		return vfio_group_fd;
-	}
-	/* if we're in a secondary process, request group fd from the primary
-	 * process via our socket
-	 */
-	else {
-		int socket_fd, ret;
-
-		socket_fd = vfio_mp_sync_connect_to_primary();
-
-		if (socket_fd < 0) {
-			RTE_LOG(ERR, EAL, "  cannot connect to primary process!\n");
-			return -1;
-		}
-		if (vfio_mp_sync_send_request(socket_fd, SOCKET_REQ_GROUP) < 0) {
-			RTE_LOG(ERR, EAL, "  cannot request container fd!\n");
-			close(socket_fd);
-			return -1;
-		}
-		if (vfio_mp_sync_send_request(socket_fd, iommu_group_no) < 0) {
-			RTE_LOG(ERR, EAL, "  cannot send group number!\n");
-			close(socket_fd);
-			return -1;
-		}
-		ret = vfio_mp_sync_receive_request(socket_fd);
-		switch (ret) {
-		case SOCKET_NO_FD:
-			close(socket_fd);
-			return 0;
-		case SOCKET_OK:
-			vfio_group_fd = vfio_mp_sync_receive_fd(socket_fd);
-			/* if we got the fd, return it */
-			if (vfio_group_fd > 0) {
-				close(socket_fd);
-				return vfio_group_fd;
-			}
-			/* fall-through on error */
-		default:
-			RTE_LOG(ERR, EAL, "  cannot get container fd!\n");
-			close(socket_fd);
-			return -1;
-		}
-	}
-	return -1;
-}
-
-/* parse IOMMU group number for a PCI device
- * returns 1 on success, -1 for errors, 0 for non-existent group
- */
-static int
-pci_vfio_get_group_no(const char *pci_addr, int *iommu_group_no)
-{
-	return vfio_get_group_no(pci_get_sysfs_path(), pci_addr, iommu_group_no);
-}
-
-static void
-clear_current_group(void)
-{
-	vfio_cfg.vfio_groups[vfio_cfg.vfio_group_idx].group_no = 0;
-	vfio_cfg.vfio_groups[vfio_cfg.vfio_group_idx].fd = -1;
-}
-
-/**
- * Setup vfio_cfg for the device indentified by its address. It discovers
- * the configured I/O MMU groups or sets a new one for the device. If a new
- * groups is assigned, the DMA mapping is performed.
- * Returns 0 on success, a negative value on failure and a positive value in
- * case the given device cannot be managed this way.
- */
-static int pci_vfio_setup_device(const char *pci_addr, int *vfio_dev_fd,
-		struct vfio_device_info *device_info)
-{
-	struct vfio_group_status group_status = {
-			.argsz = sizeof(group_status)
-	};
-	int vfio_group_fd;
-	int iommu_group_no;
-	int ret;
-
-	/* get group number */
-	ret = pci_vfio_get_group_no(pci_addr, &iommu_group_no);
-	if (ret == 0) {
-		RTE_LOG(WARNING, EAL, "  %s not managed by VFIO driver, skipping\n",
-			pci_addr);
-		return 1;
-	}
-
-	/* if negative, something failed */
-	if (ret < 0)
-		return -1;
-
-	/* get the actual group fd */
-	vfio_group_fd = pci_vfio_get_group_fd(iommu_group_no);
-	if (vfio_group_fd < 0)
-		return -1;
-
-	/* store group fd */
-	vfio_cfg.vfio_groups[vfio_cfg.vfio_group_idx].group_no = iommu_group_no;
-	vfio_cfg.vfio_groups[vfio_cfg.vfio_group_idx].fd = vfio_group_fd;
-
-	/* if group_fd == 0, that means the device isn't managed by VFIO */
-	if (vfio_group_fd == 0) {
-		RTE_LOG(WARNING, EAL, "  %s not managed by VFIO driver, skipping\n",
-				pci_addr);
-		/* we store 0 as group fd to distinguish between existing but
-		 * unbound VFIO groups, and groups that don't exist at all.
-		 */
-		vfio_cfg.vfio_group_idx++;
-		return 1;
-	}
-
-	/*
-	 * at this point, we know that this group is viable (meaning, all devices
-	 * are either bound to VFIO or not bound to anything)
-	 */
-
-	/* check if the group is viable */
-	ret = ioctl(vfio_group_fd, VFIO_GROUP_GET_STATUS, &group_status);
-	if (ret) {
-		RTE_LOG(ERR, EAL, "  %s cannot get group status, "
-				"error %i (%s)\n", pci_addr, errno, strerror(errno));
-		close(vfio_group_fd);
-		clear_current_group();
-		return -1;
-	} else if (!(group_status.flags & VFIO_GROUP_FLAGS_VIABLE)) {
-		RTE_LOG(ERR, EAL, "  %s VFIO group is not viable!\n", pci_addr);
-		close(vfio_group_fd);
-		clear_current_group();
-		return -1;
-	}
-
-	/* check if group does not have a container yet */
-	if (!(group_status.flags & VFIO_GROUP_FLAGS_CONTAINER_SET)) {
-
-		/* add group to a container */
-		ret = ioctl(vfio_group_fd, VFIO_GROUP_SET_CONTAINER,
-				&vfio_cfg.vfio_container_fd);
-		if (ret) {
-			RTE_LOG(ERR, EAL, "  %s cannot add VFIO group to container, "
-					"error %i (%s)\n", pci_addr, errno, strerror(errno));
-			close(vfio_group_fd);
-			clear_current_group();
-			return -1;
-		}
-		/*
-		 * at this point we know that this group has been successfully
-		 * initialized, so we increment vfio_group_idx to indicate that we can
-		 * add new groups.
-		 */
-		vfio_cfg.vfio_group_idx++;
-	}
-
-	/*
-	 * pick an IOMMU type and set up DMA mappings for container
-	 *
-	 * needs to be done only once, only when at least one group is assigned to
-	 * a container and only in primary process
-	 */
-	if (internal_config.process_type == RTE_PROC_PRIMARY &&
-			vfio_cfg.vfio_container_has_dma == 0) {
-		/* select an IOMMU type which we will be using */
-		const struct vfio_iommu_type *t =
-				vfio_set_iommu_type(vfio_cfg.vfio_container_fd);
-		if (!t) {
-			RTE_LOG(ERR, EAL, "  %s failed to select IOMMU type\n", pci_addr);
-			return -1;
-		}
-		ret = t->dma_map_func(vfio_cfg.vfio_container_fd);
-		if (ret) {
-			RTE_LOG(ERR, EAL, "  %s DMA remapping failed, "
-					"error %i (%s)\n", pci_addr, errno, strerror(errno));
-			return -1;
-		}
-		vfio_cfg.vfio_container_has_dma = 1;
-	}
-
-	/* get a file descriptor for the device */
-	*vfio_dev_fd = ioctl(vfio_group_fd, VFIO_GROUP_GET_DEVICE_FD, pci_addr);
-	if (*vfio_dev_fd < 0) {
-		/* if we cannot get a device fd, this simply means that this
-		 * particular port is not bound to VFIO
-		 */
-		RTE_LOG(WARNING, EAL, "  %s not managed by VFIO driver, skipping\n",
-				pci_addr);
-		return 1;
-	}
-
-	/* test and setup the device */
-	ret = ioctl(*vfio_dev_fd, VFIO_DEVICE_GET_INFO, device_info);
-	if (ret) {
-		RTE_LOG(ERR, EAL, "  %s cannot get device info, "
-				"error %i (%s)\n", pci_addr, errno, strerror(errno));
-		close(*vfio_dev_fd);
-		return -1;
-	}
-
-	return 0;
-}
-
 /*
  * map the PCI resources of a PCI device in virtual memory (VFIO version).
  * primary and secondary processes follow almost exactly the same path
@@ -575,7 +323,8 @@ pci_vfio_map_resource(struct rte_pci_device *dev)
 	snprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,
 			loc->domain, loc->bus, loc->devid, loc->function);
 
-	if ((ret = pci_vfio_setup_device(pci_addr, &vfio_dev_fd, &device_info)))
+	if ((ret = vfio_setup_device(pci_get_sysfs_path(), pci_addr,
+					&vfio_dev_fd, &device_info)))
 		return ret;
 
 	/* get MSI-X BAR, if any (we have to know where it is because we can't
@@ -834,50 +583,12 @@ pci_vfio_ioport_unmap(struct rte_pci_ioport *p)
 int
 pci_vfio_enable(void)
 {
-	/* initialize group list */
-	int i;
-	int vfio_available;
-
-	for (i = 0; i < VFIO_MAX_GROUPS; i++) {
-		vfio_cfg.vfio_groups[i].fd = -1;
-		vfio_cfg.vfio_groups[i].group_no = -1;
-	}
-
-	/* inform the user that we are probing for VFIO */
-	RTE_LOG(INFO, EAL, "Probing VFIO support...\n");
-
-	/* check if vfio-pci module is loaded */
-	vfio_available = rte_eal_check_module("vfio_pci");
-
-	/* return error directly */
-	if (vfio_available == -1) {
-		RTE_LOG(INFO, EAL, "Could not get loaded module details!\n");
-		return -1;
-	}
-
-	/* return 0 if VFIO modules not loaded */
-	if (vfio_available == 0) {
-		RTE_LOG(DEBUG, EAL, "VFIO modules not loaded, "
-			"skipping VFIO support...\n");
-		return 0;
-	}
-
-	vfio_cfg.vfio_container_fd = vfio_get_container_fd();
-
-	/* check if we have VFIO driver enabled */
-	if (vfio_cfg.vfio_container_fd != -1) {
-		RTE_LOG(NOTICE, EAL, "VFIO support initialized\n");
-		vfio_cfg.vfio_enabled = 1;
-	} else {
-		RTE_LOG(NOTICE, EAL, "VFIO support could not be initialized\n");
-	}
-
-	return 0;
+	return vfio_enable("vfio_pci");
 }
 
 int
 pci_vfio_is_enabled(void)
 {
-	return vfio_cfg.vfio_enabled;
+	return vfio_is_enabled("vfio_pci");
 }
 #endif
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_vfio_mp_sync.c b/lib/librte_eal/linuxapp/eal/eal_pci_vfio_mp_sync.c
index a759f02..b3f4c51 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci_vfio_mp_sync.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci_vfio_mp_sync.c
@@ -310,7 +310,7 @@ pci_vfio_mp_sync_thread(void __rte_unused * arg)
 				continue;
 			}
 
-			fd = pci_vfio_get_group_fd(vfio_group_no);
+			fd = vfio_get_group_fd(vfio_group_no);
 
 			if (fd < 0)
 				vfio_mp_sync_send_request(conn_sock, SOCKET_ERR);
diff --git a/lib/librte_eal/linuxapp/eal/eal_vfio.c b/lib/librte_eal/linuxapp/eal/eal_vfio.c
index 2bf810e..d11f723 100644
--- a/lib/librte_eal/linuxapp/eal/eal_vfio.c
+++ b/lib/librte_eal/linuxapp/eal/eal_vfio.c
@@ -42,9 +42,296 @@
 
 #include "eal_filesystem.h"
 #include "eal_vfio.h"
+#include "eal_private.h"
 
 #ifdef VFIO_PRESENT
 
+/* per-process VFIO config */
+static struct vfio_config vfio_cfg;
+
+int
+vfio_get_group_fd(int iommu_group_no)
+{
+	int i;
+	int vfio_group_fd;
+	char filename[PATH_MAX];
+
+	/* check if we already have the group descriptor open */
+	for (i = 0; i < vfio_cfg.vfio_group_idx; i++)
+		if (vfio_cfg.vfio_groups[i].group_no == iommu_group_no)
+			return vfio_cfg.vfio_groups[i].fd;
+
+	/* if primary, try to open the group */
+	if (internal_config.process_type == RTE_PROC_PRIMARY) {
+		/* try regular group format */
+		snprintf(filename, sizeof(filename),
+				 VFIO_GROUP_FMT, iommu_group_no);
+		vfio_group_fd = open(filename, O_RDWR);
+		if (vfio_group_fd < 0) {
+			/* if file not found, it's not an error */
+			if (errno != ENOENT) {
+				RTE_LOG(ERR, EAL, "Cannot open %s: %s\n", filename,
+						strerror(errno));
+				return -1;
+			}
+
+			/* special case: try no-IOMMU path as well */
+			snprintf(filename, sizeof(filename),
+					VFIO_NOIOMMU_GROUP_FMT, iommu_group_no);
+			vfio_group_fd = open(filename, O_RDWR);
+			if (vfio_group_fd < 0) {
+				if (errno != ENOENT) {
+					RTE_LOG(ERR, EAL, "Cannot open %s: %s\n", filename,
+							strerror(errno));
+					return -1;
+				}
+				return 0;
+			}
+			/* noiommu group found */
+		}
+
+		/* if the fd is valid, create a new group for it */
+		if (vfio_cfg.vfio_group_idx == VFIO_MAX_GROUPS) {
+			RTE_LOG(ERR, EAL, "Maximum number of VFIO groups reached!\n");
+			close(vfio_group_fd);
+			return -1;
+		}
+		vfio_cfg.vfio_groups[vfio_cfg.vfio_group_idx].group_no = iommu_group_no;
+		vfio_cfg.vfio_groups[vfio_cfg.vfio_group_idx].fd = vfio_group_fd;
+		return vfio_group_fd;
+	}
+	/* if we're in a secondary process, request group fd from the primary
+	 * process via our socket
+	 */
+	else {
+		int socket_fd, ret;
+
+		socket_fd = vfio_mp_sync_connect_to_primary();
+
+		if (socket_fd < 0) {
+			RTE_LOG(ERR, EAL, "  cannot connect to primary process!\n");
+			return -1;
+		}
+		if (vfio_mp_sync_send_request(socket_fd, SOCKET_REQ_GROUP) < 0) {
+			RTE_LOG(ERR, EAL, "  cannot request container fd!\n");
+			close(socket_fd);
+			return -1;
+		}
+		if (vfio_mp_sync_send_request(socket_fd, iommu_group_no) < 0) {
+			RTE_LOG(ERR, EAL, "  cannot send group number!\n");
+			close(socket_fd);
+			return -1;
+		}
+		ret = vfio_mp_sync_receive_request(socket_fd);
+		switch (ret) {
+		case SOCKET_NO_FD:
+			close(socket_fd);
+			return 0;
+		case SOCKET_OK:
+			vfio_group_fd = vfio_mp_sync_receive_fd(socket_fd);
+			/* if we got the fd, return it */
+			if (vfio_group_fd > 0) {
+				close(socket_fd);
+				return vfio_group_fd;
+			}
+			/* fall-through on error */
+		default:
+			RTE_LOG(ERR, EAL, "  cannot get container fd!\n");
+			close(socket_fd);
+			return -1;
+		}
+	}
+	return -1;
+}
+
+static void
+clear_current_group(void)
+{
+	vfio_cfg.vfio_groups[vfio_cfg.vfio_group_idx].group_no = 0;
+	vfio_cfg.vfio_groups[vfio_cfg.vfio_group_idx].fd = -1;
+}
+
+int vfio_setup_device(const char *sysfs_base, const char *dev_addr,
+		int *vfio_dev_fd, struct vfio_device_info *device_info)
+{
+	struct vfio_group_status group_status = {
+			.argsz = sizeof(group_status)
+	};
+	int vfio_group_fd;
+	int iommu_group_no;
+	int ret;
+
+	/* get group number */
+	ret = vfio_get_group_no(sysfs_base, dev_addr, &iommu_group_no);
+	if (ret == 0) {
+		RTE_LOG(WARNING, EAL, "  %s not managed by VFIO driver, skipping\n",
+			dev_addr);
+		return 1;
+	}
+
+	/* if negative, something failed */
+	if (ret < 0)
+		return -1;
+
+	/* get the actual group fd */
+	vfio_group_fd = vfio_get_group_fd(iommu_group_no);
+	if (vfio_group_fd < 0)
+		return -1;
+
+	/* store group fd */
+	vfio_cfg.vfio_groups[vfio_cfg.vfio_group_idx].group_no = iommu_group_no;
+	vfio_cfg.vfio_groups[vfio_cfg.vfio_group_idx].fd = vfio_group_fd;
+
+	/* if group_fd == 0, that means the device isn't managed by VFIO */
+	if (vfio_group_fd == 0) {
+		RTE_LOG(WARNING, EAL, "  %s not managed by VFIO driver, skipping\n",
+				dev_addr);
+		/* we store 0 as group fd to distinguish between existing but
+		 * unbound VFIO groups, and groups that don't exist at all.
+		 */
+		vfio_cfg.vfio_group_idx++;
+		return 1;
+	}
+
+	/*
+	 * at this point, we know that this group is viable (meaning, all devices
+	 * are either bound to VFIO or not bound to anything)
+	 */
+
+	/* check if the group is viable */
+	ret = ioctl(vfio_group_fd, VFIO_GROUP_GET_STATUS, &group_status);
+	if (ret) {
+		RTE_LOG(ERR, EAL, "  %s cannot get group status, "
+				"error %i (%s)\n", dev_addr, errno, strerror(errno));
+		close(vfio_group_fd);
+		clear_current_group();
+		return -1;
+	} else if (!(group_status.flags & VFIO_GROUP_FLAGS_VIABLE)) {
+		RTE_LOG(ERR, EAL, "  %s VFIO group is not viable!\n", dev_addr);
+		close(vfio_group_fd);
+		clear_current_group();
+		return -1;
+	}
+
+	/* check if group does not have a container yet */
+	if (!(group_status.flags & VFIO_GROUP_FLAGS_CONTAINER_SET)) {
+
+		/* add group to a container */
+		ret = ioctl(vfio_group_fd, VFIO_GROUP_SET_CONTAINER,
+				&vfio_cfg.vfio_container_fd);
+		if (ret) {
+			RTE_LOG(ERR, EAL, "  %s cannot add VFIO group to container, "
+					"error %i (%s)\n", dev_addr, errno, strerror(errno));
+			close(vfio_group_fd);
+			clear_current_group();
+			return -1;
+		}
+		/*
+		 * at this point we know that this group has been successfully
+		 * initialized, so we increment vfio_group_idx to indicate that we can
+		 * add new groups.
+		 */
+		vfio_cfg.vfio_group_idx++;
+	}
+
+	/*
+	 * pick an IOMMU type and set up DMA mappings for container
+	 *
+	 * needs to be done only once, only when at least one group is assigned to
+	 * a container and only in primary process
+	 */
+	if (internal_config.process_type == RTE_PROC_PRIMARY &&
+			vfio_cfg.vfio_container_has_dma == 0) {
+		/* select an IOMMU type which we will be using */
+		const struct vfio_iommu_type *t =
+				vfio_set_iommu_type(vfio_cfg.vfio_container_fd);
+		if (!t) {
+			RTE_LOG(ERR, EAL, "  %s failed to select IOMMU type\n", dev_addr);
+			return -1;
+		}
+		ret = t->dma_map_func(vfio_cfg.vfio_container_fd);
+		if (ret) {
+			RTE_LOG(ERR, EAL, "  %s DMA remapping failed, "
+					"error %i (%s)\n", dev_addr, errno, strerror(errno));
+			return -1;
+		}
+		vfio_cfg.vfio_container_has_dma = 1;
+	}
+
+	/* get a file descriptor for the device */
+	*vfio_dev_fd = ioctl(vfio_group_fd, VFIO_GROUP_GET_DEVICE_FD, dev_addr);
+	if (*vfio_dev_fd < 0) {
+		/* if we cannot get a device fd, this simply means that this
+		* particular port is not bound to VFIO
+		*/
+		RTE_LOG(WARNING, EAL, "  %s not managed by VFIO driver, skipping\n",
+				dev_addr);
+		return 1;
+	}
+
+	/* test and setup the device */
+	ret = ioctl(*vfio_dev_fd, VFIO_DEVICE_GET_INFO, device_info);
+	if (ret) {
+		RTE_LOG(ERR, EAL, "  %s cannot get device info, "
+				"error %i (%s)\n", dev_addr, errno, strerror(errno));
+		close(*vfio_dev_fd);
+		return -1;
+	}
+
+	return 0;
+}
+
+int
+vfio_enable(const char *modname)
+{
+	/* initialize group list */
+	int i;
+	int vfio_available;
+
+	for (i = 0; i < VFIO_MAX_GROUPS; i++) {
+		vfio_cfg.vfio_groups[i].fd = -1;
+		vfio_cfg.vfio_groups[i].group_no = -1;
+	}
+
+	/* inform the user that we are probing for VFIO */
+	RTE_LOG(INFO, EAL, "Probing VFIO support...\n");
+
+	/* check if vfio-pci module is loaded */
+	vfio_available = rte_eal_check_module(modname);
+
+	/* return error directly */
+	if (vfio_available == -1) {
+		RTE_LOG(INFO, EAL, "Could not get loaded module details!\n");
+		return -1;
+	}
+
+	/* return 0 if VFIO modules not loaded */
+	if (vfio_available == 0) {
+		RTE_LOG(DEBUG, EAL, "VFIO modules not loaded, "
+			"skipping VFIO support...\n");
+		return 0;
+	}
+
+	vfio_cfg.vfio_container_fd = vfio_get_container_fd();
+
+	/* check if we have VFIO driver enabled */
+	if (vfio_cfg.vfio_container_fd != -1) {
+		RTE_LOG(NOTICE, EAL, "VFIO support initialized\n");
+		vfio_cfg.vfio_enabled = 1;
+	} else {
+		RTE_LOG(NOTICE, EAL, "VFIO support could not be initialized\n");
+	}
+
+	return 0;
+}
+
+int
+vfio_is_enabled(const char *modname)
+{
+	const int mod_available = rte_eal_check_module(modname);
+	return vfio_cfg.vfio_enabled && mod_available;
+}
+
 const struct vfio_iommu_type *
 vfio_set_iommu_type(int vfio_container_fd) {
 	unsigned idx;
diff --git a/lib/librte_eal/linuxapp/eal/eal_vfio.h b/lib/librte_eal/linuxapp/eal/eal_vfio.h
index 619cd6b..d4532a5 100644
--- a/lib/librte_eal/linuxapp/eal/eal_vfio.h
+++ b/lib/librte_eal/linuxapp/eal/eal_vfio.h
@@ -126,6 +126,23 @@ int
 vfio_get_group_no(const char *sysfs_base,
 		const char *dev_addr, int *iommu_group_no);
 
+/* open group fd or get an existing one */
+int
+vfio_get_group_fd(int iommu_group_no);
+
+/**
+ * Setup vfio_cfg for the device indentified by its address. It discovers
+ * the configured I/O MMU groups or sets a new one for the device. If a new
+ * groups is assigned, the DMA mapping is performed.
+ * Returns 0 on success, a negative value on failure and a positive value in
+ * case the given device cannot be managed this way.
+ */
+int vfio_setup_device(const char *sysfs_base, const char *dev_addr,
+		int *vfio_dev_fd, struct vfio_device_info *device_info);
+
+int vfio_enable(const char *modname);
+int vfio_is_enabled(const char *modname);
+
 #define SOCKET_REQ_CONTAINER 0x100
 #define SOCKET_REQ_GROUP 0x200
 #define SOCKET_OK 0x0
-- 
2.8.0

  parent reply	other threads:[~2016-07-04 15:16 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-07-04 15:16 [PATCH v3 00/16] Make VFIO support less dependent on PCI Jan Viktorin
2016-07-04 15:16 ` [PATCH v3 01/16] vfio: fix include of eal_private.h to be local Jan Viktorin
2016-07-04 15:16 ` [PATCH v3 02/16] vfio: move VFIO-specific stuff to eal_vfio.h Jan Viktorin
2016-07-04 15:16 ` [PATCH v3 03/16] vfio: move common vfio constants " Jan Viktorin
2016-07-04 15:16 ` [PATCH v3 04/16] vfio: move vfio_iommu_type and dma_map functions to eal_vfio Jan Viktorin
2016-07-04 15:16 ` [PATCH v3 05/16] vfio: generalize pci_vfio_set_iommu_type Jan Viktorin
2016-07-04 15:16 ` [PATCH v3 06/16] vfio: generalize pci_vfio_has_supported_extensions Jan Viktorin
2016-07-10 17:36   ` Thomas Monjalon
2016-07-04 15:16 ` [PATCH v3 07/16] vfio: move vfio-specific SOCKET_* constants Jan Viktorin
2016-07-04 15:16 ` [PATCH v3 08/16] vfio: generalize pci_vfio_get_container_fd Jan Viktorin
2016-07-04 15:16 ` [PATCH v3 09/16] vfio: generalize pci_vfio_get_group_no Jan Viktorin
2016-07-04 15:16 ` [PATCH v3 10/16] vfio: extract setup logic out of pci_vfio_map_resource Jan Viktorin
2016-07-04 15:16 ` Jan Viktorin [this message]
2016-07-04 15:16 ` [PATCH v3 12/16] vfio: fix typo in doc for vfio_setup_device Jan Viktorin
2016-07-04 15:16 ` [PATCH v3 13/16] vfio: make vfio_*_dma_map and iommu_types private Jan Viktorin
2016-07-04 15:16 ` [PATCH v3 14/16] vfio: rename and generalize eal_pci_vfio_mp_sync Jan Viktorin
2016-07-04 15:16 ` [PATCH v3 15/16] vfio: initialize vfio out of the PCI subsystem Jan Viktorin
2016-07-04 15:16 ` [PATCH v3 16/16] vfio: change VFIO init to be extendable Jan Viktorin
2016-07-04 15:26 ` [PATCH v3 00/16] Make VFIO support less dependent on PCI Burakov, Anatoly
2016-07-10 18:17 ` Thomas Monjalon

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1467645411-15494-12-git-send-email-viktorin@rehivetech.com \
    --to=viktorin@rehivetech.com \
    --cc=anatoly.burakov@intel.com \
    --cc=david.marchand@6wind.com \
    --cc=dev@dpdk.org \
    --cc=keith.wiles@intel.com \
    --cc=shreyansh.jain@nxp.com \
    --cc=sshukla@mvista.com \
    --cc=stephen@networkplumber.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.