[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