#include <sys/eventfd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
+#include <sys/mman.h>
#include <rte_log.h>
#include <rte_pci.h>
#include <rte_tailq.h>
#include <rte_eal_memconfig.h>
#include <rte_malloc.h>
+#include <eal_private.h>
#include "eal_filesystem.h"
#include "eal_pci_init.h"
ret = ioctl(vfio_container_fd, VFIO_SET_IOMMU,
VFIO_TYPE1_IOMMU);
if (ret) {
- RTE_LOG(ERR, EAL, " cannot set IOMMU type!\n");
+ RTE_LOG(ERR, EAL, " cannot set IOMMU type, "
+ "error %i (%s)\n", errno, strerror(errno));
return -1;
}
ret = ioctl(vfio_container_fd, VFIO_IOMMU_MAP_DMA, &dma_map);
if (ret) {
- RTE_LOG(ERR, EAL, " cannot set up DMA remapping!\n");
+ RTE_LOG(ERR, EAL, " cannot set up DMA remapping, "
+ "error %i (%s)\n", errno, strerror(errno));
return -1;
}
}
ret = ioctl(vfio_dev_fd, VFIO_DEVICE_GET_IRQ_INFO, &irq);
if (ret < 0) {
- RTE_LOG(ERR, EAL, " cannot get IRQ info!\n");
+ RTE_LOG(ERR, EAL, " cannot get IRQ info, "
+ "error %i (%s)\n", errno, strerror(errno));
return -1;
}
/* set up an eventfd for interrupts */
fd = eventfd(0, 0);
if (fd < 0) {
- RTE_LOG(ERR, EAL, " cannot set up eventfd!\n");
+ RTE_LOG(ERR, EAL, " cannot set up eventfd, "
+ "error %i (%s)\n", errno, strerror(errno));
return -1;
}
if (internal_config.process_type == RTE_PROC_PRIMARY) {
vfio_container_fd = open(VFIO_CONTAINER_PATH, O_RDWR);
if (vfio_container_fd < 0) {
- RTE_LOG(ERR, EAL, " cannot open VFIO container!\n");
+ RTE_LOG(ERR, EAL, " cannot open VFIO container, "
+ "error %i (%s)\n", errno, strerror(errno));
return -1;
}
/* check VFIO API version */
ret = ioctl(vfio_container_fd, VFIO_GET_API_VERSION);
if (ret != VFIO_API_VERSION) {
- RTE_LOG(ERR, EAL, " unknown VFIO API version!\n");
+ if (ret < 0)
+ RTE_LOG(ERR, EAL, " could not get VFIO API version, "
+ "error %i (%s)\n", errno, strerror(errno));
+ else
+ RTE_LOG(ERR, EAL, " unsupported VFIO API version!\n");
close(vfio_container_fd);
return -1;
}
/* check if we support IOMMU type 1 */
ret = ioctl(vfio_container_fd, VFIO_CHECK_EXTENSION, VFIO_TYPE1_IOMMU);
- if (!ret) {
- RTE_LOG(ERR, EAL, " unknown IOMMU driver!\n");
+ if (ret != 1) {
+ if (ret < 0)
+ RTE_LOG(ERR, EAL, " could not get IOMMU type, "
+ "error %i (%s)\n", errno,
+ strerror(errno));
+ else
+ RTE_LOG(ERR, EAL, " unsupported IOMMU type "
+ "detected in VFIO\n");
close(vfio_container_fd);
return -1;
}
/* if primary, try to open the group */
if (internal_config.process_type == RTE_PROC_PRIMARY) {
- rte_snprintf(filename, sizeof(filename),
+ snprintf(filename, sizeof(filename),
VFIO_GROUP_FMT, iommu_group_no);
vfio_group_fd = open(filename, O_RDWR);
if (vfio_group_fd < 0) {
memset(filename, 0, sizeof(filename));
/* try to find out IOMMU group for this device */
- rte_snprintf(linkname, sizeof(linkname),
+ snprintf(linkname, sizeof(linkname),
SYSFS_PCI_DEVICES "/%s/iommu_group", pci_addr);
ret = readlink(linkname, filename, sizeof(filename));
dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
/* store PCI address string */
- rte_snprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,
+ snprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,
loc->domain, loc->bus, loc->devid, loc->function);
- /* get container fd (needs to be done only once per initialization) */
- if (vfio_cfg.vfio_container_fd == -1) {
- int vfio_container_fd = pci_vfio_get_container_fd();
- if (vfio_container_fd < 0) {
- RTE_LOG(ERR, EAL, " %s cannot open VFIO container!\n", pci_addr);
- return -1;
- }
-
- vfio_cfg.vfio_container_fd = vfio_container_fd;
- }
-
/* get group number */
iommu_group_no = pci_vfio_get_group_no(pci_addr);
/* check if the group is viable */
ret = ioctl(vfio_group_fd, VFIO_GROUP_GET_STATUS, &group_status);
if (ret) {
- RTE_LOG(ERR, EAL, " %s cannot get group status!\n", pci_addr);
+ RTE_LOG(ERR, EAL, " %s cannot get group status, "
+ "error %i (%s)\n", pci_addr, errno, strerror(errno));
close(vfio_group_fd);
clear_current_group();
return -1;
ret = ioctl(vfio_group_fd, VFIO_GROUP_SET_CONTAINER,
&vfio_cfg.vfio_container_fd);
if (ret) {
- RTE_LOG(ERR, EAL, " %s cannot add VFIO group to container!\n",
- pci_addr);
+ RTE_LOG(ERR, EAL, " %s cannot add VFIO group to container, "
+ "error %i (%s)\n", pci_addr, errno, strerror(errno));
close(vfio_group_fd);
clear_current_group();
return -1;
vfio_cfg.vfio_container_has_dma == 0) {
ret = pci_vfio_setup_dma_maps(vfio_cfg.vfio_container_fd);
if (ret) {
- RTE_LOG(ERR, EAL, " %s DMA remapping failed!\n", pci_addr);
+ RTE_LOG(ERR, EAL, " %s DMA remapping failed, "
+ "error %i (%s)\n", pci_addr, errno, strerror(errno));
return -1;
}
vfio_cfg.vfio_container_has_dma = 1;
/* test and setup the device */
ret = ioctl(vfio_dev_fd, VFIO_DEVICE_GET_INFO, &device_info);
if (ret) {
- RTE_LOG(ERR, EAL, " %s cannot get device info!\n", pci_addr);
+ RTE_LOG(ERR, EAL, " %s cannot get device info, "
+ "error %i (%s)\n", pci_addr, errno, strerror(errno));
close(vfio_dev_fd);
return -1;
}
ret = ioctl(vfio_dev_fd, VFIO_DEVICE_GET_REGION_INFO, ®);
if (ret) {
- RTE_LOG(ERR, EAL, " %s cannot get device region info!\n",
- pci_addr);
+ RTE_LOG(ERR, EAL, " %s cannot get device region info "
+ "error %i (%s)\n", pci_addr, errno, strerror(errno));
close(vfio_dev_fd);
if (internal_config.process_type == RTE_PROC_PRIMARY)
rte_free(vfio_res);
if (i == msix_bar)
continue;
- bar_addr = pci_map_resource(maps[i].addr, vfio_dev_fd, reg.offset,
- reg.size);
+ if (internal_config.process_type == RTE_PROC_PRIMARY) {
+ /* try mapping somewhere close to the end of hugepages */
+ if (pci_map_addr == NULL)
+ pci_map_addr = pci_find_max_end_va();
+
+ bar_addr = pci_map_resource(pci_map_addr, vfio_dev_fd, reg.offset,
+ reg.size);
+ pci_map_addr = RTE_PTR_ADD(bar_addr, (size_t) reg.size);
+ } else {
+ bar_addr = pci_map_resource(maps[i].addr, vfio_dev_fd, reg.offset,
+ reg.size);
+ }
- if (bar_addr == NULL) {
+ if (bar_addr == MAP_FAILED ||
+ (internal_config.process_type == RTE_PROC_SECONDARY &&
+ bar_addr != maps[i].addr)) {
RTE_LOG(ERR, EAL, " %s mapping BAR%i failed: %s\n", pci_addr, i,
strerror(errno));
close(vfio_dev_fd);
{
/* initialize group list */
int i;
+ int module_vfio_type1;
for (i = 0; i < VFIO_MAX_GROUPS; i++) {
vfio_cfg.vfio_groups[i].fd = -1;
vfio_cfg.vfio_groups[i].group_no = -1;
}
- vfio_cfg.vfio_container_fd = -1;
+
+ module_vfio_type1 = rte_eal_check_module("vfio_iommu_type1");
+
+ /* return error directly */
+ if (module_vfio_type1 == -1) {
+ RTE_LOG(INFO, EAL, "Could not get loaded module details!\n");
+ return -1;
+ }
+
+ /* return 0 if VFIO modules not loaded */
+ if (module_vfio_type1 == 0) {
+ RTE_LOG(INFO, EAL, "VFIO modules not all loaded, "
+ "skip VFIO support...\n");
+ return 0;
+ }
+
+ vfio_cfg.vfio_container_fd = pci_vfio_get_container_fd();
/* check if we have VFIO driver enabled */
- if (access(VFIO_DIR, F_OK) == 0)
+ if (vfio_cfg.vfio_container_fd != -1)
vfio_cfg.vfio_enabled = 1;
else
- RTE_LOG(INFO, EAL, "VFIO driver not loaded or wrong permissions\n");
+ RTE_LOG(INFO, EAL, "VFIO support could not be initialized\n");
return 0;
}