[PATCH v19 04/26] bus/pci: move VFIO concerns in Linux implementation

David Marchand david.marchand at redhat.com
Wed Oct 7 09:31:42 CEST 2026


Make the common PCI code independent of the VFIO API.
Move VFIO dma map/unmap operation in Linux only code: adopt the
same approach than IOMMU VA support and expose a OS specific handler
which calls a common implementation for FreeBSD and Windows.

Signed-off-by: David Marchand <david.marchand at redhat.com>
---
 drivers/bus/pci/bsd/pci.c     | 12 ++++++++++
 drivers/bus/pci/linux/pci.c   | 35 ++++++++++++++++++++++++++++++
 drivers/bus/pci/pci_common.c  | 26 +++++-----------------
 drivers/bus/pci/private.h     | 41 +++++++++++++++++++++++++++++++++++
 drivers/bus/pci/windows/pci.c | 12 ++++++++++
 5 files changed, 105 insertions(+), 21 deletions(-)

diff --git a/drivers/bus/pci/bsd/pci.c b/drivers/bus/pci/bsd/pci.c
index c6df31d486..2af99d3678 100644
--- a/drivers/bus/pci/bsd/pci.c
+++ b/drivers/bus/pci/bsd/pci.c
@@ -397,6 +397,18 @@ rte_pci_scan(void)
 	return -1;
 }
 
+int
+pci_device_dma_map(struct rte_device *dev, void *addr, uint64_t iova, size_t len)
+{
+	return pci_dma_map(dev, addr, iova, len);
+}
+
+int
+pci_device_dma_unmap(struct rte_device *dev, void *addr, uint64_t iova, size_t len)
+{
+	return pci_dma_unmap(dev, addr, iova, len);
+}
+
 bool
 pci_device_iommu_support_va(__rte_unused const struct rte_pci_device *dev)
 {
diff --git a/drivers/bus/pci/linux/pci.c b/drivers/bus/pci/linux/pci.c
index 9aae0a5d14..bcb5b3278d 100644
--- a/drivers/bus/pci/linux/pci.c
+++ b/drivers/bus/pci/linux/pci.c
@@ -5,6 +5,7 @@
 #include <string.h>
 #include <dirent.h>
 
+#include <rte_errno.h>
 #include <rte_log.h>
 #include <rte_pci.h>
 #include <rte_bus_pci.h>
@@ -474,6 +475,40 @@ rte_pci_scan(void)
 	return -1;
 }
 
+int
+pci_device_dma_map(struct rte_device *dev, void *addr, uint64_t iova, size_t len)
+{
+	int ret = pci_dma_map(dev, addr, iova, len);
+
+	if (ret == -1 && rte_errno == ENOTSUP) {
+		struct rte_pci_device *pdev = RTE_BUS_DEVICE(dev, *pdev);
+
+		/* In case driver doesn't provide any specific mapping try fallback to VFIO. */
+		if (pdev->kdrv == RTE_PCI_KDRV_VFIO)
+			ret = rte_vfio_container_dma_map(RTE_VFIO_DEFAULT_CONTAINER_FD,
+				(uintptr_t)addr, iova, len);
+	}
+
+	return ret;
+}
+
+int
+pci_device_dma_unmap(struct rte_device *dev, void *addr, uint64_t iova, size_t len)
+{
+	int ret = pci_dma_unmap(dev, addr, iova, len);
+
+	if (ret == -1 && rte_errno == ENOTSUP) {
+		struct rte_pci_device *pdev = RTE_BUS_DEVICE(dev, *pdev);
+
+		/* In case driver doesn't provide any specific mapping try fallback to VFIO. */
+		if (pdev->kdrv == RTE_PCI_KDRV_VFIO)
+			return rte_vfio_container_dma_unmap(RTE_VFIO_DEFAULT_CONTAINER_FD,
+				(uintptr_t)addr, iova, len);
+	}
+
+	return ret;
+}
+
 #if defined(RTE_ARCH_X86)
 bool
 pci_device_iommu_support_va(const struct rte_pci_device *dev)
diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
index dc8db80d3b..3770b4ad75 100644
--- a/drivers/bus/pci/pci_common.c
+++ b/drivers/bus/pci/pci_common.c
@@ -25,7 +25,6 @@
 #include <rte_string_fns.h>
 #include <rte_common.h>
 #include <rte_devargs.h>
-#include <rte_vfio.h>
 #include <rte_tailq.h>
 
 #include "private.h"
@@ -474,7 +473,7 @@ pci_sigbus_handler(const void *failure_addr)
 	return ret;
 }
 
