X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fbus%2Fpci%2Flinux%2Fpci_vfio.c;h=e3f7b6abeb64ab7ccf3229f9c2a158fd97572bd0;hb=81db321daeccec0c78bbe8bf4492f18f084ba30f;hp=64cd84a6897fde6132672c8130ad2832888c6e86;hpb=d25ab4b7f128610cb5310b424c1f608686173f13;p=dpdk.git diff --git a/drivers/bus/pci/linux/pci_vfio.c b/drivers/bus/pci/linux/pci_vfio.c index 64cd84a689..e3f7b6abeb 100644 --- a/drivers/bus/pci/linux/pci_vfio.c +++ b/drivers/bus/pci/linux/pci_vfio.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -33,7 +34,6 @@ * This code tries to determine if the PCI device is bound to VFIO driver, * and initialize it (map BARs, set up interrupts) if that's the case. * - * This file is only compiled if CONFIG_RTE_EAL_VFIO is set to "y". */ #ifdef VFIO_PRESENT @@ -149,6 +149,38 @@ pci_vfio_get_msix_bar(int fd, struct pci_msix_table *msix_table) return 0; } +/* enable PCI bus memory space */ +static int +pci_vfio_enable_bus_memory(int dev_fd) +{ + uint16_t cmd; + int ret; + + ret = pread64(dev_fd, &cmd, sizeof(cmd), + VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) + + PCI_COMMAND); + + if (ret != sizeof(cmd)) { + RTE_LOG(ERR, EAL, "Cannot read command from PCI config space!\n"); + return -1; + } + + if (cmd & PCI_COMMAND_MEMORY) + return 0; + + cmd |= PCI_COMMAND_MEMORY; + ret = pwrite64(dev_fd, &cmd, sizeof(cmd), + VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) + + PCI_COMMAND); + + if (ret != sizeof(cmd)) { + RTE_LOG(ERR, EAL, "Cannot write command to PCI config space!\n"); + return -1; + } + + return 0; +} + /* set PCI bus mastering */ static int pci_vfio_set_bus_master(int dev_fd, bool op) @@ -427,6 +459,11 @@ pci_rte_vfio_setup_device(struct rte_pci_device *dev, int vfio_dev_fd) return -1; } + if (pci_vfio_enable_bus_memory(vfio_dev_fd)) { + RTE_LOG(ERR, EAL, "Cannot enable bus memory!\n"); + return -1; + } + /* set bus mastering for the device */ if (pci_vfio_set_bus_master(vfio_dev_fd, true)) { RTE_LOG(ERR, EAL, "Cannot set up bus mastering!\n"); @@ -524,11 +561,23 @@ pci_vfio_mmap_bar(int vfio_dev_fd, struct mapped_pci_resource *vfio_res, map_addr = pci_map_resource(bar_addr, vfio_dev_fd, memreg[0].offset, memreg[0].size, - MAP_FIXED); + RTE_MAP_FORCE_ADDRESS); } + /* + * Regarding "memreg[0].size == 0": + * If this BAR has MSI-X table, memreg[0].size (the + * first part or the part before the table) can + * legitimately be 0 for hardware using vector table + * offset 0 (i.e. first part does not exist). + * + * When memreg[0].size is 0, "mapping the first part" + * never happens, and map_addr is NULL at this + * point. So check that mapping has been actually + * attempted. + */ /* if there's a second part, try to map it */ - if (map_addr != MAP_FAILED + if ((map_addr != NULL || memreg[0].size == 0) && memreg[1].offset && memreg[1].size) { void *second_addr = RTE_PTR_ADD(bar_addr, (uintptr_t)(memreg[1].offset - @@ -537,10 +586,10 @@ pci_vfio_mmap_bar(int vfio_dev_fd, struct mapped_pci_resource *vfio_res, vfio_dev_fd, memreg[1].offset, memreg[1].size, - MAP_FIXED); + RTE_MAP_FORCE_ADDRESS); } - if (map_addr == MAP_FAILED || !map_addr) { + if (map_addr == NULL) { munmap(bar_addr, bar->size); bar_addr = MAP_FAILED; RTE_LOG(ERR, EAL, "Failed to map pci BAR%d\n", @@ -713,7 +762,7 @@ pci_vfio_map_resource_primary(struct rte_pci_device *dev) } } - for (i = 0; i < (int) vfio_res->nb_maps; i++) { + for (i = 0; i < vfio_res->nb_maps; i++) { struct vfio_region_info *reg = NULL; void *bar_addr; @@ -789,7 +838,8 @@ pci_vfio_map_resource_primary(struct rte_pci_device *dev) err_vfio_res: rte_free(vfio_res); err_vfio_dev_fd: - close(vfio_dev_fd); + rte_vfio_release_device(rte_pci_get_sysfs_path(), + pci_addr, vfio_dev_fd); return -1; } @@ -838,7 +888,7 @@ pci_vfio_map_resource_secondary(struct rte_pci_device *dev) /* map BARs */ maps = vfio_res->maps; - for (i = 0; i < (int) vfio_res->nb_maps; i++) { + for (i = 0; i < vfio_res->nb_maps; i++) { ret = pci_vfio_mmap_bar(vfio_dev_fd, vfio_res, i, MAP_FIXED); if (ret < 0) { RTE_LOG(ERR, EAL, " %s mapping BAR%i failed: %s\n", @@ -857,7 +907,8 @@ pci_vfio_map_resource_secondary(struct rte_pci_device *dev) return 0; err_vfio_dev_fd: - close(vfio_dev_fd); + rte_vfio_release_device(rte_pci_get_sysfs_path(), + pci_addr, vfio_dev_fd); return -1; } @@ -897,7 +948,7 @@ find_and_unmap_vfio_resource(struct mapped_pci_res_list *vfio_res_list, pci_addr); maps = vfio_res->maps; - for (i = 0; i < (int) vfio_res->nb_maps; i++) { + for (i = 0; i < vfio_res->nb_maps; i++) { /* * We do not need to be aware of MSI-X table BAR mappings as @@ -966,7 +1017,7 @@ pci_vfio_unmap_resource_primary(struct rte_pci_device *dev) } TAILQ_REMOVE(vfio_res_list, vfio_res, next); - + rte_free(vfio_res); return 0; }