[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