aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorDave Barach <dave@barachs.net>2018-12-18 16:06:36 -0500
committerDamjan Marion <dmarion@me.com>2018-12-19 07:24:56 +0000
commit4d3739dddb00277690025aa85caad08d30f8f4ab (patch)
treee953a6ab1d3c43701527a2d21a147d9f9db16ca3 /src/plugins
parenta9d5bea69fafbcc2f24d71439433c9b710db665f (diff)
dpdk plugin: blacklist PCI devices by type
Change-Id: I89695c1ad47131ed830f35c677937ce12025a40d Signed-off-by: Dave Barach <dave@barachs.net>
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/dpdk/device/dpdk.h3
-rw-r--r--src/plugins/dpdk/device/init.c45
2 files changed, 47 insertions, 1 deletions
diff --git a/src/plugins/dpdk/device/dpdk.h b/src/plugins/dpdk/device/dpdk.h
index 4c45e875933..a1e07b42ca7 100644
--- a/src/plugins/dpdk/device/dpdk.h
+++ b/src/plugins/dpdk/device/dpdk.h
@@ -377,6 +377,9 @@ typedef struct
dpdk_device_config_t *dev_confs;
uword *device_config_index_by_pci_addr;
+ /* devices blacklist by pci vendor_id, device_id */
+ u32 *blacklist_by_pci_vendor_and_device;
+
} dpdk_config_main_t;
extern dpdk_config_main_t dpdk_config_main;
diff --git a/src/plugins/dpdk/device/init.c b/src/plugins/dpdk/device/init.c
index 9a78ac6761b..c0a927acae5 100644
--- a/src/plugins/dpdk/device/init.c
+++ b/src/plugins/dpdk/device/init.c
@@ -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)) \