diff options
Diffstat (limited to 'src/plugins/dpdk')
-rw-r--r-- | src/plugins/dpdk/device/dpdk.h | 3 | ||||
-rw-r--r-- | src/plugins/dpdk/device/init.c | 45 |
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)) \ |