@@ -33,7 +33,7 @@ obj-$(CONFIG_MILKYMIST) += milkymist-minimac2.o
obj-$(CONFIG_PSERIES) += spapr_llan.o
obj-$(CONFIG_XILINX_ETHLITE) += xilinx_ethlite.o
-obj-$(CONFIG_VIRTIO) += virtio-net.o
+obj-$(CONFIG_VIRTIO) += virtio-net.o vhost-pci-net.o
obj-y += vhost_net.o
obj-$(CONFIG_ETSEC) += fsl_etsec/etsec.o fsl_etsec/registers.o \
new file mode 100644
@@ -0,0 +1,142 @@
+/*
+ * vhost-pci-net support
+ *
+ * Copyright Intel, Inc. 2016
+ *
+ * Authors:
+ * Wei Wang <wei.w.wang@intel.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ * Contributions after 2012-01-13 are licensed under the terms of the
+ * GNU GPL, version 2 or (at your option) any later version.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/iov.h"
+#include "hw/virtio/virtio.h"
+#include "net/net.h"
+#include "net/checksum.h"
+#include "net/tap.h"
+#include "qemu/error-report.h"
+#include "qemu/timer.h"
+#include "hw/virtio/virtio-net.h"
+//#include "net/vhost_net.h"
+#include "hw/virtio/virtio-bus.h"
+#include "qapi/qmp/qjson.h"
+#include "qapi-event.h"
+#include "hw/virtio/virtio-access.h"
+#include "hw/virtio/vhost-pci-net.h"
+
+void vhost_pci_net_set_max_rxqs(VhostPCINet *vpnet, uint16_t num)
+{
+ vpnet->max_rxq_num = num;
+}
+
+static void vpnet_handle_input(VirtIODevice *vdev, VirtQueue *vq)
+{
+}
+
+static void vpnet_handle_output(VirtIODevice *vdev, VirtQueue *vq)
+{
+}
+
+static void vhost_pci_net_device_realize(DeviceState *dev, Error **errp)
+{
+ VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+ VhostPCINet *vpnet = VHOST_PCI_NET(vdev);
+ int i;
+
+ virtio_init(vdev, "vhost-pci-net", VIRTIO_ID_VHOST_PCI_NET, vpnet->config_size);
+
+ /* control quque: host to guest */
+ vpnet->cvq_rx = virtio_add_queue(vdev, 32, vpnet_handle_input);
+ /* control quque: guest to host */
+ vpnet->cvq_tx = virtio_add_queue(vdev, 32, vpnet_handle_output);
+
+ vpnet->rxqs = g_malloc0(sizeof(VirtQueue *) * vpnet->max_rxq_num);
+ for (i = 0; i < vpnet->max_rxq_num; i++) {
+ vpnet->rxqs[i] = virtio_add_queue(vdev, 256, vpnet_handle_output);
+ }
+}
+
+static void vhost_pci_net_device_unrealize(DeviceState *dev, Error **errp)
+{
+}
+
+static void vhost_pci_net_get_config(VirtIODevice *vdev, uint8_t *config)
+{
+}
+
+static void vhost_pci_net_set_config(VirtIODevice *vdev, const uint8_t *config)
+{
+}
+
+void vhost_pci_net_init_device_features(VhostPCINet *vpnet, uint64_t features)
+{
+ vpnet->device_features = features;
+}
+
+static uint64_t vhost_pci_net_get_features(VirtIODevice *vdev, uint64_t features, Error **errp)
+{
+ VhostPCINet *vpnet = VHOST_PCI_NET(vdev);
+
+ return vpnet->device_features;
+}
+
+static void vhost_pci_net_set_features(VirtIODevice *vdev, uint64_t features)
+{
+}
+
+static void vhost_pci_net_instance_init(Object *obj)
+{
+ VhostPCINet *vpnet = VHOST_PCI_NET(obj);
+
+ /*
+ * The default config_size is sizeof(struct vhost_pci_net_config).
+ * Can be overriden with vhost_pci_net_set_config_size.
+ */
+ vpnet->config_size = sizeof(struct vhost_pci_net_config);
+}
+
+static Property vhost_pci_net_properties[] = {
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void vhost_pci_net_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+
+ dc->props = vhost_pci_net_properties;
+ set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
+ vdc->realize = vhost_pci_net_device_realize;
+ vdc->unrealize = vhost_pci_net_device_unrealize;
+ vdc->get_config = vhost_pci_net_get_config;
+ vdc->set_config = vhost_pci_net_set_config;
+ vdc->get_features = vhost_pci_net_get_features;
+ vdc->set_features = vhost_pci_net_set_features;
+// vdc->bad_features = vhost_pci_net_bad_features;
+// vdc->reset = vhost_pci_net_reset;
+// vdc->set_status = vhost_pci_net_set_status;
+// vdc->guest_notifier_mask = vhost_pci_net_guest_notifier_mask;
+// vdc->guest_notifier_pending = vhost_pci_net_guest_notifier_pending;
+// vdc->load = vhost_pci_net_load_device;
+// vdc->save = vhost_pci_net_save_device;
+}
+
+static const TypeInfo vhost_pci_net_info = {
+ .name = TYPE_VHOST_PCI_NET,
+ .parent = TYPE_VIRTIO_DEVICE,
+ .instance_size = sizeof(VhostPCINet),
+ .instance_init = vhost_pci_net_instance_init,
+ .class_init = vhost_pci_net_class_init,
+};
+
+static void virtio_register_types(void)
+{
+ type_register_static(&vhost_pci_net_info);
+}
+
+type_init(virtio_register_types)
@@ -25,6 +25,7 @@
#include "hw/virtio/virtio-scsi.h"
#include "hw/virtio/virtio-balloon.h"
#include "hw/virtio/virtio-input.h"
+#include "hw/virtio/vhost-pci-net.h"
#include "hw/pci/pci.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
@@ -2416,6 +2417,71 @@ static const TypeInfo virtio_host_pci_info = {
};
#endif
+/* vhost-pci-net */
+
+static Property vhost_pci_net_pci_properties[] = {
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void vhost_pci_net_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
+{
+ DeviceState *qdev = DEVICE(vpci_dev);
+ VhostPCINetPCI *dev = VHOST_PCI_NET_PCI(vpci_dev);
+ DeviceState *vdev = DEVICE(&dev->vdev);
+ PeerConnectionTable *ent;
+
+// virtio_net_set_netclient_name(&dev->vdev, qdev->id,
+// object_get_typename(OBJECT(qdev)));
+ qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
+
+ ent = vp_server_find_table_ent(qdev->id);
+ if (ent == NULL)
+ printf("%s called: no entry found \n", __func__);
+
+ /* Sanity Check */
+ if (ent->virtio_id != VIRTIO_ID_NET)
+ printf("%s called: device type doesn't match \n", __func__);
+ ent->bar_id = 2;
+ pci_register_bar(&vpci_dev->pci_dev, ent->bar_id,
+ PCI_BASE_ADDRESS_SPACE_MEMORY |
+ PCI_BASE_ADDRESS_MEM_PREFETCH |
+ PCI_BASE_ADDRESS_MEM_TYPE_64,
+ ent->bar_mr);
+ vhost_pci_net_set_max_rxqs(&dev->vdev, ent->vq_num / 2);
+ vhost_pci_net_init_device_features(&dev->vdev, ent->peer_feature_bits);
+ object_property_set_bool(OBJECT(vdev), true, "realized", errp);
+}
+
+static void vhost_pci_net_pci_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+ VirtioPCIClass *vpciklass = VIRTIO_PCI_CLASS(klass);
+
+ k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+ k->device_id = PCI_DEVICE_ID_VHOST_PCI_NET;
+ k->class_id = PCI_CLASS_NETWORK_ETHERNET;
+ set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
+ dc->props = vhost_pci_net_pci_properties;
+ vpciklass->realize = vhost_pci_net_pci_realize;
+}
+
+static void vhost_pci_net_pci_instance_init(Object *obj)
+{
+ VhostPCINetPCI *dev = VHOST_PCI_NET_PCI(obj);
+
+ virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
+ TYPE_VHOST_PCI_NET);
+}
+
+static const TypeInfo vhost_pci_net_pci_info = {
+ .name = TYPE_VHOST_PCI_NET_PCI,
+ .parent = TYPE_VIRTIO_PCI,
+ .instance_size = sizeof(VhostPCINetPCI),
+ .instance_init = vhost_pci_net_pci_instance_init,
+ .class_init = vhost_pci_net_pci_class_init,
+};
+
/* virtio-pci-bus */
static void virtio_pci_bus_new(VirtioBusState *bus, size_t bus_size,
@@ -2482,6 +2548,7 @@ static void virtio_pci_register_types(void)
type_register_static(&virtio_balloon_pci_info);
type_register_static(&virtio_serial_pci_info);
type_register_static(&virtio_net_pci_info);
+ type_register_static(&vhost_pci_net_pci_info);
#ifdef CONFIG_VHOST_SCSI
type_register_static(&vhost_scsi_pci_info);
#endif
@@ -25,6 +25,7 @@
#include "hw/virtio/virtio-bus.h"
#include "hw/virtio/virtio-input.h"
#include "hw/virtio/virtio-gpu.h"
+#include "hw/virtio/vhost-pci-net.h"
#ifdef CONFIG_VIRTFS
#include "hw/9pfs/virtio-9p.h"
#endif
@@ -44,6 +45,7 @@ typedef struct VirtIOInputPCI VirtIOInputPCI;
typedef struct VirtIOInputHIDPCI VirtIOInputHIDPCI;
typedef struct VirtIOInputHostPCI VirtIOInputHostPCI;
typedef struct VirtIOGPUPCI VirtIOGPUPCI;
+typedef struct VhostPCINetPCI VhostPCINetPCI;
/* virtio-pci-bus */
@@ -247,6 +249,18 @@ struct VirtIONetPCI {
};
/*
+ * vhost-pci-net-pci: This extends VirtioPCIProxy.
+ */
+#define TYPE_VHOST_PCI_NET_PCI "vhost-pci-net-pci"
+#define VHOST_PCI_NET_PCI(obj) \
+ OBJECT_CHECK(VhostPCINetPCI, (obj), TYPE_VHOST_PCI_NET_PCI)
+
+struct VhostPCINetPCI {
+ VirtIOPCIProxy parent_obj;
+ VhostPCINet vdev;
+};
+
+/*
* virtio-9p-pci: This extends VirtioPCIProxy.
*/
@@ -79,6 +79,7 @@
#define PCI_DEVICE_ID_VIRTIO_SCSI 0x1004
#define PCI_DEVICE_ID_VIRTIO_RNG 0x1005
#define PCI_DEVICE_ID_VIRTIO_9P 0x1009
+#define PCI_DEVICE_ID_VHOST_PCI_NET 0x1023
#define PCI_VENDOR_ID_REDHAT 0x1b36
#define PCI_DEVICE_ID_REDHAT_BRIDGE 0x0001
new file mode 100644
@@ -0,0 +1,39 @@
+/*
+ * Virtio Network Device
+ *
+ * Copyright Intel, Corp. 2016
+ *
+ * Authors:
+ * Wei Wang <wei.w.wang@intel.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef _QEMU_VHOST_PCI_NET_H
+#define _QEMU_VHOST_PCI_NET_H
+
+#include "standard-headers/linux/vhost_pci_net.h"
+#include "hw/virtio/virtio.h"
+#include "hw/virtio/vhost-pci-server.h"
+
+#define TYPE_VHOST_PCI_NET "vhost-pci-net-device"
+#define VHOST_PCI_NET(obj) \
+ OBJECT_CHECK(VhostPCINet, (obj), TYPE_VHOST_PCI_NET)
+
+typedef struct VhostPCINet {
+ VirtIODevice parent_obj;
+
+ VirtQueue *cvq_rx, *cvq_tx;
+ VirtQueue **rxqs;
+ uint64_t device_features;
+ size_t config_size;
+ uint16_t max_rxq_num;
+} VhostPCINet;
+
+void vhost_pci_net_set_max_rxqs(VhostPCINet *dev, uint16_t num);
+
+void vhost_pci_net_init_device_features(VhostPCINet *vpnet, uint64_t features);
+
+#endif
new file mode 100644
@@ -0,0 +1,45 @@
+#ifndef _LINUX_VHOST_PCI_NET_H
+#define _LINUX_VHOST_PCI_NET_H
+
+/* This header is BSD licensed so anyone can use the definitions to implement
+ * compatible drivers/servers.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Intel nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL Intel OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE. */
+#include "standard-headers/linux/types.h"
+#include "standard-headers/linux/virtio_ids.h"
+#include "standard-headers/linux/virtio_config.h"
+#include "standard-headers/linux/virtio_types.h"
+#include "standard-headers/linux/if_ether.h"
+
+struct vhost_pci_net_config {
+ /* Maximum number of receive queues;
+ * Should be equal to the number of the
+ * transmit queues of the peer device.
+ * Legal values are between 1 and 0x8000
+ */
+ uint16_t rq_num;
+} QEMU_PACKED;
+
+
+#endif
@@ -41,5 +41,6 @@
#define VIRTIO_ID_CAIF 12 /* Virtio caif */
#define VIRTIO_ID_GPU 16 /* virtio GPU */
#define VIRTIO_ID_INPUT 18 /* virtio input */
+#define VIRTIO_ID_VHOST_PCI_NET 0x23 /* vhost-pci-net */
#endif /* _LINUX_VIRTIO_IDS_H */
Signed-off-by: Wei Wang <wei.w.wang@intel.com> --- hw/net/Makefile.objs | 2 +- hw/net/vhost-pci-net.c | 142 +++++++++++++++++++++++++ hw/virtio/virtio-pci.c | 67 ++++++++++++ hw/virtio/virtio-pci.h | 14 +++ include/hw/pci/pci.h | 1 + include/hw/virtio/vhost-pci-net.h | 39 +++++++ include/standard-headers/linux/vhost_pci_net.h | 45 ++++++++ include/standard-headers/linux/virtio_ids.h | 1 + 8 files changed, 310 insertions(+), 1 deletion(-) create mode 100644 hw/net/vhost-pci-net.c create mode 100644 include/hw/virtio/vhost-pci-net.h create mode 100644 include/standard-headers/linux/vhost_pci_net.h