dpdk plugin: blacklist PCI devices by type
[vpp.git] / src / plugins / dpdk / device / init.c
index 9a78ac6..c0a927a 100644 (file)
@@ -828,6 +828,7 @@ dpdk_bind_devices_to_uio (dpdk_config_main_t * conf)
   int num_whitelisted = vec_len (conf->dev_confs);
   vlib_pci_device_info_t *d = 0;
   vlib_pci_addr_t *addr = 0, *addrs;
+  int i;
 
   addrs = vlib_pci_get_all_dev_addrs ();
   /* *INDENT-OFF* */
@@ -856,11 +857,41 @@ dpdk_bind_devices_to_uio (dpdk_config_main_t * conf)
        uword * p = hash_get (conf->device_config_index_by_pci_addr, addr->as_u32);
 
        if (!p)
-         continue;
+          {
+          skipped:
+            continue;
+          }
 
        devconf = pool_elt_at_index (conf->dev_confs, p[0]);
       }
 
+    /* Enforce Device blacklist by vendor and device */
+    for (i = 0; i < vec_len (conf->blacklist_by_pci_vendor_and_device); i++)
+      {
+        u16 vendor, device;
+        vendor = (u16)(conf->blacklist_by_pci_vendor_and_device[i] >> 16);
+        device = (u16)(conf->blacklist_by_pci_vendor_and_device[i] & 0xFFFF);
+        if (d->vendor_id == vendor && d->device_id == device)
+          {
+            /*
+             * Expected case: device isn't whitelisted,
+             * so blacklist it...
+             */
+            if (devconf == 0)
+              {
+                /* Device is blacklisted */
+                pool_get (conf->dev_confs, devconf);
+                hash_set (conf->device_config_index_by_pci_addr, addr->as_u32,
+                          devconf - conf->dev_confs);
+                devconf->pci_addr.as_u32 = addr->as_u32;
+                devconf->is_blacklisted = 1;
+                goto skipped;
+              }
+            else /* explicitly whitelisted, ignore the device blacklist  */
+              break;
+          }
+      }
+
     /* virtio */
     if (d->vendor_id == 0x1af4 &&
             (d->device_id == VIRTIO_PCI_LEGACY_DEVICEID_NET ||
@@ -1095,6 +1126,7 @@ dpdk_config (vlib_main_t * vm, unformat_input_t * input)
   u8 file_prefix = 0;
   u8 *socket_mem = 0;
   u8 *huge_dir_path = 0;
+  u32 vendor, device;
 
   huge_dir_path =
     format (0, "%s/hugepages%c", vlib_unix_get_runtime_dir (), 0);
@@ -1171,6 +1203,17 @@ dpdk_config (vlib_main_t * vm, unformat_input_t * input)
          tmp = format (0, "--no-pci%c", 0);
          vec_add1 (conf->eal_init_args, tmp);
        }
+      else if (unformat (input, "blacklist %x:%x", &vendor, &device))
+       {
+         u32 blacklist_entry;
+         if (vendor > 0xFFFF)
+           return clib_error_return (0, "blacklist PCI vendor out of range");
+         if (device > 0xFFFF)
+           return clib_error_return (0, "blacklist PCI device out of range");
+         blacklist_entry = (vendor << 16) | (device & 0xffff);
+         vec_add1 (conf->blacklist_by_pci_vendor_and_device,
+                   blacklist_entry);
+       }
 
 #define _(a)                                    \
       else if (unformat(input, #a))             \