[dpdk-dev] [PATCH 02/10] linuxapp/eal_pci: get iommu class

Santosh Shukla santosh.shukla at caviumnetworks.com
Thu Jun 8 13:05:05 CEST 2017


Get iommu class of PCI device on the bus and returns preferred iova
mapping mode for that bus.

IOVA mapping scheme for linuxapp case:
- uio/uio_generic/vfio_noiommu --> default i.e.. (RTE_IOVA_PA)
- vfio --> RTE_IOVA_VA.
- In case of no device attached to any driver,
  return RTE_IOVA_DC.

Signed-off-by: Santosh Shukla <santosh.shukla at caviumnetworks.com>
Signed-off-by: Jerin Jacob <jerin.jacob at caviumnetworks.com>
---
 lib/librte_eal/linuxapp/eal/eal_pci.c           | 38 +++++++++++++++++++++++++
 lib/librte_eal/linuxapp/eal/eal_vfio.c          | 23 +++++++++++++++
 lib/librte_eal/linuxapp/eal/eal_vfio.h          |  4 +++
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |  7 +++++
 4 files changed, 72 insertions(+)

diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
index 595622b21..2772e883e 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
@@ -45,6 +45,7 @@
 #include "eal_filesystem.h"
 #include "eal_private.h"
 #include "eal_pci_init.h"
+#include "eal_vfio.h"
 
 /**
  * @file
@@ -488,6 +489,43 @@ rte_pci_scan(void)
 	return -1;
 }
 
+/*
+ * Get iommu class of PCI devices on the bus.
+ * Check that those devices are attached to iommu driver.
+ * If attached then return iova_va or iova_pa mode, else
+ * return with dont_care(_DC).
+ */
+enum rte_iova_mode
+rte_pci_get_iommu_class(void)
+{
+	struct rte_pci_device *dev = NULL;
+	int ret = RTE_IOVA_DC;
+
+	TAILQ_FOREACH(dev, &rte_pci_bus.device_list, next) {
+
+		if (dev->kdrv == RTE_KDRV_UNKNOWN ||
+		    dev->kdrv == RTE_KDRV_NONE)
+			continue;
+
+		if (dev->kdrv != RTE_KDRV_VFIO) {
+			ret = RTE_IOVA_PA;
+			return ret;
+		}
+
+		ret = RTE_IOVA_VA;
+	}
+
+	/* In case of iova_va, check for vfio_noiommu mode */
+	if (ret == RTE_IOVA_VA) {
+#ifdef VFIO_PRESENT
+		if (vfio_noiommu_is_enabled() == 1)
+#endif
+			ret = RTE_IOVA_PA;
+	}
+
+	return ret;
+}
+
 /* Read PCI config space. */
 int rte_pci_read_config(const struct rte_pci_device *device,
 		void *buf, size_t len, off_t offset)
diff --git a/lib/librte_eal/linuxapp/eal/eal_vfio.c b/lib/librte_eal/linuxapp/eal/eal_vfio.c
index 946df7e31..04914406f 100644
--- a/lib/librte_eal/linuxapp/eal/eal_vfio.c
+++ b/lib/librte_eal/linuxapp/eal/eal_vfio.c
@@ -816,4 +816,27 @@ vfio_noiommu_dma_map(int __rte_unused vfio_container_fd)
 	return 0;
 }
 
+int
+vfio_noiommu_is_enabled(void)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)
+	return -1;
+#else
+	int fd, ret, cnt __rte_unused;
+	char c;
+
+	ret = -1;
+	fd = open(VFIO_NOIOMMU_MODE, O_RDONLY);
+	if (fd < 0)
+		return -1;
+
+	cnt = read(fd, &c, 1);
+	if (c == 'Y')
+		ret = 1;
+
+	close(fd);
+	return ret;
+#endif
+}
+
 #endif
diff --git a/lib/librte_eal/linuxapp/eal/eal_vfio.h b/lib/librte_eal/linuxapp/eal/eal_vfio.h
index 5ff63e5d7..26ea8e119 100644
--- a/lib/librte_eal/linuxapp/eal/eal_vfio.h
+++ b/lib/librte_eal/linuxapp/eal/eal_vfio.h
@@ -150,6 +150,8 @@ struct vfio_config {
 #define VFIO_NOIOMMU_GROUP_FMT "/dev/vfio/noiommu-%u"
 #define VFIO_GET_REGION_ADDR(x) ((uint64_t) x << 40ULL)
 #define VFIO_GET_REGION_IDX(x) (x >> 40)
+#define VFIO_NOIOMMU_MODE      \
+	"/sys/module/vfio/parameters/enable_unsafe_noiommu_mode"
 
 /* DMA mapping function prototype.
  * Takes VFIO container fd as a parameter.
@@ -210,6 +212,8 @@ int pci_vfio_is_enabled(void);
 
 int vfio_mp_sync_setup(void);
 
+int vfio_noiommu_is_enabled(void);
+
 #define SOCKET_REQ_CONTAINER 0x100
 #define SOCKET_REQ_GROUP 0x200
 #define SOCKET_CLR_GROUP 0x300
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index 670bab3a5..2cea7c272 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -198,3 +198,10 @@ DPDK_17.05 {
 	vfio_get_group_no;
 
 } DPDK_17.02;
+
+DPDK_17.08 {
+	global:
+
+	rte_pci_get_iommu_class;
+
+} DPDK_17.05;
-- 
2.11.0



More information about the dev mailing list