X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fbus%2Fpci%2Flinux%2Fpci.c;h=740a2cdad4ecc3f0474912e35a59adbc9f839baa;hb=7d087a0a8b8e53278302601cd4b22e50ef0d5ee2;hp=b931cf9d1078900f5a8cb13cd018ba926e86da7a;hpb=0cb86518db57d35e0abc14d6703fad561a0310e2;p=dpdk.git diff --git a/drivers/bus/pci/linux/pci.c b/drivers/bus/pci/linux/pci.c index b931cf9d10..740a2cdad4 100644 --- a/drivers/bus/pci/linux/pci.c +++ b/drivers/bus/pci/linux/pci.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include @@ -329,9 +328,6 @@ pci_scan_one(const char *dirname, const struct rte_pci_addr *addr) dev->kdrv = RTE_KDRV_IGB_UIO; else if (!strcmp(driver, "uio_pci_generic")) dev->kdrv = RTE_KDRV_UIO_GENERIC; - else if (!strcmp(driver, "mlx4_core") || - !strcmp(driver, "mlx5_core")) - dev->kdrv = RTE_KDRV_NIC_MLX; else dev->kdrv = RTE_KDRV_UNKNOWN; } else @@ -500,95 +496,13 @@ error: return -1; } -/* - * Is pci device bound to any kdrv - */ -static inline int -pci_one_device_is_bound(void) -{ - struct rte_pci_device *dev = NULL; - int ret = 0; - - FOREACH_DEVICE_ON_PCIBUS(dev) { - if (dev->kdrv == RTE_KDRV_UNKNOWN || - dev->kdrv == RTE_KDRV_NONE) { - continue; - } else { - ret = 1; - break; - } - } - return ret; -} - -/* - * Any one of the device bound to uio - */ -static inline int -pci_one_device_bound_uio(void) -{ - struct rte_pci_device *dev = NULL; - struct rte_devargs *devargs; - int need_check; - - FOREACH_DEVICE_ON_PCIBUS(dev) { - devargs = dev->device.devargs; - - need_check = 0; - switch (rte_pci_bus.bus.conf.scan_mode) { - case RTE_BUS_SCAN_WHITELIST: - if (devargs && devargs->policy == RTE_DEV_WHITELISTED) - need_check = 1; - break; - case RTE_BUS_SCAN_UNDEFINED: - case RTE_BUS_SCAN_BLACKLIST: - if (devargs == NULL || - devargs->policy != RTE_DEV_BLACKLISTED) - need_check = 1; - break; - } - - if (!need_check) - continue; - - if (dev->kdrv == RTE_KDRV_IGB_UIO || - dev->kdrv == RTE_KDRV_UIO_GENERIC) { - return 1; - } - } - return 0; -} - -/* - * Any one of the device has iova as va - */ -static inline int -pci_one_device_has_iova_va(void) -{ - struct rte_pci_device *dev = NULL; - struct rte_pci_driver *drv = NULL; - - FOREACH_DRIVER_ON_PCIBUS(drv) { - if (drv && drv->drv_flags & RTE_PCI_DRV_IOVA_AS_VA) { - FOREACH_DEVICE_ON_PCIBUS(dev) { - if ((dev->kdrv == RTE_KDRV_VFIO || - dev->kdrv == RTE_KDRV_NIC_MLX) && - rte_pci_match(drv, dev)) - return 1; - } - } - } - return 0; -} - #if defined(RTE_ARCH_X86) -static bool -pci_one_device_iommu_support_va(struct rte_pci_device *dev) +bool +pci_device_iommu_support_va(const struct rte_pci_device *dev) { #define VTD_CAP_MGAW_SHIFT 16 #define VTD_CAP_MGAW_MASK (0x3fULL << VTD_CAP_MGAW_SHIFT) -#define X86_VA_WIDTH 47 /* From Documentation/x86/x86_64/mm.txt */ - struct rte_pci_addr *addr = &dev->addr; + const struct rte_pci_addr *addr = &dev->addr; char filename[PATH_MAX]; FILE *fp; uint64_t mgaw, vtd_cap_reg = 0; @@ -597,18 +511,19 @@ pci_one_device_iommu_support_va(struct rte_pci_device *dev) "%s/" PCI_PRI_FMT "/iommu/intel-iommu/cap", rte_pci_get_sysfs_path(), addr->domain, addr->bus, addr->devid, addr->function); - if (access(filename, F_OK) == -1) { - /* We don't have an Intel IOMMU, assume VA supported*/ - return true; - } - /* We have an intel IOMMU */ fp = fopen(filename, "r"); if (fp == NULL) { - RTE_LOG(ERR, EAL, "%s(): can't open %s\n", __func__, filename); + /* We don't have an Intel IOMMU, assume VA supported */ + if (errno == ENOENT) + return true; + + RTE_LOG(ERR, EAL, "%s(): can't open %s: %s\n", + __func__, filename, strerror(errno)); return false; } + /* We have an Intel IOMMU */ if (fscanf(fp, "%" PRIx64, &vtd_cap_reg) != 1) { RTE_LOG(ERR, EAL, "%s(): can't read %s\n", __func__, filename); fclose(fp); @@ -631,81 +546,55 @@ pci_one_device_iommu_support_va(struct rte_pci_device *dev) return true; } #elif defined(RTE_ARCH_PPC_64) -static bool -pci_one_device_iommu_support_va(__rte_unused struct rte_pci_device *dev) +bool +pci_device_iommu_support_va(__rte_unused const struct rte_pci_device *dev) { return false; } #else -static bool -pci_one_device_iommu_support_va(__rte_unused struct rte_pci_device *dev) +bool +pci_device_iommu_support_va(__rte_unused const struct rte_pci_device *dev) { return true; } #endif -/* - * All devices IOMMUs support VA as IOVA - */ -static bool -pci_devices_iommu_support_va(void) -{ - struct rte_pci_device *dev = NULL; - struct rte_pci_driver *drv = NULL; - - FOREACH_DRIVER_ON_PCIBUS(drv) { - FOREACH_DEVICE_ON_PCIBUS(dev) { - 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. - */ - return pci_one_device_iommu_support_va(dev); - } - } - return true; -} - -/* - * Get iommu class of PCI devices on the bus. - */ enum rte_iova_mode -rte_pci_get_iommu_class(void) +pci_device_iova_mode(const struct rte_pci_driver *pdrv, + const struct rte_pci_device *pdev) { - bool is_bound; - bool is_vfio_noiommu_enabled = true; - bool has_iova_va; - bool is_bound_uio; - bool iommu_no_va; - - is_bound = pci_one_device_is_bound(); - if (!is_bound) - return RTE_IOVA_DC; - - has_iova_va = pci_one_device_has_iova_va(); - is_bound_uio = pci_one_device_bound_uio(); - iommu_no_va = !pci_devices_iommu_support_va(); + enum rte_iova_mode iova_mode = RTE_IOVA_DC; + + switch (pdev->kdrv) { + case RTE_KDRV_VFIO: { #ifdef VFIO_PRESENT - is_vfio_noiommu_enabled = rte_vfio_noiommu_is_enabled() == true ? - true : false; + static int is_vfio_noiommu_enabled = -1; + + if (is_vfio_noiommu_enabled == -1) { + if (rte_vfio_noiommu_is_enabled() == 1) + is_vfio_noiommu_enabled = 1; + else + is_vfio_noiommu_enabled = 0; + } + if (is_vfio_noiommu_enabled != 0) + iova_mode = RTE_IOVA_PA; + else if ((pdrv->drv_flags & RTE_PCI_DRV_NEED_IOVA_AS_VA) != 0) + iova_mode = RTE_IOVA_VA; #endif + break; + } - if (has_iova_va && !is_bound_uio && !is_vfio_noiommu_enabled && - !iommu_no_va) - return RTE_IOVA_VA; + case RTE_KDRV_IGB_UIO: + case RTE_KDRV_UIO_GENERIC: + iova_mode = RTE_IOVA_PA; + break; - 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"); + default: + if ((pdrv->drv_flags & RTE_PCI_DRV_NEED_IOVA_AS_VA) != 0) + iova_mode = RTE_IOVA_VA; + break; } - - return RTE_IOVA_PA; + return iova_mode; } /* Read PCI config space. */ @@ -768,6 +657,12 @@ pci_ioport_map(struct rte_pci_device *dev, int bar __rte_unused, int found = 0; size_t linesz; + if (rte_eal_iopl_init() != 0) { + RTE_LOG(ERR, EAL, "%s(): insufficient ioport permissions for PCI device %s\n", + __func__, dev->name); + return -1; + } + snprintf(pci_id, sizeof(pci_id), PCI_PRI_FMT, dev->addr.domain, dev->addr.bus, dev->addr.devid, dev->addr.function);