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 <[email protected]> --- 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 bcf0a409da..5e4c055b07 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> @@ -478,6 +479,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

