summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/plugins/dpdk/device/init.c2
-rw-r--r--src/vlib/linux/pci.c55
-rw-r--r--src/vpp/conf/startup.conf4
3 files changed, 58 insertions, 3 deletions
diff --git a/src/plugins/dpdk/device/init.c b/src/plugins/dpdk/device/init.c
index a6b6440f230..6041a3ca2a8 100755
--- a/src/plugins/dpdk/device/init.c
+++ b/src/plugins/dpdk/device/init.c
@@ -1035,7 +1035,7 @@ dpdk_config (vlib_main_t * vm, unformat_input_t * input)
}
if (!conf->uio_driver_name)
- conf->uio_driver_name = format (0, "uio_pci_generic%c", 0);
+ conf->uio_driver_name = format (0, "auto%c", 0);
/*
* Use 1G huge pages if available.
diff --git a/src/vlib/linux/pci.c b/src/vlib/linux/pci.c
index 69dcdd0d760..62edcf4f8b6 100644
--- a/src/vlib/linux/pci.c
+++ b/src/vlib/linux/pci.c
@@ -56,6 +56,8 @@
static const char *sysfs_pci_dev_path = "/sys/bus/pci/devices";
static const char *sysfs_pci_drv_path = "/sys/bus/pci/drivers";
+static char *sysfs_mod_vfio_noiommu =
+ "/sys/module/vfio/parameters/enable_unsafe_noiommu_mode";
typedef struct
{
@@ -314,6 +316,16 @@ done:
return di;
}
+static int
+directory_exists (char *path)
+{
+ struct stat s = { 0 };
+ if (stat (path, &s) == -1)
+ return 0;
+
+ return S_ISDIR (s.st_mode);
+}
+
clib_error_t *
vlib_pci_bind_to_uio (vlib_pci_addr_t * addr, char *uio_drv_name)
{
@@ -331,6 +343,49 @@ vlib_pci_bind_to_uio (vlib_pci_addr_t * addr, char *uio_drv_name)
if (error)
return error;
+ if (strncmp ("auto", uio_drv_name, 5) == 0)
+ {
+ int vfio_pci_loaded = 0;
+
+ if (directory_exists ("/sys/module/vfio_pci"))
+ vfio_pci_loaded = 1;
+
+ if (di->iommu_group != -1)
+ {
+ /* device is bound to IOMMU group */
+ if (!vfio_pci_loaded)
+ {
+ error = clib_error_return (0, "Skipping PCI device %U: device "
+ "is bound to IOMMU group and "
+ "vfio-pci driver is not loaded",
+ format_vlib_pci_addr, addr);
+ goto done;
+ }
+ else
+ uio_drv_name = "vfio-pci";
+ }
+ else
+ {
+ /* device is not bound to IOMMU group so we have multiple options */
+ if (vfio_pci_loaded &&
+ (error = clib_sysfs_write (sysfs_mod_vfio_noiommu, "Y")) == 0)
+ uio_drv_name = "vfio-pci";
+ else if (directory_exists ("/sys/module/uio_pci_generic"))
+ uio_drv_name = "uio_pci_generic";
+ else if (directory_exists ("/sys/module/igb_uio"))
+ uio_drv_name = "igb_uio";
+ else
+ {
+ clib_error_free (error);
+ error = clib_error_return (0, "Skipping PCI device %U: missing "
+ "kernel VFIO or UIO driver",
+ format_vlib_pci_addr, addr);
+ goto done;
+ }
+ clib_error_free (error);
+ }
+ }
+
s = format (s, "%v/driver%c", dev_dir_name, 0);
driver_name = clib_sysfs_link_to_name ((char *) s);
vec_reset_length (s);
diff --git a/src/vpp/conf/startup.conf b/src/vpp/conf/startup.conf
index 304dd1fab3f..b18c6743869 100644
--- a/src/vpp/conf/startup.conf
+++ b/src/vpp/conf/startup.conf
@@ -105,8 +105,8 @@ cpu {
# vdev eth_bond0,mode=1,slave=0000:02:00.0,slave=0000:03:00.0
# vdev eth_bond1,mode=1,slave=0000:02:00.1,slave=0000:03:00.1
- ## Change UIO driver used by VPP, Options are: igb_uio, vfio-pci
- ## and uio_pci_generic (default)
+ ## Change UIO driver used by VPP, Options are: igb_uio, vfio-pci,
+ ## uio_pci_generic or auto (default)
# uio-driver vfio-pci
## Disable mutli-segment buffers, improves performance but