-static int
+int
 pci_dma_map(struct rte_device *dev, void *addr, uint64_t iova, size_t len)
 {
 	struct rte_pci_device *pdev = RTE_BUS_DEVICE(dev, *pdev);
@@ -482,19 +481,12 @@ pci_dma_map(struct rte_device *dev, void *addr, uint64_t iova, size_t len)
 
 	if (pdrv->dma_map != NULL)
 		return pdrv->dma_map(pdev, addr, iova, len);
-	/**
-	 *  In case driver don't provides any specific mapping
-	 *  try fallback to VFIO.
-	 */
-	if (pdev->kdrv == RTE_PCI_KDRV_VFIO)
-		return rte_vfio_container_dma_map
-				(RTE_VFIO_DEFAULT_CONTAINER_FD, (uintptr_t)addr,
-				 iova, len);
+
 	rte_errno = ENOTSUP;
 	return -1;
 }
 
-static int
+int
 pci_dma_unmap(struct rte_device *dev, void *addr, uint64_t iova, size_t len)
 {
 	struct rte_pci_device *pdev = RTE_BUS_DEVICE(dev, *pdev);
@@ -502,14 +494,6 @@ pci_dma_unmap(struct rte_device *dev, void *addr, uint64_t iova, size_t len)
 
 	if (pdrv->dma_unmap != NULL)
 		return pdrv->dma_unmap(pdev, addr, iova, len);
-	/**
-	 *  In case driver don't provides any specific mapping
-	 *  try fallback to VFIO.
-	 */
-	if (pdev->kdrv == RTE_PCI_KDRV_VFIO)
-		return rte_vfio_container_dma_unmap
-				(RTE_VFIO_DEFAULT_CONTAINER_FD, (uintptr_t)addr,
-				 iova, len);
 	rte_errno = ENOTSUP;
 	return -1;
 }
@@ -727,8 +711,8 @@ struct rte_bus rte_pci_bus = {
 	.parse = pci_parse,
 	.dev_compare = pci_dev_compare,
 	.devargs_parse = rte_pci_devargs_parse,
-	.dma_map = pci_dma_map,
-	.dma_unmap = pci_dma_unmap,
+	.dma_map = pci_device_dma_map,
+	.dma_unmap = pci_device_dma_unmap,
 	.get_iommu_class = rte_pci_get_iommu_class,
 	.dev_iterate = rte_pci_dev_iterate,
 	.hot_unplug_handler = pci_hot_unplug_handler,
diff --git a/drivers/bus/pci/private.h b/drivers/bus/pci/private.h
index 8103c32881..f266a1b04d 100644
--- a/drivers/bus/pci/private.h
+++ b/drivers/bus/pci/private.h
@@ -210,6 +210,47 @@ pci_uio_remap_resource(struct rte_pci_device *dev);
 int pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
 		struct mapped_pci_resource *uio_res, int map_idx);
 
+/**
+ * Call driver DMA map callback if any.
+ *
+ * @param dev
+ *   Device pointer.
+ * @param addr
+ *   Virtual address to map.
+ * @param iova
+ *   IOVA address to map.
+ * @param len
+ *   Length of the memory segment being mapped.
+ * @return
+ *   0 on success, -1 on error
+ */
+int pci_dma_map(struct rte_device *dev, void *addr, uint64_t iova, size_t len);
+
+/**
+ * Call driver DMA unmap callback if any.
+ *
+ * @param dev
+ *   Device pointer.
+ * @param addr
+ *   Virtual address to unmap.
+ * @param iova
+ *   IOVA address to unmap.
+ * @param len
+ *   Length of the memory segment being unmapped.
+ * @return
+ *   0 on success, -1 on error
+ */
+int pci_dma_unmap(struct rte_device *dev, void *addr, uint64_t iova, size_t len);
+
+/**
+ * OS specific callbacks for dma_map/dma_unmap
+ */
+int
+pci_device_dma_map(struct rte_device *dev, void *addr, uint64_t iova, size_t len);
+
+int
+pci_device_dma_unmap(struct rte_device *dev, void *addr, uint64_t iova, size_t len);
+
 /**
  * OS specific callbacks for rte_pci_get_iommu_class
  *
diff --git a/drivers/bus/pci/windows/pci.c b/drivers/bus/pci/windows/pci.c
index 7b51301d1e..383c6bdc2f 100644
--- a/drivers/bus/pci/windows/pci.c
+++ b/drivers/bus/pci/windows/pci.c
@@ -120,6 +120,18 @@ rte_pci_mmio_write(const struct rte_pci_device *dev, int bar,
 	return len;
 }
 
+int
+pci_device_dma_map(struct rte_device *dev, void *addr, uint64_t iova, size_t len)
+{
+	return pci_dma_map(dev, addr, iova, len);
+}
+
+int
+pci_device_dma_unmap(struct rte_device *dev, void *addr, uint64_t iova, size_t len)
+{
+	return pci_dma_unmap(dev, addr, iova, len);
+}
+
 enum rte_iova_mode
 pci_device_iova_mode(const struct rte_pci_driver *pdrv __rte_unused,
 		const struct rte_pci_device *pdev __rte_unused)
-- 
2.54.0



More information about the dev mailing list