diff mbox

[RFC,3/4] vhost-pci-net device support

Message ID 1478746069-79574-4-git-send-email-wei.w.wang@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Wang, Wei W Nov. 10, 2016, 2:47 a.m. UTC
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
diff mbox

Patch

diff --git a/hw/net/Makefile.objs b/hw/net/Makefile.objs
index 610ed3e..71d6d2e 100644
--- a/hw/net/Makefile.objs
+++ b/hw/net/Makefile.objs
@@ -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 \
diff --git a/hw/net/vhost-pci-net.c b/hw/net/vhost-pci-net.c
new file mode 100644
index 0000000..3830caa
--- /dev/null
+++ b/hw/net/vhost-pci-net.c
@@ -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)
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 755f921..c4f6c72 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -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
diff --git a/hw/virtio/virtio-pci.h b/hw/virtio/virtio-pci.h
index 25fbf8a..0531b3f 100644
--- a/hw/virtio/virtio-pci.h
+++ b/hw/virtio/virtio-pci.h
@@ -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.
  */
 
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index 929ec2f..d25f031 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -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
diff --git a/include/hw/virtio/vhost-pci-net.h b/include/hw/virtio/vhost-pci-net.h
new file mode 100644
index 0000000..b5f59ee
--- /dev/null
+++ b/include/hw/virtio/vhost-pci-net.h
@@ -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
diff --git a/include/standard-headers/linux/vhost_pci_net.h b/include/standard-headers/linux/vhost_pci_net.h
new file mode 100644
index 0000000..8a92231
--- /dev/null
+++ b/include/standard-headers/linux/vhost_pci_net.h
@@ -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
diff --git a/include/standard-headers/linux/virtio_ids.h b/include/standard-headers/linux/virtio_ids.h
index 77925f5..48f896d 100644
--- a/include/standard-headers/linux/virtio_ids.h
+++ b/include/standard-headers/linux/virtio_ids.h
@@ -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 */