In the case where no drivers are registered with the system, rte_pci_get_iommu_class should return RTE_IOVA_DC.
Signed-off-by: Ben Walker <benjamin.wal...@intel.com> Change-Id: Ia5b0cae100cfcfe46a9e4996328f9746ce33cfd3 --- drivers/bus/pci/linux/pci.c | 79 ++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 41 deletions(-) diff --git a/drivers/bus/pci/linux/pci.c b/drivers/bus/pci/linux/pci.c index 09af66571..abc21061f 100644 --- a/drivers/bus/pci/linux/pci.c +++ b/drivers/bus/pci/linux/pci.c @@ -589,49 +589,68 @@ pci_ignore_device(struct rte_pci_device *dev) enum rte_iova_mode rte_pci_get_iommu_class(void) { - bool is_bound = false; - bool is_vfio_noiommu_enabled = true; - bool has_iova_va = false; - bool is_bound_uio = false; - bool iommu_no_va = false; - struct rte_pci_device *dev = NULL; - struct rte_pci_driver *drv = NULL; + struct rte_pci_device *dev; + struct rte_pci_driver *drv; + struct rte_pci_addr *addr; + enum rte_iova_mode iova_mode; + + iova_mode = RTE_IOVA_DC; FOREACH_DEVICE_ON_PCIBUS(dev) { if (pci_ignore_device(dev)) continue; + addr = &dev->addr; + switch (dev->kdrv) { case RTE_KDRV_UNKNOWN: case RTE_KDRV_NONE: break; case RTE_KDRV_VFIO: - is_bound = true; FOREACH_DRIVER_ON_PCIBUS(drv) { if (!rte_pci_match(drv, dev)) continue; - /* - * just one PCI device needs to be checked out because - * the IOMMU hardware is the same for all of them. - */ - iommu_no_va = !pci_one_device_iommu_support_va(dev); + if ((drv->drv_flags & RTE_PCI_DRV_IOVA_AS_VA) == 0) + continue; - if (drv->drv_flags & RTE_PCI_DRV_IOVA_AS_VA) { - has_iova_va = true; - break; + if (!pci_one_device_iommu_support_va(dev)) { + RTE_LOG(WARNING, EAL, "Device " PCI_PRI_FMT " wanted IOVA as VA, but ", + addr->domain, addr->bus, addr->devid, addr->function); + RTE_LOG(WARNING, EAL, "IOMMU does not support it.\n"); + iova_mode = RTE_IOVA_PA; + } +#ifdef VFIO_PRESENT + else if (rte_vfio_noiommu_is_enabled()) { + RTE_LOG(WARNING, EAL, "Device " PCI_PRI_FMT " wanted IOVA as VA, but ", + addr->domain, addr->bus, addr->devid, addr->function); + RTE_LOG(WARNING, EAL, "vfio-noiommu is enabled.\n"); + iova_mode = RTE_IOVA_PA; +#endif + } else if (iova_mode == RTE_IOVA_PA) { + RTE_LOG(WARNING, EAL, "Device " PCI_PRI_FMT " wanted IOVA as VA, but ", + addr->domain, addr->bus, addr->devid, addr->function); + RTE_LOG(WARNING, EAL, "other devices require PA.\n"); + } else { + iova_mode = RTE_IOVA_VA; } } break; case RTE_KDRV_IGB_UIO: case RTE_KDRV_UIO_GENERIC: case RTE_KDRV_NIC_UIO: - is_bound = true; FOREACH_DRIVER_ON_PCIBUS(drv) { if (!rte_pci_match(drv, dev)) continue; - is_bound_uio = true; + if (iova_mode == RTE_IOVA_VA) { + RTE_LOG(WARNING, EAL, "Some devices wanted IOVA as VA, but "); + RTE_LOG(WARNING, EAL, "device " PCI_PRI_FMT " requires PA.\n", + addr->domain, addr->bus, addr->devid, addr->function); + + } + + iova_mode = RTE_IOVA_PA; break; } break; @@ -639,29 +658,7 @@ rte_pci_get_iommu_class(void) } } - if (!is_bound) - return RTE_IOVA_DC; - -#ifdef VFIO_PRESENT - is_vfio_noiommu_enabled = rte_vfio_noiommu_is_enabled() == true ? - true : false; -#endif - - if (has_iova_va && !is_bound_uio && !is_vfio_noiommu_enabled && - !iommu_no_va) - return RTE_IOVA_VA; - - if (has_iova_va) { - RTE_LOG(WARNING, EAL, "Some devices want iova as va but pa will be used because.. "); - if (is_vfio_noiommu_enabled) - RTE_LOG(WARNING, EAL, "vfio-noiommu mode configured\n"); - if (is_bound_uio) - RTE_LOG(WARNING, EAL, "few device bound to UIO\n"); - if (iommu_no_va) - RTE_LOG(WARNING, EAL, "IOMMU does not support IOVA as VA\n"); - } - - return RTE_IOVA_PA; + return iova_mode; } /* Read PCI config space. */ -- 2.20.1