X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=lib%2Flibrte_eal%2Flinuxapp%2Feal%2Feal_pci_vfio.c;h=f91b9242439315da9adf46f5d003f78d2853cd1c;hb=701c8d80c820461e8255dfb7387a09f0e54399f0;hp=ffa2dd05bf02ee4b912f006e34069815f6bb36fb;hpb=756ce64b1ecdf107acfa45fc3f31359ca338649e;p=dpdk.git diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c index ffa2dd05bf..f91b924243 100644 --- a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c +++ b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c @@ -74,6 +74,7 @@ EAL_REGISTER_TAILQ(rte_vfio_tailq) #define VFIO_GROUP_FMT "/dev/vfio/%u" #define VFIO_NOIOMMU_GROUP_FMT "/dev/vfio/noiommu-%u" #define VFIO_GET_REGION_ADDR(x) ((uint64_t) x << 40ULL) +#define VFIO_GET_REGION_IDX(x) (x >> 40) /* per-process VFIO config */ static struct vfio_config vfio_cfg; @@ -534,6 +535,7 @@ pci_vfio_get_group_fd(int iommu_group_no) /* if the fd is valid, create a new group for it */ if (vfio_cfg.vfio_group_idx == VFIO_MAX_GROUPS) { RTE_LOG(ERR, EAL, "Maximum number of VFIO groups reached!\n"); + close(vfio_group_fd); return -1; } vfio_cfg.vfio_groups[vfio_cfg.vfio_group_idx].group_no = iommu_group_no; @@ -600,7 +602,7 @@ pci_vfio_get_group_no(const char *pci_addr, int *iommu_group_no) /* try to find out IOMMU group for this device */ snprintf(linkname, sizeof(linkname), - SYSFS_PCI_DEVICES "/%s/iommu_group", pci_addr); + "%s/%s/iommu_group", pci_get_sysfs_path(), pci_addr); ret = readlink(linkname, filename, sizeof(filename)); @@ -659,6 +661,7 @@ pci_vfio_map_resource(struct rte_pci_device *dev) struct pci_map *maps; uint32_t msix_table_offset = 0; uint32_t msix_table_size = 0; + uint32_t ioport_bar; dev->intr_handle.fd = -1; dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN; @@ -853,6 +856,25 @@ pci_vfio_map_resource(struct rte_pci_device *dev) return -1; } + /* chk for io port region */ + ret = pread64(vfio_dev_fd, &ioport_bar, sizeof(ioport_bar), + VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) + + PCI_BASE_ADDRESS_0 + i*4); + + if (ret != sizeof(ioport_bar)) { + RTE_LOG(ERR, EAL, + "Cannot read command (%x) from config space!\n", + PCI_BASE_ADDRESS_0 + i*4); + return -1; + } + + if (ioport_bar & PCI_BASE_ADDRESS_SPACE_IO) { + RTE_LOG(INFO, EAL, + "Ignore mapping IO port bar(%d) addr: %x\n", + i, ioport_bar); + continue; + } + /* skip non-mmapable BARs */ if ((reg.flags & VFIO_REGION_INFO_FLAG_MMAP) == 0) continue; @@ -979,30 +1001,41 @@ int pci_vfio_ioport_map(struct rte_pci_device *dev, int bar, struct rte_pci_ioport *p) { - RTE_SET_USED(dev); - RTE_SET_USED(bar); - RTE_SET_USED(p); - return -1; + if (bar < VFIO_PCI_BAR0_REGION_INDEX || + bar > VFIO_PCI_BAR5_REGION_INDEX) { + RTE_LOG(ERR, EAL, "invalid bar (%d)!\n", bar); + return -1; + } + + p->dev = dev; + p->base = VFIO_GET_REGION_ADDR(bar); + return 0; } void pci_vfio_ioport_read(struct rte_pci_ioport *p, void *data, size_t len, off_t offset) { - RTE_SET_USED(p); - RTE_SET_USED(data); - RTE_SET_USED(len); - RTE_SET_USED(offset); + const struct rte_intr_handle *intr_handle = &p->dev->intr_handle; + + if (pread64(intr_handle->vfio_dev_fd, data, + len, p->base + offset) <= 0) + RTE_LOG(ERR, EAL, + "Can't read from PCI bar (%" PRIu64 ") : offset (%x)\n", + VFIO_GET_REGION_IDX(p->base), (int)offset); } void pci_vfio_ioport_write(struct rte_pci_ioport *p, const void *data, size_t len, off_t offset) { - RTE_SET_USED(p); - RTE_SET_USED(data); - RTE_SET_USED(len); - RTE_SET_USED(offset); + const struct rte_intr_handle *intr_handle = &p->dev->intr_handle; + + if (pwrite64(intr_handle->vfio_dev_fd, data, + len, p->base + offset) <= 0) + RTE_LOG(ERR, EAL, + "Can't write to PCI bar (%" PRIu64 ") : offset (%x)\n", + VFIO_GET_REGION_IDX(p->base), (int)offset); } int @@ -1038,7 +1071,7 @@ pci_vfio_enable(void) /* return 0 if VFIO modules not loaded */ if (vfio_available == 0) { - RTE_LOG(INFO, EAL, "VFIO modules not loaded, " + RTE_LOG(DEBUG, EAL, "VFIO modules not loaded, " "skipping VFIO support...\n"); return 0; }