@@ -33,7 +33,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
INC := rte_branch_prediction.h rte_common.h
INC += rte_debug.h rte_eal.h rte_errno.h rte_launch.h rte_lcore.h
-INC += rte_log.h rte_memory.h rte_memzone.h rte_pci.h
+INC += rte_log.h rte_memory.h rte_memzone.h rte_pci.h rte_vmbus.h
INC += rte_per_lcore.h rte_random.h
INC += rte_tailq.h rte_interrupts.h rte_alarm.h
INC += rte_string_fns.h rte_version.h
@@ -113,6 +113,13 @@ rte_eal_devargs_add(enum rte_devtype devtype, const char *devargs_str)
goto fail;
break;
+ case RTE_DEVTYPE_WHITELISTED_VMBUS:
+ case RTE_DEVTYPE_BLACKLISTED_VMBUS:
+#ifdef RTE_LIBRTE_HV_PMD
+ if (uuid_parse(buf, devargs->uuid) == 0)
+ break;
+#endif
+ goto fail;
}
free(buf);
@@ -95,6 +95,11 @@ eal_long_options[] = {
{OPT_VFIO_INTR, 1, NULL, OPT_VFIO_INTR_NUM },
{OPT_VMWARE_TSC_MAP, 0, NULL, OPT_VMWARE_TSC_MAP_NUM },
{OPT_XEN_DOM0, 0, NULL, OPT_XEN_DOM0_NUM },
+#ifdef RTE_LIBRTE_HV_PMD
+ {OPT_NO_VMBUS, 0, NULL, OPT_NO_VMBUS_NUM },
+ {OPT_VMBUS_BLACKLIST, 1, NULL, OPT_VMBUS_BLACKLIST_NUM },
+ {OPT_VMBUS_WHITELIST, 1, NULL, OPT_VMBUS_WHITELIST_NUM },
+#endif
{0, 0, NULL, 0 }
};
@@ -855,6 +860,21 @@ eal_parse_common_option(int opt, const char *optarg,
conf->no_pci = 1;
break;
+#ifdef RTE_LIBRTE_HV_PMD
+ case OPT_NO_VMBUS_NUM:
+ conf->no_vmbus = 1;
+ break;
+ case OPT_VMBUS_BLACKLIST_NUM:
+ if (rte_eal_devargs_add(RTE_DEVTYPE_BLACKLISTED_VMBUS,
+ optarg) < 0)
+ return -1;
+ break;
+ case OPT_VMBUS_WHITELIST_NUM:
+ if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_VMBUS,
+ optarg) < 0)
+ return -1;
+ break;
+#endif
case OPT_NO_HPET_NUM:
conf->no_hpet = 1;
break;
@@ -987,6 +1007,14 @@ eal_check_common_options(struct internal_config *internal_cfg)
return -1;
}
+#ifdef RTE_LIBRTE_HV_PMD
+ if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_VMBUS) != 0 &&
+ rte_eal_devargs_type_count(RTE_DEVTYPE_BLACKLISTED_VMBUS) != 0) {
+ RTE_LOG(ERR, EAL, "Options vmbus blacklist and whitelist "
+ "cannot be used at the same time\n");
+ return -1;
+ }
+#endif
return 0;
}
@@ -1036,5 +1064,15 @@ eal_common_usage(void)
" --"OPT_NO_PCI" Disable PCI\n"
" --"OPT_NO_HPET" Disable HPET\n"
" --"OPT_NO_SHCONF" No shared config (mmap'd files)\n"
+#ifdef RTE_LIBRTE_HV_PMD
+ " --"OPT_NO_VMBUS" Disable VMBUS\n"
+ " --"OPT_VMBUS_BLACKLIST" Add a VMBUS device to black list.\n"
+ " Prevent EAL from using this PCI device. The argument\n"
+ " format is device UUID.\n"
+ " --"OPT_VMBUS_WHITELIST" Add a VMBUS device to white list.\n"
+ " Only use the specified VMBUS devices. The argument format\n"
+ " is device UUID This option can be present\n"
+ " several times (once per device).\n"
+#endif
"\n", RTE_MAX_LCORE);
}
@@ -69,7 +69,8 @@ struct internal_config {
volatile unsigned no_pci; /**< true to disable PCI */
volatile unsigned no_hpet; /**< true to disable HPET */
volatile unsigned vmware_tsc_map; /**< true to use VMware TSC mapping
- * instead of native TSC */
+ * instead of native TSC */
+ volatile unsigned no_vmbus; /**< true to disable VMBUS */
volatile unsigned no_shconf; /**< true if there is no shared config */
volatile unsigned create_uio_dev; /**< true to create /dev/uioX devices */
volatile enum rte_proc_type_t process_type; /**< multi-process proc type */
@@ -83,6 +83,12 @@ enum {
OPT_VMWARE_TSC_MAP_NUM,
#define OPT_XEN_DOM0 "xen-dom0"
OPT_XEN_DOM0_NUM,
+#define OPT_NO_VMBUS "no-vmbus"
+ OPT_NO_VMBUS_NUM,
+#define OPT_VMBUS_BLACKLIST "vmbus-blacklist"
+ OPT_VMBUS_BLACKLIST_NUM,
+#define OPT_VMBUS_WHITELIST "vmbus-whitelist"
+ OPT_VMBUS_WHITELIST_NUM,
OPT_LONG_MAX_NUM
};
@@ -210,6 +210,11 @@ int pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
struct mapped_pci_resource *uio_res, int map_idx);
/**
+ * VMBUS related functions and structures
+ */
+int rte_eal_vmbus_init(void);
+
+/**
* Init tail queues for non-EAL library structures. This is to allow
* the rings, mempools, etc. lists to be shared among multiple processes
*
@@ -51,6 +51,9 @@ extern "C" {
#include <stdio.h>
#include <sys/queue.h>
#include <rte_pci.h>
+#ifdef RTE_LIBRTE_HV_PMD
+#include <uuid/uuid.h>
+#endif
/**
* Type of generic device
@@ -59,6 +62,8 @@ enum rte_devtype {
RTE_DEVTYPE_WHITELISTED_PCI,
RTE_DEVTYPE_BLACKLISTED_PCI,
RTE_DEVTYPE_VIRTUAL,
+ RTE_DEVTYPE_WHITELISTED_VMBUS,
+ RTE_DEVTYPE_BLACKLISTED_VMBUS,
};
/**
@@ -88,6 +93,9 @@ struct rte_devargs {
/** Driver name. */
char drv_name[32];
} virt;
+#ifdef RTE_LIBRTE_HV_PMD
+ uuid_t uuid;
+#endif
};
/** Arguments string as given by user or "" for no argument. */
char *args;
@@ -71,6 +71,11 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_timer.c
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_interrupts.c
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_alarm.c
+ifeq ($(CONFIG_RTE_LIBRTE_HV_PMD),y)
+SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_vmbus.c
+LDLIBS += -luuid
+endif
+
# from common dir
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_lcore.c
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_timer.c
@@ -114,6 +119,7 @@ CFLAGS_eal_hugepage_info.o := -D_GNU_SOURCE
CFLAGS_eal_pci.o := -D_GNU_SOURCE
CFLAGS_eal_pci_uio.o := -D_GNU_SOURCE
CFLAGS_eal_pci_vfio.o := -D_GNU_SOURCE
+CFLAGS_eal_vmbux.o := -D_GNU_SOURCE
CFLAGS_eal_common_whitelist.o := -D_GNU_SOURCE
CFLAGS_eal_common_options.o := -D_GNU_SOURCE
CFLAGS_eal_common_thread.o := -D_GNU_SOURCE
@@ -70,6 +70,7 @@
#include <rte_cpuflags.h>
#include <rte_interrupts.h>
#include <rte_pci.h>
+#include <rte_vmbus.h>
#include <rte_dev.h>
#include <rte_devargs.h>
#include <rte_common.h>
@@ -830,6 +831,11 @@ rte_eal_init(int argc, char **argv)
eal_check_mem_on_local_socket();
+#ifdef RTE_LIBRTE_HV_PMD
+ if (rte_eal_vmbus_init() < 0)
+ RTE_LOG(ERR, EAL, "Cannot init VMBUS\n");
+#endif
+
if (eal_plugins_init() < 0)
rte_panic("Cannot init plugins\n");
@@ -887,6 +893,11 @@ rte_eal_init(int argc, char **argv)
if (rte_eal_pci_probe())
rte_panic("Cannot probe PCI\n");
+#ifdef RTE_LIBRTE_HV_PMD
+ if (rte_eal_vmbus_probe() < 0)
+ rte_panic("Cannot probe VMBUS\n");
+#endif
+
rte_eal_mcfg_complete();
return fctret;
@@ -3294,3 +3294,93 @@ rte_eth_dev_l2_tunnel_offload_set(uint8_t port_id,
-ENOTSUP);
return (*dev->dev_ops->l2_tunnel_offload_set)(dev, l2_tunnel, mask, en);
}
+
+
+#ifdef RTE_LIBRTE_HV_PMD
+int
+rte_eth_dev_vmbus_probe(struct rte_vmbus_driver *vmbus_drv,
+ struct rte_vmbus_device *vmbus_dev)
+{
+ struct eth_driver *eth_drv = (struct eth_driver *)vmbus_drv;
+ struct rte_eth_dev *eth_dev;
+ char ustr[UUID_BUF_SZ];
+ int diag;
+
+ uuid_unparse(vmbus_dev->device_id, ustr);
+
+ eth_dev = rte_eth_dev_allocate(ustr);
+ if (eth_dev == NULL)
+ return -ENOMEM;
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+ eth_dev->data->dev_private = rte_zmalloc("ethdev private structure",
+ eth_drv->dev_private_size,
+ RTE_CACHE_LINE_SIZE);
+ if (eth_dev->data->dev_private == NULL)
+ rte_panic("Cannot allocate memzone for private port data\n");
+ }
+
+ eth_dev->device = &vmbus_dev->device;
+ eth_dev->driver = eth_drv;
+ eth_dev->data->rx_mbuf_alloc_failed = 0;
+
+ /* init user callbacks */
+ TAILQ_INIT(&(eth_dev->link_intr_cbs));
+
+ /*
+ * Set the default maximum frame size.
+ */
+ eth_dev->data->mtu = ETHER_MTU;
+
+ /* Invoke PMD device initialization function */
+ diag = (*eth_drv->eth_dev_init)(eth_dev);
+ if (diag == 0)
+ return 0;
+
+ RTE_PMD_DEBUG_TRACE("driver %s: eth_dev_init(%s) failed\n",
+ vmbus_drv->driver.name, ustr);
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+ rte_free(eth_dev->data->dev_private);
+
+ return diag;
+}
+
+int
+rte_eth_dev_vmbus_remove(struct rte_vmbus_device *vmbus_dev)
+{
+ const struct eth_driver *eth_drv;
+ struct rte_eth_dev *eth_dev;
+ char ustr[UUID_BUF_SZ];
+ int ret;
+
+ if (vmbus_dev == NULL)
+ return -EINVAL;
+
+ uuid_unparse(vmbus_dev->device_id, ustr);
+ eth_dev = rte_eth_dev_allocated(ustr);
+ if (eth_dev == NULL)
+ return -ENODEV;
+
+ eth_drv = (const struct eth_driver *)vmbus_dev->driver;
+
+ /* Invoke PMD device uninit function */
+ if (*eth_drv->eth_dev_uninit) {
+ ret = (*eth_drv->eth_dev_uninit)(eth_dev);
+ if (ret)
+ return ret;
+ }
+
+ /* free ether device */
+ rte_eth_dev_release_port(eth_dev);
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+ rte_free(eth_dev->data->dev_private);
+
+ eth_dev->device = NULL;
+ eth_dev->driver = NULL;
+ eth_dev->data = NULL;
+
+ return 0;
+}
+#endif
@@ -180,6 +180,7 @@ extern "C" {
#include <rte_log.h>
#include <rte_interrupts.h>
#include <rte_pci.h>
+#include <rte_vmbus.h>
#include <rte_dev.h>
#include <rte_devargs.h>
#include "rte_ether.h"
@@ -1866,7 +1867,11 @@ typedef int (*eth_dev_uninit_t)(struct rte_eth_dev *eth_dev);
* - The size of the private data to allocate for each matching device.
*/
struct eth_driver {
- struct rte_pci_driver pci_drv; /**< The PMD is also a PCI driver. */
+ union {
+ struct rte_pci_driver pci_drv; /**< The PMD PCI driver. */
+ struct rte_vmbus_driver vmbus_drv;/**< The PMD VMBUS drv. */
+ };
+
eth_dev_init_t eth_dev_init; /**< Device init function. */
eth_dev_uninit_t eth_dev_uninit; /**< Device uninit function. */
unsigned int dev_private_size; /**< Size of device private data. */
@@ -4383,6 +4388,21 @@ int rte_eth_dev_pci_probe(struct rte_pci_driver *pci_drv,
*/
int rte_eth_dev_pci_remove(struct rte_pci_device *pci_dev);
+/**
+ * @internal
+ * Wrapper for use by vmbus drivers as a .probe function to attach to a ethdev
+ * interface.
+ */
+int rte_eth_dev_vmbus_probe(struct rte_vmbus_driver *vmbus_drv,
+ struct rte_vmbus_device *vmbus_dev);
+
+/**
+ * @internal
+ * Wrapper for use by vmbus drivers as a .remove function to detach a ethdev
+ * interface.
+ */
+int rte_eth_dev_vmbus_remove(struct rte_vmbus_device *vmbus_dev);
+
#ifdef __cplusplus
}
#endif
@@ -130,6 +130,7 @@ ifeq ($(CONFIG_RTE_LIBRTE_VHOST),y)
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_VHOST) += -lrte_pmd_vhost
endif # $(CONFIG_RTE_LIBRTE_VHOST)
_LDLIBS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD) += -lrte_pmd_vmxnet3_uio
+_LDLIBS-$(CONFIG_RTE_LIBRTE_HV_PMD) += -luuid
ifeq ($(CONFIG_RTE_LIBRTE_CRYPTODEV),y)
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += -lrte_pmd_aesni_mb