All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH for-2.8 0/2] vhost-vsock: add vhost-vsock device
@ 2016-08-16 12:27 Stefan Hajnoczi
  2016-08-16 12:27 ` [Qemu-devel] [PATCH for-2.8 1/2] linux-headers: add virtio vsock headers Stefan Hajnoczi
  2016-08-16 12:27 ` [Qemu-devel] [PATCH for-2.8 2/2] vhost-vsock: add virtio sockets device Stefan Hajnoczi
  0 siblings, 2 replies; 7+ messages in thread
From: Stefan Hajnoczi @ 2016-08-16 12:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Michael S. Tsirkin, Christoffer Dall, Alex Bennée,
	marius vlad, Claudio Imbrenda, Greg Kurz, Ian Campbell,
	Stefan Hajnoczi

This patch series adds -device vhost-vsock,guest-cid=<cid> to QEMU.  The vsock
device is a host-guest communications device comparable to virtio-serial except
it offers POSIX Sockets API semantics.

It uses the vhost_vsock.ko Linux kernel module for AF_VSOCK socket
communications.  The kernel module was merged for Linux 4.8 in commit
0803e04011c.  Host applications use regular POSIX Sockets API syscalls to
communicate with guests.

For more information, see http://qemu-project.org/Features/VirtioVsock.

Stefan Hajnoczi (2):
  linux-headers: add virtio vsock headers
  vhost-vsock: add virtio sockets device

 configure                                     |  10 +
 hw/s390x/virtio-ccw.c                         |  54 ++++
 hw/s390x/virtio-ccw.h                         |  15 +
 hw/virtio/Makefile.objs                       |   2 +
 hw/virtio/vhost-backend.c                     |  17 ++
 hw/virtio/vhost-vsock.c                       | 417 ++++++++++++++++++++++++++
 hw/virtio/virtio-pci.c                        |  51 ++++
 hw/virtio/virtio-pci.h                        |  18 ++
 include/hw/pci/pci.h                          |   1 +
 include/hw/virtio/vhost-backend.h             |   5 +
 include/hw/virtio/vhost-vsock.h               |  41 +++
 include/standard-headers/linux/virtio_ids.h   |   1 +
 include/standard-headers/linux/virtio_vsock.h |  94 ++++++
 linux-headers/linux/vhost.h                   |   5 +
 14 files changed, 731 insertions(+)
 create mode 100644 hw/virtio/vhost-vsock.c
 create mode 100644 include/hw/virtio/vhost-vsock.h
 create mode 100644 include/standard-headers/linux/virtio_vsock.h

-- 
2.7.4

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Qemu-devel] [PATCH for-2.8 1/2] linux-headers: add virtio vsock headers
  2016-08-16 12:27 [Qemu-devel] [PATCH for-2.8 0/2] vhost-vsock: add vhost-vsock device Stefan Hajnoczi
@ 2016-08-16 12:27 ` Stefan Hajnoczi
  2016-08-16 12:27 ` [Qemu-devel] [PATCH for-2.8 2/2] vhost-vsock: add virtio sockets device Stefan Hajnoczi
  1 sibling, 0 replies; 7+ messages in thread
From: Stefan Hajnoczi @ 2016-08-16 12:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Michael S. Tsirkin, Christoffer Dall, Alex Bennée,
	marius vlad, Claudio Imbrenda, Greg Kurz, Ian Campbell,
	Stefan Hajnoczi

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 include/standard-headers/linux/virtio_ids.h   |  1 +
 include/standard-headers/linux/virtio_vsock.h | 94 +++++++++++++++++++++++++++
 linux-headers/linux/vhost.h                   |  5 ++
 3 files changed, 100 insertions(+)
 create mode 100644 include/standard-headers/linux/virtio_vsock.h

diff --git a/include/standard-headers/linux/virtio_ids.h b/include/standard-headers/linux/virtio_ids.h
index 77925f5..3228d58 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_VSOCK        19 /* virtio vsock transport */
 
 #endif /* _LINUX_VIRTIO_IDS_H */
diff --git a/include/standard-headers/linux/virtio_vsock.h b/include/standard-headers/linux/virtio_vsock.h
new file mode 100644
index 0000000..be44321
--- /dev/null
+++ b/include/standard-headers/linux/virtio_vsock.h
@@ -0,0 +1,94 @@
+/*
+ * This header, excluding the #ifdef __KERNEL__ part, 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 IBM 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 IBM 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.
+ *
+ * Copyright (C) Red Hat, Inc., 2013-2015
+ * Copyright (C) Asias He <asias@redhat.com>, 2013
+ * Copyright (C) Stefan Hajnoczi <stefanha@redhat.com>, 2015
+ */
+
+#ifndef _LINUX_VIRTIO_VSOCK_H
+#define _LINUX_VIRTIO_VSOCK_H
+
+#include "standard-headers/linux/types.h"
+#include "standard-headers/linux/virtio_ids.h"
+#include "standard-headers/linux/virtio_config.h"
+
+struct virtio_vsock_config {
+	uint64_t guest_cid;
+} QEMU_PACKED;
+
+enum virtio_vsock_event_id {
+	VIRTIO_VSOCK_EVENT_TRANSPORT_RESET = 0,
+};
+
+struct virtio_vsock_event {
+	uint32_t id;
+} QEMU_PACKED;
+
+struct virtio_vsock_hdr {
+	uint64_t	src_cid;
+	uint64_t	dst_cid;
+	uint32_t	src_port;
+	uint32_t	dst_port;
+	uint32_t	len;
+	uint16_t	type;		/* enum virtio_vsock_type */
+	uint16_t	op;		/* enum virtio_vsock_op */
+	uint32_t	flags;
+	uint32_t	buf_alloc;
+	uint32_t	fwd_cnt;
+} QEMU_PACKED;
+
+enum virtio_vsock_type {
+	VIRTIO_VSOCK_TYPE_STREAM = 1,
+};
+
+enum virtio_vsock_op {
+	VIRTIO_VSOCK_OP_INVALID = 0,
+
+	/* Connect operations */
+	VIRTIO_VSOCK_OP_REQUEST = 1,
+	VIRTIO_VSOCK_OP_RESPONSE = 2,
+	VIRTIO_VSOCK_OP_RST = 3,
+	VIRTIO_VSOCK_OP_SHUTDOWN = 4,
+
+	/* To send payload */
+	VIRTIO_VSOCK_OP_RW = 5,
+
+	/* Tell the peer our credit info */
+	VIRTIO_VSOCK_OP_CREDIT_UPDATE = 6,
+	/* Request the peer to send the credit info to us */
+	VIRTIO_VSOCK_OP_CREDIT_REQUEST = 7,
+};
+
+/* VIRTIO_VSOCK_OP_SHUTDOWN flags values */
+enum virtio_vsock_shutdown {
+	VIRTIO_VSOCK_SHUTDOWN_RCV = 1,
+	VIRTIO_VSOCK_SHUTDOWN_SEND = 2,
+};
+
+#endif /* _LINUX_VIRTIO_VSOCK_H */
diff --git a/linux-headers/linux/vhost.h b/linux-headers/linux/vhost.h
index 571294c..81df17b 100644
--- a/linux-headers/linux/vhost.h
+++ b/linux-headers/linux/vhost.h
@@ -175,4 +175,9 @@ struct vhost_scsi_target {
 #define VHOST_SCSI_SET_EVENTS_MISSED _IOW(VHOST_VIRTIO, 0x43, __u32)
 #define VHOST_SCSI_GET_EVENTS_MISSED _IOW(VHOST_VIRTIO, 0x44, __u32)
 
+/* VHOST_VSOCK specific defines */
+
+#define VHOST_VSOCK_SET_GUEST_CID	_IOW(VHOST_VIRTIO, 0x60, __u64)
+#define VHOST_VSOCK_SET_RUNNING		_IOW(VHOST_VIRTIO, 0x61, int)
+
 #endif
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [Qemu-devel] [PATCH for-2.8 2/2] vhost-vsock: add virtio sockets device
  2016-08-16 12:27 [Qemu-devel] [PATCH for-2.8 0/2] vhost-vsock: add vhost-vsock device Stefan Hajnoczi
  2016-08-16 12:27 ` [Qemu-devel] [PATCH for-2.8 1/2] linux-headers: add virtio vsock headers Stefan Hajnoczi
@ 2016-08-16 12:27 ` Stefan Hajnoczi
  2016-08-23 17:45   ` Claudio Imbrenda
  2016-09-09 21:07   ` Michael S. Tsirkin
  1 sibling, 2 replies; 7+ messages in thread
From: Stefan Hajnoczi @ 2016-08-16 12:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Michael S. Tsirkin, Christoffer Dall, Alex Bennée,
	marius vlad, Claudio Imbrenda, Greg Kurz, Ian Campbell,
	Stefan Hajnoczi

Implement the new virtio sockets device for host<->guest communication
using the Sockets API.  Most of the work is done in a vhost kernel
driver so that virtio-vsock can hook into the AF_VSOCK address family.
The QEMU vhost-vsock device handles configuration and live migration
while the rx/tx happens in the vhost_vsock.ko Linux kernel driver.

The vsock device must be given a CID (host-wide unique address):

  # qemu -device vhost-vsock-pci,id=vhost-vsock-pci0,guest-cid=3 ...

For more information see:
http://qemu-project.org/Features/VirtioVsock

[Endianness fixes and virtio-ccw support by Claudio Imbrenda
<imbrenda@linux.vnet.ibm.com>]

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 configure                         |  10 +
 hw/s390x/virtio-ccw.c             |  54 +++++
 hw/s390x/virtio-ccw.h             |  15 ++
 hw/virtio/Makefile.objs           |   2 +
 hw/virtio/vhost-backend.c         |  17 ++
 hw/virtio/vhost-vsock.c           | 417 ++++++++++++++++++++++++++++++++++++++
 hw/virtio/virtio-pci.c            |  51 +++++
 hw/virtio/virtio-pci.h            |  18 ++
 include/hw/pci/pci.h              |   1 +
 include/hw/virtio/vhost-backend.h |   5 +
 include/hw/virtio/vhost-vsock.h   |  41 ++++
 11 files changed, 631 insertions(+)
 create mode 100644 hw/virtio/vhost-vsock.c
 create mode 100644 include/hw/virtio/vhost-vsock.h

diff --git a/configure b/configure
index 4b808f9..a71ad4c 100755
--- a/configure
+++ b/configure
@@ -229,6 +229,7 @@ xfs=""
 
 vhost_net="no"
 vhost_scsi="no"
+vhost_vsock="no"
 kvm="no"
 rdma=""
 gprof="no"
@@ -674,6 +675,7 @@ Haiku)
   kvm="yes"
   vhost_net="yes"
   vhost_scsi="yes"
+  vhost_vsock="yes"
   QEMU_INCLUDES="-I\$(SRC_PATH)/linux-headers -I$(pwd)/linux-headers $QEMU_INCLUDES"
 ;;
 esac
@@ -1017,6 +1019,10 @@ for opt do
   ;;
   --enable-vhost-scsi) vhost_scsi="yes"
   ;;
+  --disable-vhost-vsock) vhost_vsock="no"
+  ;;
+  --enable-vhost-vsock) vhost_vsock="yes"
+  ;;
   --disable-opengl) opengl="no"
   ;;
   --enable-opengl) opengl="yes"
@@ -4871,6 +4877,7 @@ echo "uuid support      $uuid"
 echo "libcap-ng support $cap_ng"
 echo "vhost-net support $vhost_net"
 echo "vhost-scsi support $vhost_scsi"
+echo "vhost-vsock support $vhost_vsock"
 echo "Trace backends    $trace_backends"
 if have_backend "simple"; then
 echo "Trace output file $trace_file-<pid>"
@@ -5252,6 +5259,9 @@ fi
 if test "$vhost_net" = "yes" ; then
   echo "CONFIG_VHOST_NET_USED=y" >> $config_host_mak
 fi
+if test "$vhost_vsock" = "yes" ; then
+  echo "CONFIG_VHOST_VSOCK=y" >> $config_host_mak
+fi
 if test "$blobs" = "yes" ; then
   echo "INSTALL_BLOBS=yes" >> $config_host_mak
 fi
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index a554a24..bd5475a 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -1658,6 +1658,57 @@ static const TypeInfo virtio_ccw_9p_info = {
 };
 #endif
 
+#ifdef CONFIG_VHOST_VSOCK
+
+static Property vhost_vsock_ccw_properties[] = {
+    DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
+    DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev,
+                       VIRTIO_CCW_MAX_REV),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void vhost_vsock_ccw_realize(VirtioCcwDevice *ccw_dev, Error **errp)
+{
+    VHostVSockCCWState *dev = VHOST_VSOCK_CCW(ccw_dev);
+    DeviceState *vdev = DEVICE(&dev->vdev);
+    Error *err = NULL;
+
+    qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus));
+    object_property_set_bool(OBJECT(vdev), true, "realized", &err);
+    if (err) {
+        error_propagate(errp, err);
+    }
+}
+
+static void vhost_vsock_ccw_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
+
+    k->realize = vhost_vsock_ccw_realize;
+    k->exit = virtio_ccw_exit;
+    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+    dc->props = vhost_vsock_ccw_properties;
+    dc->reset = virtio_ccw_reset;
+}
+
+static void vhost_vsock_ccw_instance_init(Object *obj)
+{
+    VHostVSockCCWState *dev = VHOST_VSOCK_CCW(obj);
+
+    virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
+                                TYPE_VHOST_VSOCK);
+}
+
+static const TypeInfo vhost_vsock_ccw_info = {
+    .name          = TYPE_VHOST_VSOCK_CCW,
+    .parent        = TYPE_VIRTIO_CCW_DEVICE,
+    .instance_size = sizeof(VHostVSockCCWState),
+    .instance_init = vhost_vsock_ccw_instance_init,
+    .class_init    = vhost_vsock_ccw_class_init,
+};
+#endif
+
 static void virtio_ccw_register(void)
 {
     type_register_static(&virtio_ccw_bus_info);
@@ -1674,6 +1725,9 @@ static void virtio_ccw_register(void)
 #ifdef CONFIG_VIRTFS
     type_register_static(&virtio_ccw_9p_info);
 #endif
+#ifdef CONFIG_VHOST_VSOCK
+    type_register_static(&vhost_vsock_ccw_info);
+#endif
 }
 
 type_init(virtio_ccw_register)
diff --git a/hw/s390x/virtio-ccw.h b/hw/s390x/virtio-ccw.h
index 1c6bc86..904e357 100644
--- a/hw/s390x/virtio-ccw.h
+++ b/hw/s390x/virtio-ccw.h
@@ -23,6 +23,9 @@
 #include "hw/virtio/virtio-balloon.h"
 #include "hw/virtio/virtio-rng.h"
 #include "hw/virtio/virtio-bus.h"
+#ifdef CONFIG_VHOST_VSOCK
+#include "hw/virtio/vhost-vsock.h"
+#endif /* CONFIG_VHOST_VSOCK */
 
 #include "hw/s390x/s390_flic.h"
 #include "hw/s390x/css.h"
@@ -197,4 +200,16 @@ typedef struct V9fsCCWState {
 
 #endif /* CONFIG_VIRTFS */
 
+#ifdef CONFIG_VHOST_VSOCK
+#define TYPE_VHOST_VSOCK_CCW "vhost-vsock-ccw"
+#define VHOST_VSOCK_CCW(obj) \
+    OBJECT_CHECK(VHostVSockCCWState, (obj), TYPE_VHOST_VSOCK_CCW)
+
+typedef struct VHostVSockCCWState {
+    VirtioCcwDevice parent_obj;
+    VHostVSock vdev;
+} VHostVSockCCWState;
+
+#endif /* CONFIG_VHOST_VSOCK */
+
 #endif
diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs
index 3e2b175..e716308 100644
--- a/hw/virtio/Makefile.objs
+++ b/hw/virtio/Makefile.objs
@@ -5,3 +5,5 @@ common-obj-y += virtio-mmio.o
 
 obj-y += virtio.o virtio-balloon.o 
 obj-$(CONFIG_LINUX) += vhost.o vhost-backend.o vhost-user.o
+
+obj-$(CONFIG_VHOST_VSOCK) += vhost-vsock.o
diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c
index 7681f15..272a5ec 100644
--- a/hw/virtio/vhost-backend.c
+++ b/hw/virtio/vhost-backend.c
@@ -172,6 +172,19 @@ static int vhost_kernel_get_vq_index(struct vhost_dev *dev, int idx)
     return idx - dev->vq_index;
 }
 
+#ifdef CONFIG_VHOST_VSOCK
+static int vhost_kernel_vsock_set_guest_cid(struct vhost_dev *dev,
+                                            uint64_t guest_cid)
+{
+    return vhost_kernel_call(dev, VHOST_VSOCK_SET_GUEST_CID, &guest_cid);
+}
+
+static int vhost_kernel_vsock_set_running(struct vhost_dev *dev, int start)
+{
+    return vhost_kernel_call(dev, VHOST_VSOCK_SET_RUNNING, &start);
+}
+#endif /* CONFIG_VHOST_VSOCK */
+
 static const VhostOps kernel_ops = {
         .backend_type = VHOST_BACKEND_TYPE_KERNEL,
         .vhost_backend_init = vhost_kernel_init,
@@ -197,6 +210,10 @@ static const VhostOps kernel_ops = {
         .vhost_set_owner = vhost_kernel_set_owner,
         .vhost_reset_device = vhost_kernel_reset_device,
         .vhost_get_vq_index = vhost_kernel_get_vq_index,
+#ifdef CONFIG_VHOST_VSOCK
+        .vhost_vsock_set_guest_cid = vhost_kernel_vsock_set_guest_cid,
+        .vhost_vsock_set_running = vhost_kernel_vsock_set_running,
+#endif /* CONFIG_VHOST_VSOCK */
 };
 
 int vhost_set_backend_type(struct vhost_dev *dev, VhostBackendType backend_type)
diff --git a/hw/virtio/vhost-vsock.c b/hw/virtio/vhost-vsock.c
new file mode 100644
index 0000000..bde2456
--- /dev/null
+++ b/hw/virtio/vhost-vsock.c
@@ -0,0 +1,417 @@
+/*
+ * Virtio vsock device
+ *
+ * Copyright 2015 Red Hat, Inc.
+ *
+ * Authors:
+ *  Stefan Hajnoczi <stefanha@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * (at your option) any later version.  See the COPYING file in the
+ * top-level directory.
+ */
+
+#include <sys/ioctl.h>
+#include "qemu/osdep.h"
+#include "standard-headers/linux/virtio_vsock.h"
+#include "qapi/error.h"
+#include "hw/virtio/virtio-bus.h"
+#include "hw/virtio/virtio-access.h"
+#include "migration/migration.h"
+#include "qemu/error-report.h"
+#include "hw/virtio/vhost-vsock.h"
+#include "qemu/iov.h"
+#include "monitor/monitor.h"
+
+enum {
+    VHOST_VSOCK_SAVEVM_VERSION = 0,
+
+    VHOST_VSOCK_QUEUE_SIZE = 128,
+};
+
+static void vhost_vsock_get_config(VirtIODevice *vdev, uint8_t *config)
+{
+    VHostVSock *vsock = VHOST_VSOCK(vdev);
+    struct virtio_vsock_config vsockcfg = {};
+
+    virtio_stq_p(vdev, &vsockcfg.guest_cid, vsock->conf.guest_cid);
+    memcpy(config, &vsockcfg, sizeof(vsockcfg));
+}
+
+static int vhost_vsock_set_guest_cid(VHostVSock *vsock)
+{
+    const VhostOps *vhost_ops = vsock->vhost_dev.vhost_ops;
+    int ret;
+
+    if (!vhost_ops->vhost_vsock_set_guest_cid) {
+        return -ENOSYS;
+    }
+
+    ret = vhost_ops->vhost_vsock_set_guest_cid(&vsock->vhost_dev,
+                                               vsock->conf.guest_cid);
+    if (ret < 0) {
+        return -errno;
+    }
+    return 0;
+}
+
+static int vhost_vsock_set_running(VHostVSock *vsock, int start)
+{
+    const VhostOps *vhost_ops = vsock->vhost_dev.vhost_ops;
+    int ret;
+
+    if (!vhost_ops->vhost_vsock_set_running) {
+        return -ENOSYS;
+    }
+
+    ret = vhost_ops->vhost_vsock_set_running(&vsock->vhost_dev, start);
+    if (ret < 0) {
+        return -errno;
+    }
+    return 0;
+}
+
+static void vhost_vsock_start(VirtIODevice *vdev)
+{
+    VHostVSock *vsock = VHOST_VSOCK(vdev);
+    BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
+    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
+    int ret;
+    int i;
+
+    if (!k->set_guest_notifiers) {
+        error_report("binding does not support guest notifiers");
+        return;
+    }
+
+    ret = vhost_dev_enable_notifiers(&vsock->vhost_dev, vdev);
+    if (ret < 0) {
+        error_report("Error enabling host notifiers: %d", -ret);
+        return;
+    }
+
+    ret = k->set_guest_notifiers(qbus->parent, vsock->vhost_dev.nvqs, true);
+    if (ret < 0) {
+        error_report("Error binding guest notifier: %d", -ret);
+        goto err_host_notifiers;
+    }
+
+    vsock->vhost_dev.acked_features = vdev->guest_features;
+    ret = vhost_dev_start(&vsock->vhost_dev, vdev);
+    if (ret < 0) {
+        error_report("Error starting vhost: %d", -ret);
+        goto err_guest_notifiers;
+    }
+
+    ret = vhost_vsock_set_running(vsock, 1);
+    if (ret < 0) {
+        error_report("Error starting vhost vsock: %d", -ret);
+        goto err_dev_start;
+    }
+
+    /* guest_notifier_mask/pending not used yet, so just unmask
+     * everything here.  virtio-pci will do the right thing by
+     * enabling/disabling irqfd.
+     */
+    for (i = 0; i < vsock->vhost_dev.nvqs; i++) {
+        vhost_virtqueue_mask(&vsock->vhost_dev, vdev, i, false);
+    }
+
+    return;
+
+err_dev_start:
+    vhost_dev_stop(&vsock->vhost_dev, vdev);
+err_guest_notifiers:
+    k->set_guest_notifiers(qbus->parent, vsock->vhost_dev.nvqs, false);
+err_host_notifiers:
+    vhost_dev_disable_notifiers(&vsock->vhost_dev, vdev);
+}
+
+static void vhost_vsock_stop(VirtIODevice *vdev)
+{
+    VHostVSock *vsock = VHOST_VSOCK(vdev);
+    BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
+    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
+    int ret;
+
+    if (!k->set_guest_notifiers) {
+        return;
+    }
+
+    ret = vhost_vsock_set_running(vsock, 0);
+    if (ret < 0) {
+        error_report("vhost vsock set running failed: %d", ret);
+        return;
+    }
+
+    vhost_dev_stop(&vsock->vhost_dev, vdev);
+
+    ret = k->set_guest_notifiers(qbus->parent, vsock->vhost_dev.nvqs, false);
+    if (ret < 0) {
+        error_report("vhost guest notifier cleanup failed: %d", ret);
+        return;
+    }
+
+    vhost_dev_disable_notifiers(&vsock->vhost_dev, vdev);
+}
+
+static void vhost_vsock_set_status(VirtIODevice *vdev, uint8_t status)
+{
+    VHostVSock *vsock = VHOST_VSOCK(vdev);
+    bool should_start = status & VIRTIO_CONFIG_S_DRIVER_OK;
+
+    if (!vdev->vm_running) {
+        should_start = false;
+    }
+
+    if (vsock->vhost_dev.started == should_start) {
+        return;
+    }
+
+    if (should_start) {
+        vhost_vsock_start(vdev);
+    } else {
+        vhost_vsock_stop(vdev);
+    }
+}
+
+static uint64_t vhost_vsock_get_features(VirtIODevice *vdev,
+                                         uint64_t requested_features,
+                                         Error **errp)
+{
+    /* No feature bits used yet */
+    return requested_features;
+}
+
+static void vhost_vsock_handle_output(VirtIODevice *vdev, VirtQueue *vq)
+{
+    /* Do nothing */
+}
+
+static void vhost_vsock_guest_notifier_mask(VirtIODevice *vdev, int idx,
+                                            bool mask)
+{
+    VHostVSock *vsock = VHOST_VSOCK(vdev);
+
+    vhost_virtqueue_mask(&vsock->vhost_dev, vdev, idx, mask);
+}
+
+static bool vhost_vsock_guest_notifier_pending(VirtIODevice *vdev, int idx)
+{
+    VHostVSock *vsock = VHOST_VSOCK(vdev);
+
+    return vhost_virtqueue_pending(&vsock->vhost_dev, idx);
+}
+
+static void vhost_vsock_send_transport_reset(VHostVSock *vsock)
+{
+    VirtQueueElement *elem;
+    VirtQueue *vq = vsock->event_vq;
+    struct virtio_vsock_event event = {
+        .id = cpu_to_le32(VIRTIO_VSOCK_EVENT_TRANSPORT_RESET),
+    };
+
+    elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
+    if (!elem) {
+        error_report("vhost-vsock missed transport reset event");
+        return;
+    }
+
+    if (elem->out_num) {
+        error_report("invalid vhost-vsock event virtqueue element with "
+                     "out buffers");
+        goto out;
+    }
+
+    if (iov_from_buf(elem->in_sg, elem->in_num, 0,
+                     &event, sizeof(event)) != sizeof(event)) {
+        error_report("vhost-vsock event virtqueue element is too short");
+        goto out;
+    }
+
+    virtqueue_push(vq, elem, sizeof(event));
+    virtio_notify(VIRTIO_DEVICE(vsock), vq);
+
+out:
+    g_free(elem);
+}
+
+static void vhost_vsock_save(QEMUFile *f, void *opaque, size_t size)
+{
+    VHostVSock *vsock = opaque;
+    VirtIODevice *vdev = VIRTIO_DEVICE(vsock);
+
+    /* At this point, backend must be stopped, otherwise
+     * it might keep writing to memory. */
+    assert(!vsock->vhost_dev.started);
+    virtio_save(vdev, f);
+}
+
+static void vhost_vsock_post_load_timer_cleanup(VHostVSock *vsock)
+{
+    if (!vsock->post_load_timer) {
+        return;
+    }
+
+    timer_del(vsock->post_load_timer);
+    timer_free(vsock->post_load_timer);
+    vsock->post_load_timer = NULL;
+}
+
+static void vhost_vsock_post_load_timer_cb(void *opaque)
+{
+    VHostVSock *vsock = opaque;
+
+    vhost_vsock_post_load_timer_cleanup(vsock);
+    vhost_vsock_send_transport_reset(vsock);
+}
+
+static int vhost_vsock_load(QEMUFile *f, void *opaque, size_t size)
+{
+    VHostVSock *vsock = opaque;
+    VirtIODevice *vdev = VIRTIO_DEVICE(vsock);
+    int ret;
+
+    ret = virtio_load(vdev, f, VHOST_VSOCK_SAVEVM_VERSION);
+    if (ret) {
+        return ret;
+    }
+
+    if (virtio_queue_get_addr(vdev, 2)) {
+        /* Defer transport reset event to a vm clock timer so that virtqueue
+         * changes happen after migration has completed.
+         */
+        assert(!vsock->post_load_timer);
+        vsock->post_load_timer =
+            timer_new_ns(QEMU_CLOCK_VIRTUAL,
+                         vhost_vsock_post_load_timer_cb,
+                         vsock);
+        timer_mod(vsock->post_load_timer, 1);
+    }
+
+    return 0;
+}
+
+VMSTATE_VIRTIO_DEVICE(vhost_vsock, VHOST_VSOCK_SAVEVM_VERSION,
+                      vhost_vsock_load, vhost_vsock_save);
+
+static void vhost_vsock_device_realize(DeviceState *dev, Error **errp)
+{
+    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+    VHostVSock *vsock = VHOST_VSOCK(dev);
+    int vhostfd;
+    int ret;
+
+    /* Refuse to use reserved CID numbers */
+    if (vsock->conf.guest_cid <= 2) {
+        error_setg(errp, "guest-cid property must be greater than 2");
+        return;
+    }
+
+    if (vsock->conf.guest_cid > UINT32_MAX) {
+        error_setg(errp, "guest-cid property must be a 32-bit number");
+        return;
+    }
+
+    if (vsock->conf.vhostfd) {
+        vhostfd = monitor_fd_param(cur_mon, vsock->conf.vhostfd, errp);
+        if (vhostfd == -1) {
+            error_prepend(errp, "vhost-vsock: unable to parse vhostfd: ");
+            return;
+        }
+    } else {
+        vhostfd = open("/dev/vhost-vsock", O_RDWR);
+        if (vhostfd < 0) {
+            error_setg_errno(errp, -errno,
+                             "vhost-vsock: failed to open vhost device");
+            return;
+        }
+    }
+
+    virtio_init(vdev, "vhost-vsock", VIRTIO_ID_VSOCK,
+                sizeof(struct virtio_vsock_config));
+
+    /* Receive and transmit queues belong to vhost */
+    virtio_add_queue(vdev, VHOST_VSOCK_QUEUE_SIZE, vhost_vsock_handle_output);
+    virtio_add_queue(vdev, VHOST_VSOCK_QUEUE_SIZE, vhost_vsock_handle_output);
+
+    /* The event queue belongs to QEMU */
+    vsock->event_vq = virtio_add_queue(vdev, VHOST_VSOCK_QUEUE_SIZE,
+                                       vhost_vsock_handle_output);
+
+    vsock->vhost_dev.nvqs = ARRAY_SIZE(vsock->vhost_vqs);
+    vsock->vhost_dev.vqs = vsock->vhost_vqs;
+    ret = vhost_dev_init(&vsock->vhost_dev, (void *)(uintptr_t)vhostfd,
+                         VHOST_BACKEND_TYPE_KERNEL, 0);
+    if (ret < 0) {
+        error_setg_errno(errp, -ret, "vhost-vsock: vhost_dev_init failed");
+        goto err_virtio;
+    }
+
+    ret = vhost_vsock_set_guest_cid(vsock);
+    if (ret < 0) {
+        error_setg_errno(errp, -ret, "vhost-vsock: unable to set guest cid");
+        goto err_vhost_dev;
+    }
+
+    vsock->post_load_timer = NULL;
+    return;
+
+err_vhost_dev:
+    vhost_dev_cleanup(&vsock->vhost_dev);
+err_virtio:
+    virtio_cleanup(vdev);
+    close(vhostfd);
+    return;
+}
+
+static void vhost_vsock_device_unrealize(DeviceState *dev, Error **errp)
+{
+    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+    VHostVSock *vsock = VHOST_VSOCK(dev);
+
+    vhost_vsock_post_load_timer_cleanup(vsock);
+
+    /* This will stop vhost backend if appropriate. */
+    vhost_vsock_set_status(vdev, 0);
+
+    vhost_dev_cleanup(&vsock->vhost_dev);
+    virtio_cleanup(vdev);
+}
+
+static Property vhost_vsock_properties[] = {
+    DEFINE_PROP_UINT64("guest-cid", VHostVSock, conf.guest_cid, 0),
+    DEFINE_PROP_STRING("vhostfd", VHostVSock, conf.vhostfd),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void vhost_vsock_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+
+    dc->props = vhost_vsock_properties;
+    dc->vmsd = &vmstate_virtio_vhost_vsock;
+    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+    vdc->realize = vhost_vsock_device_realize;
+    vdc->unrealize = vhost_vsock_device_unrealize;
+    vdc->get_features = vhost_vsock_get_features;
+    vdc->get_config = vhost_vsock_get_config;
+    vdc->set_status = vhost_vsock_set_status;
+    vdc->guest_notifier_mask = vhost_vsock_guest_notifier_mask;
+    vdc->guest_notifier_pending = vhost_vsock_guest_notifier_pending;
+}
+
+static const TypeInfo vhost_vsock_info = {
+    .name = TYPE_VHOST_VSOCK,
+    .parent = TYPE_VIRTIO_DEVICE,
+    .instance_size = sizeof(VHostVSock),
+    .class_init = vhost_vsock_class_init,
+};
+
+static void vhost_vsock_register_types(void)
+{
+    type_register_static(&vhost_vsock_info);
+}
+
+type_init(vhost_vsock_register_types)
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 755f921..ac42c54 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -2055,6 +2055,54 @@ static const TypeInfo vhost_scsi_pci_info = {
 };
 #endif
 
+/* vhost-vsock-pci */
+
+#ifdef CONFIG_VHOST_VSOCK
+static Property vhost_vsock_pci_properties[] = {
+    DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 3),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void vhost_vsock_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
+{
+    VHostVSockPCI *dev = VHOST_VSOCK_PCI(vpci_dev);
+    DeviceState *vdev = DEVICE(&dev->vdev);
+
+    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
+    object_property_set_bool(OBJECT(vdev), true, "realized", errp);
+}
+
+static void vhost_vsock_pci_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
+    PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
+    k->realize = vhost_vsock_pci_realize;
+    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+    dc->props = vhost_vsock_pci_properties;
+    pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+    pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_VSOCK;
+    pcidev_k->revision = 0x00;
+    pcidev_k->class_id = PCI_CLASS_COMMUNICATION_OTHER;
+}
+
+static void vhost_vsock_pci_instance_init(Object *obj)
+{
+    VHostVSockPCI *dev = VHOST_VSOCK_PCI(obj);
+
+    virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
+                                TYPE_VHOST_VSOCK);
+}
+
+static const TypeInfo vhost_vsock_pci_info = {
+    .name          = TYPE_VHOST_VSOCK_PCI,
+    .parent        = TYPE_VIRTIO_PCI,
+    .instance_size = sizeof(VHostVSockPCI),
+    .instance_init = vhost_vsock_pci_instance_init,
+    .class_init    = vhost_vsock_pci_class_init,
+};
+#endif
+
 /* virtio-balloon-pci */
 
 static Property virtio_balloon_pci_properties[] = {
@@ -2485,6 +2533,9 @@ static void virtio_pci_register_types(void)
 #ifdef CONFIG_VHOST_SCSI
     type_register_static(&vhost_scsi_pci_info);
 #endif
+#ifdef CONFIG_VHOST_VSOCK
+    type_register_static(&vhost_vsock_pci_info);
+#endif
 }
 
 type_init(virtio_pci_register_types)
diff --git a/hw/virtio/virtio-pci.h b/hw/virtio/virtio-pci.h
index 25fbf8a..efd27f7 100644
--- a/hw/virtio/virtio-pci.h
+++ b/hw/virtio/virtio-pci.h
@@ -31,6 +31,9 @@
 #ifdef CONFIG_VHOST_SCSI
 #include "hw/virtio/vhost-scsi.h"
 #endif
+#ifdef CONFIG_VHOST_VSOCK
+#include "hw/virtio/vhost-vsock.h"
+#endif
 
 typedef struct VirtIOPCIProxy VirtIOPCIProxy;
 typedef struct VirtIOBlkPCI VirtIOBlkPCI;
@@ -44,6 +47,7 @@ typedef struct VirtIOInputPCI VirtIOInputPCI;
 typedef struct VirtIOInputHIDPCI VirtIOInputHIDPCI;
 typedef struct VirtIOInputHostPCI VirtIOInputHostPCI;
 typedef struct VirtIOGPUPCI VirtIOGPUPCI;
+typedef struct VHostVSockPCI VHostVSockPCI;
 
 /* virtio-pci-bus */
 
@@ -324,6 +328,20 @@ struct VirtIOGPUPCI {
     VirtIOGPU vdev;
 };
 
+#ifdef CONFIG_VHOST_VSOCK
+/*
+ * vhost-vsock-pci: This extends VirtioPCIProxy.
+ */
+#define TYPE_VHOST_VSOCK_PCI "vhost-vsock-pci"
+#define VHOST_VSOCK_PCI(obj) \
+        OBJECT_CHECK(VHostVSockPCI, (obj), TYPE_VHOST_VSOCK_PCI)
+
+struct VHostVSockPCI {
+    VirtIOPCIProxy parent_obj;
+    VHostVSock vdev;
+};
+#endif
+
 /* Virtio ABI version, if we increment this, we break the guest driver. */
 #define VIRTIO_PCI_ABI_VERSION          0
 
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index 929ec2f..e8b83bb 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_VIRTIO_VSOCK       0x1012
 
 #define PCI_VENDOR_ID_REDHAT             0x1b36
 #define PCI_DEVICE_ID_REDHAT_BRIDGE      0x0001
diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h
index cf7f0b5..6e90703 100644
--- a/include/hw/virtio/vhost-backend.h
+++ b/include/hw/virtio/vhost-backend.h
@@ -73,6 +73,9 @@ typedef int (*vhost_migration_done_op)(struct vhost_dev *dev,
 typedef bool (*vhost_backend_can_merge_op)(struct vhost_dev *dev,
                                            uint64_t start1, uint64_t size1,
                                            uint64_t start2, uint64_t size2);
+typedef int (*vhost_vsock_set_guest_cid_op)(struct vhost_dev *dev,
+                                            uint64_t guest_cid);
+typedef int (*vhost_vsock_set_running_op)(struct vhost_dev *dev, int start);
 
 typedef struct VhostOps {
     VhostBackendType backend_type;
@@ -102,6 +105,8 @@ typedef struct VhostOps {
     vhost_requires_shm_log_op vhost_requires_shm_log;
     vhost_migration_done_op vhost_migration_done;
     vhost_backend_can_merge_op vhost_backend_can_merge;
+    vhost_vsock_set_guest_cid_op vhost_vsock_set_guest_cid;
+    vhost_vsock_set_running_op vhost_vsock_set_running;
 } VhostOps;
 
 extern const VhostOps user_ops;
diff --git a/include/hw/virtio/vhost-vsock.h b/include/hw/virtio/vhost-vsock.h
new file mode 100644
index 0000000..7b9205f
--- /dev/null
+++ b/include/hw/virtio/vhost-vsock.h
@@ -0,0 +1,41 @@
+/*
+ * Vhost vsock virtio device
+ *
+ * Copyright 2015 Red Hat, Inc.
+ *
+ * Authors:
+ *  Stefan Hajnoczi <stefanha@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * (at your option) any later version.  See the COPYING file in the
+ * top-level directory.
+ */
+
+#ifndef _QEMU_VHOST_VSOCK_H
+#define _QEMU_VHOST_VSOCK_H
+
+#include "hw/virtio/virtio.h"
+#include "hw/virtio/vhost.h"
+
+#define TYPE_VHOST_VSOCK "vhost-vsock-device"
+#define VHOST_VSOCK(obj) \
+        OBJECT_CHECK(VHostVSock, (obj), TYPE_VHOST_VSOCK)
+
+typedef struct {
+    uint64_t guest_cid;
+    char *vhostfd;
+} VHostVSockConf;
+
+typedef struct {
+    /*< private >*/
+    VirtIODevice parent;
+    VHostVSockConf conf;
+    struct vhost_virtqueue vhost_vqs[2];
+    struct vhost_dev vhost_dev;
+    VirtQueue *event_vq;
+    QEMUTimer *post_load_timer;
+
+    /*< public >*/
+} VHostVSock;
+
+#endif /* _QEMU_VHOST_VSOCK_H */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [Qemu-devel] [PATCH for-2.8 2/2] vhost-vsock: add virtio sockets device
  2016-08-16 12:27 ` [Qemu-devel] [PATCH for-2.8 2/2] vhost-vsock: add virtio sockets device Stefan Hajnoczi
@ 2016-08-23 17:45   ` Claudio Imbrenda
  2016-08-24 16:00     ` Cornelia Huck
  2016-09-09 21:07   ` Michael S. Tsirkin
  1 sibling, 1 reply; 7+ messages in thread
From: Claudio Imbrenda @ 2016-08-23 17:45 UTC (permalink / raw)
  To: Stefan Hajnoczi, qemu-devel
  Cc: Michael S. Tsirkin, Christoffer Dall, Alex Bennée,
	marius vlad, Greg Kurz, Ian Campbell

Hi Stefan!

I tried it on s390x and... it doesn't compile :(
Something has been changed somewhere behind our backs, and you need to 
change this line to get it to compile again:

--- virtio-ccw.c~       2016-08-23 16:37:14.000000000 +0200
+++ virtio-ccw.c        2016-08-23 16:41:10.587853314 +0200
@@ -1661,7 +1661,7 @@
  #ifdef CONFIG_VHOST_VSOCK

  static Property vhost_vsock_ccw_properties[] = {
-    DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
+    DEFINE_PROP_CSS_DEV_ID("devno", VirtioCcwDevice, parent_obj.bus_id),
      DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev,
                         VIRTIO_CCW_MAX_REV),
      DEFINE_PROP_END_OF_LIST(),



also, using the nc-vsock utility, I noticed that the only possible way 
to get it to work is for connections from the host to the guest. Is that 
intended? IIRC (and according to the changelog of the kernel patch) we 
wanted guest -> host to be also possible?


thanks!


Claudio Imbrenda



On 16/08/16 14:27, Stefan Hajnoczi wrote:
> Implement the new virtio sockets device for host<->guest communication
> using the Sockets API.  Most of the work is done in a vhost kernel
> driver so that virtio-vsock can hook into the AF_VSOCK address family.
> The QEMU vhost-vsock device handles configuration and live migration
> while the rx/tx happens in the vhost_vsock.ko Linux kernel driver.
>
> The vsock device must be given a CID (host-wide unique address):
>
>   # qemu -device vhost-vsock-pci,id=vhost-vsock-pci0,guest-cid=3 ...
>
> For more information see:
> http://qemu-project.org/Features/VirtioVsock
>
> [Endianness fixes and virtio-ccw support by Claudio Imbrenda
> <imbrenda@linux.vnet.ibm.com>]
>
> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
> ---
>  configure                         |  10 +
>  hw/s390x/virtio-ccw.c             |  54 +++++
>  hw/s390x/virtio-ccw.h             |  15 ++
>  hw/virtio/Makefile.objs           |   2 +
>  hw/virtio/vhost-backend.c         |  17 ++
>  hw/virtio/vhost-vsock.c           | 417 ++++++++++++++++++++++++++++++++++++++
>  hw/virtio/virtio-pci.c            |  51 +++++
>  hw/virtio/virtio-pci.h            |  18 ++
>  include/hw/pci/pci.h              |   1 +
>  include/hw/virtio/vhost-backend.h |   5 +
>  include/hw/virtio/vhost-vsock.h   |  41 ++++
>  11 files changed, 631 insertions(+)
>  create mode 100644 hw/virtio/vhost-vsock.c
>  create mode 100644 include/hw/virtio/vhost-vsock.h
>
> diff --git a/configure b/configure
> index 4b808f9..a71ad4c 100755
> --- a/configure
> +++ b/configure
> @@ -229,6 +229,7 @@ xfs=""
>
>  vhost_net="no"
>  vhost_scsi="no"
> +vhost_vsock="no"
>  kvm="no"
>  rdma=""
>  gprof="no"
> @@ -674,6 +675,7 @@ Haiku)
>    kvm="yes"
>    vhost_net="yes"
>    vhost_scsi="yes"
> +  vhost_vsock="yes"
>    QEMU_INCLUDES="-I\$(SRC_PATH)/linux-headers -I$(pwd)/linux-headers $QEMU_INCLUDES"
>  ;;
>  esac
> @@ -1017,6 +1019,10 @@ for opt do
>    ;;
>    --enable-vhost-scsi) vhost_scsi="yes"
>    ;;
> +  --disable-vhost-vsock) vhost_vsock="no"
> +  ;;
> +  --enable-vhost-vsock) vhost_vsock="yes"
> +  ;;
>    --disable-opengl) opengl="no"
>    ;;
>    --enable-opengl) opengl="yes"
> @@ -4871,6 +4877,7 @@ echo "uuid support      $uuid"
>  echo "libcap-ng support $cap_ng"
>  echo "vhost-net support $vhost_net"
>  echo "vhost-scsi support $vhost_scsi"
> +echo "vhost-vsock support $vhost_vsock"
>  echo "Trace backends    $trace_backends"
>  if have_backend "simple"; then
>  echo "Trace output file $trace_file-<pid>"
> @@ -5252,6 +5259,9 @@ fi
>  if test "$vhost_net" = "yes" ; then
>    echo "CONFIG_VHOST_NET_USED=y" >> $config_host_mak
>  fi
> +if test "$vhost_vsock" = "yes" ; then
> +  echo "CONFIG_VHOST_VSOCK=y" >> $config_host_mak
> +fi
>  if test "$blobs" = "yes" ; then
>    echo "INSTALL_BLOBS=yes" >> $config_host_mak
>  fi
> diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
> index a554a24..bd5475a 100644
> --- a/hw/s390x/virtio-ccw.c
> +++ b/hw/s390x/virtio-ccw.c
> @@ -1658,6 +1658,57 @@ static const TypeInfo virtio_ccw_9p_info = {
>  };
>  #endif
>
> +#ifdef CONFIG_VHOST_VSOCK
> +
> +static Property vhost_vsock_ccw_properties[] = {
> +    DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
> +    DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev,
> +                       VIRTIO_CCW_MAX_REV),
> +    DEFINE_PROP_END_OF_LIST(),
> +};
> +
> +static void vhost_vsock_ccw_realize(VirtioCcwDevice *ccw_dev, Error **errp)
> +{
> +    VHostVSockCCWState *dev = VHOST_VSOCK_CCW(ccw_dev);
> +    DeviceState *vdev = DEVICE(&dev->vdev);
> +    Error *err = NULL;
> +
> +    qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus));
> +    object_property_set_bool(OBJECT(vdev), true, "realized", &err);
> +    if (err) {
> +        error_propagate(errp, err);
> +    }
> +}
> +
> +static void vhost_vsock_ccw_class_init(ObjectClass *klass, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(klass);
> +    VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
> +
> +    k->realize = vhost_vsock_ccw_realize;
> +    k->exit = virtio_ccw_exit;
> +    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
> +    dc->props = vhost_vsock_ccw_properties;
> +    dc->reset = virtio_ccw_reset;
> +}
> +
> +static void vhost_vsock_ccw_instance_init(Object *obj)
> +{
> +    VHostVSockCCWState *dev = VHOST_VSOCK_CCW(obj);
> +
> +    virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
> +                                TYPE_VHOST_VSOCK);
> +}
> +
> +static const TypeInfo vhost_vsock_ccw_info = {
> +    .name          = TYPE_VHOST_VSOCK_CCW,
> +    .parent        = TYPE_VIRTIO_CCW_DEVICE,
> +    .instance_size = sizeof(VHostVSockCCWState),
> +    .instance_init = vhost_vsock_ccw_instance_init,
> +    .class_init    = vhost_vsock_ccw_class_init,
> +};
> +#endif
> +
>  static void virtio_ccw_register(void)
>  {
>      type_register_static(&virtio_ccw_bus_info);
> @@ -1674,6 +1725,9 @@ static void virtio_ccw_register(void)
>  #ifdef CONFIG_VIRTFS
>      type_register_static(&virtio_ccw_9p_info);
>  #endif
> +#ifdef CONFIG_VHOST_VSOCK
> +    type_register_static(&vhost_vsock_ccw_info);
> +#endif
>  }
>
>  type_init(virtio_ccw_register)
> diff --git a/hw/s390x/virtio-ccw.h b/hw/s390x/virtio-ccw.h
> index 1c6bc86..904e357 100644
> --- a/hw/s390x/virtio-ccw.h
> +++ b/hw/s390x/virtio-ccw.h
> @@ -23,6 +23,9 @@
>  #include "hw/virtio/virtio-balloon.h"
>  #include "hw/virtio/virtio-rng.h"
>  #include "hw/virtio/virtio-bus.h"
> +#ifdef CONFIG_VHOST_VSOCK
> +#include "hw/virtio/vhost-vsock.h"
> +#endif /* CONFIG_VHOST_VSOCK */
>
>  #include "hw/s390x/s390_flic.h"
>  #include "hw/s390x/css.h"
> @@ -197,4 +200,16 @@ typedef struct V9fsCCWState {
>
>  #endif /* CONFIG_VIRTFS */
>
> +#ifdef CONFIG_VHOST_VSOCK
> +#define TYPE_VHOST_VSOCK_CCW "vhost-vsock-ccw"
> +#define VHOST_VSOCK_CCW(obj) \
> +    OBJECT_CHECK(VHostVSockCCWState, (obj), TYPE_VHOST_VSOCK_CCW)
> +
> +typedef struct VHostVSockCCWState {
> +    VirtioCcwDevice parent_obj;
> +    VHostVSock vdev;
> +} VHostVSockCCWState;
> +
> +#endif /* CONFIG_VHOST_VSOCK */
> +
>  #endif
> diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs
> index 3e2b175..e716308 100644
> --- a/hw/virtio/Makefile.objs
> +++ b/hw/virtio/Makefile.objs
> @@ -5,3 +5,5 @@ common-obj-y += virtio-mmio.o
>
>  obj-y += virtio.o virtio-balloon.o
>  obj-$(CONFIG_LINUX) += vhost.o vhost-backend.o vhost-user.o
> +
> +obj-$(CONFIG_VHOST_VSOCK) += vhost-vsock.o
> diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c
> index 7681f15..272a5ec 100644
> --- a/hw/virtio/vhost-backend.c
> +++ b/hw/virtio/vhost-backend.c
> @@ -172,6 +172,19 @@ static int vhost_kernel_get_vq_index(struct vhost_dev *dev, int idx)
>      return idx - dev->vq_index;
>  }
>
> +#ifdef CONFIG_VHOST_VSOCK
> +static int vhost_kernel_vsock_set_guest_cid(struct vhost_dev *dev,
> +                                            uint64_t guest_cid)
> +{
> +    return vhost_kernel_call(dev, VHOST_VSOCK_SET_GUEST_CID, &guest_cid);
> +}
> +
> +static int vhost_kernel_vsock_set_running(struct vhost_dev *dev, int start)
> +{
> +    return vhost_kernel_call(dev, VHOST_VSOCK_SET_RUNNING, &start);
> +}
> +#endif /* CONFIG_VHOST_VSOCK */
> +
>  static const VhostOps kernel_ops = {
>          .backend_type = VHOST_BACKEND_TYPE_KERNEL,
>          .vhost_backend_init = vhost_kernel_init,
> @@ -197,6 +210,10 @@ static const VhostOps kernel_ops = {
>          .vhost_set_owner = vhost_kernel_set_owner,
>          .vhost_reset_device = vhost_kernel_reset_device,
>          .vhost_get_vq_index = vhost_kernel_get_vq_index,
> +#ifdef CONFIG_VHOST_VSOCK
> +        .vhost_vsock_set_guest_cid = vhost_kernel_vsock_set_guest_cid,
> +        .vhost_vsock_set_running = vhost_kernel_vsock_set_running,
> +#endif /* CONFIG_VHOST_VSOCK */
>  };
>
>  int vhost_set_backend_type(struct vhost_dev *dev, VhostBackendType backend_type)
> diff --git a/hw/virtio/vhost-vsock.c b/hw/virtio/vhost-vsock.c
> new file mode 100644
> index 0000000..bde2456
> --- /dev/null
> +++ b/hw/virtio/vhost-vsock.c
> @@ -0,0 +1,417 @@
> +/*
> + * Virtio vsock device
> + *
> + * Copyright 2015 Red Hat, Inc.
> + *
> + * Authors:
> + *  Stefan Hajnoczi <stefanha@redhat.com>
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or
> + * (at your option) any later version.  See the COPYING file in the
> + * top-level directory.
> + */
> +
> +#include <sys/ioctl.h>
> +#include "qemu/osdep.h"
> +#include "standard-headers/linux/virtio_vsock.h"
> +#include "qapi/error.h"
> +#include "hw/virtio/virtio-bus.h"
> +#include "hw/virtio/virtio-access.h"
> +#include "migration/migration.h"
> +#include "qemu/error-report.h"
> +#include "hw/virtio/vhost-vsock.h"
> +#include "qemu/iov.h"
> +#include "monitor/monitor.h"
> +
> +enum {
> +    VHOST_VSOCK_SAVEVM_VERSION = 0,
> +
> +    VHOST_VSOCK_QUEUE_SIZE = 128,
> +};
> +
> +static void vhost_vsock_get_config(VirtIODevice *vdev, uint8_t *config)
> +{
> +    VHostVSock *vsock = VHOST_VSOCK(vdev);
> +    struct virtio_vsock_config vsockcfg = {};
> +
> +    virtio_stq_p(vdev, &vsockcfg.guest_cid, vsock->conf.guest_cid);
> +    memcpy(config, &vsockcfg, sizeof(vsockcfg));
> +}
> +
> +static int vhost_vsock_set_guest_cid(VHostVSock *vsock)
> +{
> +    const VhostOps *vhost_ops = vsock->vhost_dev.vhost_ops;
> +    int ret;
> +
> +    if (!vhost_ops->vhost_vsock_set_guest_cid) {
> +        return -ENOSYS;
> +    }
> +
> +    ret = vhost_ops->vhost_vsock_set_guest_cid(&vsock->vhost_dev,
> +                                               vsock->conf.guest_cid);
> +    if (ret < 0) {
> +        return -errno;
> +    }
> +    return 0;
> +}
> +
> +static int vhost_vsock_set_running(VHostVSock *vsock, int start)
> +{
> +    const VhostOps *vhost_ops = vsock->vhost_dev.vhost_ops;
> +    int ret;
> +
> +    if (!vhost_ops->vhost_vsock_set_running) {
> +        return -ENOSYS;
> +    }
> +
> +    ret = vhost_ops->vhost_vsock_set_running(&vsock->vhost_dev, start);
> +    if (ret < 0) {
> +        return -errno;
> +    }
> +    return 0;
> +}
> +
> +static void vhost_vsock_start(VirtIODevice *vdev)
> +{
> +    VHostVSock *vsock = VHOST_VSOCK(vdev);
> +    BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
> +    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
> +    int ret;
> +    int i;
> +
> +    if (!k->set_guest_notifiers) {
> +        error_report("binding does not support guest notifiers");
> +        return;
> +    }
> +
> +    ret = vhost_dev_enable_notifiers(&vsock->vhost_dev, vdev);
> +    if (ret < 0) {
> +        error_report("Error enabling host notifiers: %d", -ret);
> +        return;
> +    }
> +
> +    ret = k->set_guest_notifiers(qbus->parent, vsock->vhost_dev.nvqs, true);
> +    if (ret < 0) {
> +        error_report("Error binding guest notifier: %d", -ret);
> +        goto err_host_notifiers;
> +    }
> +
> +    vsock->vhost_dev.acked_features = vdev->guest_features;
> +    ret = vhost_dev_start(&vsock->vhost_dev, vdev);
> +    if (ret < 0) {
> +        error_report("Error starting vhost: %d", -ret);
> +        goto err_guest_notifiers;
> +    }
> +
> +    ret = vhost_vsock_set_running(vsock, 1);
> +    if (ret < 0) {
> +        error_report("Error starting vhost vsock: %d", -ret);
> +        goto err_dev_start;
> +    }
> +
> +    /* guest_notifier_mask/pending not used yet, so just unmask
> +     * everything here.  virtio-pci will do the right thing by
> +     * enabling/disabling irqfd.
> +     */
> +    for (i = 0; i < vsock->vhost_dev.nvqs; i++) {
> +        vhost_virtqueue_mask(&vsock->vhost_dev, vdev, i, false);
> +    }
> +
> +    return;
> +
> +err_dev_start:
> +    vhost_dev_stop(&vsock->vhost_dev, vdev);
> +err_guest_notifiers:
> +    k->set_guest_notifiers(qbus->parent, vsock->vhost_dev.nvqs, false);
> +err_host_notifiers:
> +    vhost_dev_disable_notifiers(&vsock->vhost_dev, vdev);
> +}
> +
> +static void vhost_vsock_stop(VirtIODevice *vdev)
> +{
> +    VHostVSock *vsock = VHOST_VSOCK(vdev);
> +    BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
> +    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
> +    int ret;
> +
> +    if (!k->set_guest_notifiers) {
> +        return;
> +    }
> +
> +    ret = vhost_vsock_set_running(vsock, 0);
> +    if (ret < 0) {
> +        error_report("vhost vsock set running failed: %d", ret);
> +        return;
> +    }
> +
> +    vhost_dev_stop(&vsock->vhost_dev, vdev);
> +
> +    ret = k->set_guest_notifiers(qbus->parent, vsock->vhost_dev.nvqs, false);
> +    if (ret < 0) {
> +        error_report("vhost guest notifier cleanup failed: %d", ret);
> +        return;
> +    }
> +
> +    vhost_dev_disable_notifiers(&vsock->vhost_dev, vdev);
> +}
> +
> +static void vhost_vsock_set_status(VirtIODevice *vdev, uint8_t status)
> +{
> +    VHostVSock *vsock = VHOST_VSOCK(vdev);
> +    bool should_start = status & VIRTIO_CONFIG_S_DRIVER_OK;
> +
> +    if (!vdev->vm_running) {
> +        should_start = false;
> +    }
> +
> +    if (vsock->vhost_dev.started == should_start) {
> +        return;
> +    }
> +
> +    if (should_start) {
> +        vhost_vsock_start(vdev);
> +    } else {
> +        vhost_vsock_stop(vdev);
> +    }
> +}
> +
> +static uint64_t vhost_vsock_get_features(VirtIODevice *vdev,
> +                                         uint64_t requested_features,
> +                                         Error **errp)
> +{
> +    /* No feature bits used yet */
> +    return requested_features;
> +}
> +
> +static void vhost_vsock_handle_output(VirtIODevice *vdev, VirtQueue *vq)
> +{
> +    /* Do nothing */
> +}
> +
> +static void vhost_vsock_guest_notifier_mask(VirtIODevice *vdev, int idx,
> +                                            bool mask)
> +{
> +    VHostVSock *vsock = VHOST_VSOCK(vdev);
> +
> +    vhost_virtqueue_mask(&vsock->vhost_dev, vdev, idx, mask);
> +}
> +
> +static bool vhost_vsock_guest_notifier_pending(VirtIODevice *vdev, int idx)
> +{
> +    VHostVSock *vsock = VHOST_VSOCK(vdev);
> +
> +    return vhost_virtqueue_pending(&vsock->vhost_dev, idx);
> +}
> +
> +static void vhost_vsock_send_transport_reset(VHostVSock *vsock)
> +{
> +    VirtQueueElement *elem;
> +    VirtQueue *vq = vsock->event_vq;
> +    struct virtio_vsock_event event = {
> +        .id = cpu_to_le32(VIRTIO_VSOCK_EVENT_TRANSPORT_RESET),
> +    };
> +
> +    elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
> +    if (!elem) {
> +        error_report("vhost-vsock missed transport reset event");
> +        return;
> +    }
> +
> +    if (elem->out_num) {
> +        error_report("invalid vhost-vsock event virtqueue element with "
> +                     "out buffers");
> +        goto out;
> +    }
> +
> +    if (iov_from_buf(elem->in_sg, elem->in_num, 0,
> +                     &event, sizeof(event)) != sizeof(event)) {
> +        error_report("vhost-vsock event virtqueue element is too short");
> +        goto out;
> +    }
> +
> +    virtqueue_push(vq, elem, sizeof(event));
> +    virtio_notify(VIRTIO_DEVICE(vsock), vq);
> +
> +out:
> +    g_free(elem);
> +}
> +
> +static void vhost_vsock_save(QEMUFile *f, void *opaque, size_t size)
> +{
> +    VHostVSock *vsock = opaque;
> +    VirtIODevice *vdev = VIRTIO_DEVICE(vsock);
> +
> +    /* At this point, backend must be stopped, otherwise
> +     * it might keep writing to memory. */
> +    assert(!vsock->vhost_dev.started);
> +    virtio_save(vdev, f);
> +}
> +
> +static void vhost_vsock_post_load_timer_cleanup(VHostVSock *vsock)
> +{
> +    if (!vsock->post_load_timer) {
> +        return;
> +    }
> +
> +    timer_del(vsock->post_load_timer);
> +    timer_free(vsock->post_load_timer);
> +    vsock->post_load_timer = NULL;
> +}
> +
> +static void vhost_vsock_post_load_timer_cb(void *opaque)
> +{
> +    VHostVSock *vsock = opaque;
> +
> +    vhost_vsock_post_load_timer_cleanup(vsock);
> +    vhost_vsock_send_transport_reset(vsock);
> +}
> +
> +static int vhost_vsock_load(QEMUFile *f, void *opaque, size_t size)
> +{
> +    VHostVSock *vsock = opaque;
> +    VirtIODevice *vdev = VIRTIO_DEVICE(vsock);
> +    int ret;
> +
> +    ret = virtio_load(vdev, f, VHOST_VSOCK_SAVEVM_VERSION);
> +    if (ret) {
> +        return ret;
> +    }
> +
> +    if (virtio_queue_get_addr(vdev, 2)) {
> +        /* Defer transport reset event to a vm clock timer so that virtqueue
> +         * changes happen after migration has completed.
> +         */
> +        assert(!vsock->post_load_timer);
> +        vsock->post_load_timer =
> +            timer_new_ns(QEMU_CLOCK_VIRTUAL,
> +                         vhost_vsock_post_load_timer_cb,
> +                         vsock);
> +        timer_mod(vsock->post_load_timer, 1);
> +    }
> +
> +    return 0;
> +}
> +
> +VMSTATE_VIRTIO_DEVICE(vhost_vsock, VHOST_VSOCK_SAVEVM_VERSION,
> +                      vhost_vsock_load, vhost_vsock_save);
> +
> +static void vhost_vsock_device_realize(DeviceState *dev, Error **errp)
> +{
> +    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
> +    VHostVSock *vsock = VHOST_VSOCK(dev);
> +    int vhostfd;
> +    int ret;
> +
> +    /* Refuse to use reserved CID numbers */
> +    if (vsock->conf.guest_cid <= 2) {
> +        error_setg(errp, "guest-cid property must be greater than 2");
> +        return;
> +    }
> +
> +    if (vsock->conf.guest_cid > UINT32_MAX) {
> +        error_setg(errp, "guest-cid property must be a 32-bit number");
> +        return;
> +    }
> +
> +    if (vsock->conf.vhostfd) {
> +        vhostfd = monitor_fd_param(cur_mon, vsock->conf.vhostfd, errp);
> +        if (vhostfd == -1) {
> +            error_prepend(errp, "vhost-vsock: unable to parse vhostfd: ");
> +            return;
> +        }
> +    } else {
> +        vhostfd = open("/dev/vhost-vsock", O_RDWR);
> +        if (vhostfd < 0) {
> +            error_setg_errno(errp, -errno,
> +                             "vhost-vsock: failed to open vhost device");
> +            return;
> +        }
> +    }
> +
> +    virtio_init(vdev, "vhost-vsock", VIRTIO_ID_VSOCK,
> +                sizeof(struct virtio_vsock_config));
> +
> +    /* Receive and transmit queues belong to vhost */
> +    virtio_add_queue(vdev, VHOST_VSOCK_QUEUE_SIZE, vhost_vsock_handle_output);
> +    virtio_add_queue(vdev, VHOST_VSOCK_QUEUE_SIZE, vhost_vsock_handle_output);
> +
> +    /* The event queue belongs to QEMU */
> +    vsock->event_vq = virtio_add_queue(vdev, VHOST_VSOCK_QUEUE_SIZE,
> +                                       vhost_vsock_handle_output);
> +
> +    vsock->vhost_dev.nvqs = ARRAY_SIZE(vsock->vhost_vqs);
> +    vsock->vhost_dev.vqs = vsock->vhost_vqs;
> +    ret = vhost_dev_init(&vsock->vhost_dev, (void *)(uintptr_t)vhostfd,
> +                         VHOST_BACKEND_TYPE_KERNEL, 0);
> +    if (ret < 0) {
> +        error_setg_errno(errp, -ret, "vhost-vsock: vhost_dev_init failed");
> +        goto err_virtio;
> +    }
> +
> +    ret = vhost_vsock_set_guest_cid(vsock);
> +    if (ret < 0) {
> +        error_setg_errno(errp, -ret, "vhost-vsock: unable to set guest cid");
> +        goto err_vhost_dev;
> +    }
> +
> +    vsock->post_load_timer = NULL;
> +    return;
> +
> +err_vhost_dev:
> +    vhost_dev_cleanup(&vsock->vhost_dev);
> +err_virtio:
> +    virtio_cleanup(vdev);
> +    close(vhostfd);
> +    return;
> +}
> +
> +static void vhost_vsock_device_unrealize(DeviceState *dev, Error **errp)
> +{
> +    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
> +    VHostVSock *vsock = VHOST_VSOCK(dev);
> +
> +    vhost_vsock_post_load_timer_cleanup(vsock);
> +
> +    /* This will stop vhost backend if appropriate. */
> +    vhost_vsock_set_status(vdev, 0);
> +
> +    vhost_dev_cleanup(&vsock->vhost_dev);
> +    virtio_cleanup(vdev);
> +}
> +
> +static Property vhost_vsock_properties[] = {
> +    DEFINE_PROP_UINT64("guest-cid", VHostVSock, conf.guest_cid, 0),
> +    DEFINE_PROP_STRING("vhostfd", VHostVSock, conf.vhostfd),
> +    DEFINE_PROP_END_OF_LIST(),
> +};
> +
> +static void vhost_vsock_class_init(ObjectClass *klass, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(klass);
> +    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
> +
> +    dc->props = vhost_vsock_properties;
> +    dc->vmsd = &vmstate_virtio_vhost_vsock;
> +    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
> +    vdc->realize = vhost_vsock_device_realize;
> +    vdc->unrealize = vhost_vsock_device_unrealize;
> +    vdc->get_features = vhost_vsock_get_features;
> +    vdc->get_config = vhost_vsock_get_config;
> +    vdc->set_status = vhost_vsock_set_status;
> +    vdc->guest_notifier_mask = vhost_vsock_guest_notifier_mask;
> +    vdc->guest_notifier_pending = vhost_vsock_guest_notifier_pending;
> +}
> +
> +static const TypeInfo vhost_vsock_info = {
> +    .name = TYPE_VHOST_VSOCK,
> +    .parent = TYPE_VIRTIO_DEVICE,
> +    .instance_size = sizeof(VHostVSock),
> +    .class_init = vhost_vsock_class_init,
> +};
> +
> +static void vhost_vsock_register_types(void)
> +{
> +    type_register_static(&vhost_vsock_info);
> +}
> +
> +type_init(vhost_vsock_register_types)
> diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
> index 755f921..ac42c54 100644
> --- a/hw/virtio/virtio-pci.c
> +++ b/hw/virtio/virtio-pci.c
> @@ -2055,6 +2055,54 @@ static const TypeInfo vhost_scsi_pci_info = {
>  };
>  #endif
>
> +/* vhost-vsock-pci */
> +
> +#ifdef CONFIG_VHOST_VSOCK
> +static Property vhost_vsock_pci_properties[] = {
> +    DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 3),
> +    DEFINE_PROP_END_OF_LIST(),
> +};
> +
> +static void vhost_vsock_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
> +{
> +    VHostVSockPCI *dev = VHOST_VSOCK_PCI(vpci_dev);
> +    DeviceState *vdev = DEVICE(&dev->vdev);
> +
> +    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
> +    object_property_set_bool(OBJECT(vdev), true, "realized", errp);
> +}
> +
> +static void vhost_vsock_pci_class_init(ObjectClass *klass, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(klass);
> +    VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
> +    PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
> +    k->realize = vhost_vsock_pci_realize;
> +    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
> +    dc->props = vhost_vsock_pci_properties;
> +    pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
> +    pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_VSOCK;
> +    pcidev_k->revision = 0x00;
> +    pcidev_k->class_id = PCI_CLASS_COMMUNICATION_OTHER;
> +}
> +
> +static void vhost_vsock_pci_instance_init(Object *obj)
> +{
> +    VHostVSockPCI *dev = VHOST_VSOCK_PCI(obj);
> +
> +    virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
> +                                TYPE_VHOST_VSOCK);
> +}
> +
> +static const TypeInfo vhost_vsock_pci_info = {
> +    .name          = TYPE_VHOST_VSOCK_PCI,
> +    .parent        = TYPE_VIRTIO_PCI,
> +    .instance_size = sizeof(VHostVSockPCI),
> +    .instance_init = vhost_vsock_pci_instance_init,
> +    .class_init    = vhost_vsock_pci_class_init,
> +};
> +#endif
> +
>  /* virtio-balloon-pci */
>
>  static Property virtio_balloon_pci_properties[] = {
> @@ -2485,6 +2533,9 @@ static void virtio_pci_register_types(void)
>  #ifdef CONFIG_VHOST_SCSI
>      type_register_static(&vhost_scsi_pci_info);
>  #endif
> +#ifdef CONFIG_VHOST_VSOCK
> +    type_register_static(&vhost_vsock_pci_info);
> +#endif
>  }
>
>  type_init(virtio_pci_register_types)
> diff --git a/hw/virtio/virtio-pci.h b/hw/virtio/virtio-pci.h
> index 25fbf8a..efd27f7 100644
> --- a/hw/virtio/virtio-pci.h
> +++ b/hw/virtio/virtio-pci.h
> @@ -31,6 +31,9 @@
>  #ifdef CONFIG_VHOST_SCSI
>  #include "hw/virtio/vhost-scsi.h"
>  #endif
> +#ifdef CONFIG_VHOST_VSOCK
> +#include "hw/virtio/vhost-vsock.h"
> +#endif
>
>  typedef struct VirtIOPCIProxy VirtIOPCIProxy;
>  typedef struct VirtIOBlkPCI VirtIOBlkPCI;
> @@ -44,6 +47,7 @@ typedef struct VirtIOInputPCI VirtIOInputPCI;
>  typedef struct VirtIOInputHIDPCI VirtIOInputHIDPCI;
>  typedef struct VirtIOInputHostPCI VirtIOInputHostPCI;
>  typedef struct VirtIOGPUPCI VirtIOGPUPCI;
> +typedef struct VHostVSockPCI VHostVSockPCI;
>
>  /* virtio-pci-bus */
>
> @@ -324,6 +328,20 @@ struct VirtIOGPUPCI {
>      VirtIOGPU vdev;
>  };
>
> +#ifdef CONFIG_VHOST_VSOCK
> +/*
> + * vhost-vsock-pci: This extends VirtioPCIProxy.
> + */
> +#define TYPE_VHOST_VSOCK_PCI "vhost-vsock-pci"
> +#define VHOST_VSOCK_PCI(obj) \
> +        OBJECT_CHECK(VHostVSockPCI, (obj), TYPE_VHOST_VSOCK_PCI)
> +
> +struct VHostVSockPCI {
> +    VirtIOPCIProxy parent_obj;
> +    VHostVSock vdev;
> +};
> +#endif
> +
>  /* Virtio ABI version, if we increment this, we break the guest driver. */
>  #define VIRTIO_PCI_ABI_VERSION          0
>
> diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
> index 929ec2f..e8b83bb 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_VIRTIO_VSOCK       0x1012
>
>  #define PCI_VENDOR_ID_REDHAT             0x1b36
>  #define PCI_DEVICE_ID_REDHAT_BRIDGE      0x0001
> diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h
> index cf7f0b5..6e90703 100644
> --- a/include/hw/virtio/vhost-backend.h
> +++ b/include/hw/virtio/vhost-backend.h
> @@ -73,6 +73,9 @@ typedef int (*vhost_migration_done_op)(struct vhost_dev *dev,
>  typedef bool (*vhost_backend_can_merge_op)(struct vhost_dev *dev,
>                                             uint64_t start1, uint64_t size1,
>                                             uint64_t start2, uint64_t size2);
> +typedef int (*vhost_vsock_set_guest_cid_op)(struct vhost_dev *dev,
> +                                            uint64_t guest_cid);
> +typedef int (*vhost_vsock_set_running_op)(struct vhost_dev *dev, int start);
>
>  typedef struct VhostOps {
>      VhostBackendType backend_type;
> @@ -102,6 +105,8 @@ typedef struct VhostOps {
>      vhost_requires_shm_log_op vhost_requires_shm_log;
>      vhost_migration_done_op vhost_migration_done;
>      vhost_backend_can_merge_op vhost_backend_can_merge;
> +    vhost_vsock_set_guest_cid_op vhost_vsock_set_guest_cid;
> +    vhost_vsock_set_running_op vhost_vsock_set_running;
>  } VhostOps;
>
>  extern const VhostOps user_ops;
> diff --git a/include/hw/virtio/vhost-vsock.h b/include/hw/virtio/vhost-vsock.h
> new file mode 100644
> index 0000000..7b9205f
> --- /dev/null
> +++ b/include/hw/virtio/vhost-vsock.h
> @@ -0,0 +1,41 @@
> +/*
> + * Vhost vsock virtio device
> + *
> + * Copyright 2015 Red Hat, Inc.
> + *
> + * Authors:
> + *  Stefan Hajnoczi <stefanha@redhat.com>
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or
> + * (at your option) any later version.  See the COPYING file in the
> + * top-level directory.
> + */
> +
> +#ifndef _QEMU_VHOST_VSOCK_H
> +#define _QEMU_VHOST_VSOCK_H
> +
> +#include "hw/virtio/virtio.h"
> +#include "hw/virtio/vhost.h"
> +
> +#define TYPE_VHOST_VSOCK "vhost-vsock-device"
> +#define VHOST_VSOCK(obj) \
> +        OBJECT_CHECK(VHostVSock, (obj), TYPE_VHOST_VSOCK)
> +
> +typedef struct {
> +    uint64_t guest_cid;
> +    char *vhostfd;
> +} VHostVSockConf;
> +
> +typedef struct {
> +    /*< private >*/
> +    VirtIODevice parent;
> +    VHostVSockConf conf;
> +    struct vhost_virtqueue vhost_vqs[2];
> +    struct vhost_dev vhost_dev;
> +    VirtQueue *event_vq;
> +    QEMUTimer *post_load_timer;
> +
> +    /*< public >*/
> +} VHostVSock;
> +
> +#endif /* _QEMU_VHOST_VSOCK_H */
>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Qemu-devel] [PATCH for-2.8 2/2] vhost-vsock: add virtio sockets device
  2016-08-23 17:45   ` Claudio Imbrenda
@ 2016-08-24 16:00     ` Cornelia Huck
  0 siblings, 0 replies; 7+ messages in thread
From: Cornelia Huck @ 2016-08-24 16:00 UTC (permalink / raw)
  To: Claudio Imbrenda
  Cc: Stefan Hajnoczi, qemu-devel, marius vlad, Michael S. Tsirkin,
	Ian Campbell, Alex Bennée, Christoffer Dall, Greg Kurz

On Tue, 23 Aug 2016 19:45:15 +0200
Claudio Imbrenda <imbrenda@linux.vnet.ibm.com> wrote:

> Hi Stefan!
> 
> I tried it on s390x and... it doesn't compile :(
> Something has been changed somewhere behind our backs, and you need to 
> change this line to get it to compile again:
> 
> --- virtio-ccw.c~       2016-08-23 16:37:14.000000000 +0200
> +++ virtio-ccw.c        2016-08-23 16:41:10.587853314 +0200
> @@ -1661,7 +1661,7 @@
>   #ifdef CONFIG_VHOST_VSOCK
> 
>   static Property vhost_vsock_ccw_properties[] = {
> -    DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
> +    DEFINE_PROP_CSS_DEV_ID("devno", VirtioCcwDevice, parent_obj.bus_id),
>       DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev,
>                          VIRTIO_CCW_MAX_REV),
>       DEFINE_PROP_END_OF_LIST(),

This was changed completely in the open ;)

Your change looks correct to me.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Qemu-devel] [PATCH for-2.8 2/2] vhost-vsock: add virtio sockets device
  2016-08-16 12:27 ` [Qemu-devel] [PATCH for-2.8 2/2] vhost-vsock: add virtio sockets device Stefan Hajnoczi
  2016-08-23 17:45   ` Claudio Imbrenda
@ 2016-09-09 21:07   ` Michael S. Tsirkin
  2016-09-12 14:56     ` Claudio Imbrenda
  1 sibling, 1 reply; 7+ messages in thread
From: Michael S. Tsirkin @ 2016-09-09 21:07 UTC (permalink / raw)
  To: Stefan Hajnoczi
  Cc: qemu-devel, Christoffer Dall, Alex Bennée, marius vlad,
	Claudio Imbrenda, Greg Kurz, Ian Campbell

On Tue, Aug 16, 2016 at 01:27:22PM +0100, Stefan Hajnoczi wrote:
> Implement the new virtio sockets device for host<->guest communication
> using the Sockets API.  Most of the work is done in a vhost kernel
> driver so that virtio-vsock can hook into the AF_VSOCK address family.
> The QEMU vhost-vsock device handles configuration and live migration
> while the rx/tx happens in the vhost_vsock.ko Linux kernel driver.
> 
> The vsock device must be given a CID (host-wide unique address):
> 
>   # qemu -device vhost-vsock-pci,id=vhost-vsock-pci0,guest-cid=3 ...
> 
> For more information see:
> http://qemu-project.org/Features/VirtioVsock
> 
> [Endianness fixes and virtio-ccw support by Claudio Imbrenda
> <imbrenda@linux.vnet.ibm.com>]
> 
> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>

Seems to fail build:

/scm/qemu/hw/s390x/virtio-ccw.c:1664:4: error: ‘VirtioCcwDevice {aka
struct VirtioCcwDevice}’ has no member named ‘bus_id’
     DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
    ^
/scm/qemu/hw/s390x/virtio-ccw.c:1664:49: error: ‘VirtioCcwDevice {aka
struct VirtioCcwDevice}’ has no member named ‘bus_id’
     DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),



> ---
>  configure                         |  10 +
>  hw/s390x/virtio-ccw.c             |  54 +++++
>  hw/s390x/virtio-ccw.h             |  15 ++
>  hw/virtio/Makefile.objs           |   2 +
>  hw/virtio/vhost-backend.c         |  17 ++
>  hw/virtio/vhost-vsock.c           | 417 ++++++++++++++++++++++++++++++++++++++
>  hw/virtio/virtio-pci.c            |  51 +++++
>  hw/virtio/virtio-pci.h            |  18 ++
>  include/hw/pci/pci.h              |   1 +
>  include/hw/virtio/vhost-backend.h |   5 +
>  include/hw/virtio/vhost-vsock.h   |  41 ++++
>  11 files changed, 631 insertions(+)
>  create mode 100644 hw/virtio/vhost-vsock.c
>  create mode 100644 include/hw/virtio/vhost-vsock.h
> 
> diff --git a/configure b/configure
> index 4b808f9..a71ad4c 100755
> --- a/configure
> +++ b/configure
> @@ -229,6 +229,7 @@ xfs=""
>  
>  vhost_net="no"
>  vhost_scsi="no"
> +vhost_vsock="no"
>  kvm="no"
>  rdma=""
>  gprof="no"
> @@ -674,6 +675,7 @@ Haiku)
>    kvm="yes"
>    vhost_net="yes"
>    vhost_scsi="yes"
> +  vhost_vsock="yes"
>    QEMU_INCLUDES="-I\$(SRC_PATH)/linux-headers -I$(pwd)/linux-headers $QEMU_INCLUDES"
>  ;;
>  esac
> @@ -1017,6 +1019,10 @@ for opt do
>    ;;
>    --enable-vhost-scsi) vhost_scsi="yes"
>    ;;
> +  --disable-vhost-vsock) vhost_vsock="no"
> +  ;;
> +  --enable-vhost-vsock) vhost_vsock="yes"
> +  ;;
>    --disable-opengl) opengl="no"
>    ;;
>    --enable-opengl) opengl="yes"
> @@ -4871,6 +4877,7 @@ echo "uuid support      $uuid"
>  echo "libcap-ng support $cap_ng"
>  echo "vhost-net support $vhost_net"
>  echo "vhost-scsi support $vhost_scsi"
> +echo "vhost-vsock support $vhost_vsock"
>  echo "Trace backends    $trace_backends"
>  if have_backend "simple"; then
>  echo "Trace output file $trace_file-<pid>"
> @@ -5252,6 +5259,9 @@ fi
>  if test "$vhost_net" = "yes" ; then
>    echo "CONFIG_VHOST_NET_USED=y" >> $config_host_mak
>  fi
> +if test "$vhost_vsock" = "yes" ; then
> +  echo "CONFIG_VHOST_VSOCK=y" >> $config_host_mak
> +fi
>  if test "$blobs" = "yes" ; then
>    echo "INSTALL_BLOBS=yes" >> $config_host_mak
>  fi
> diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
> index a554a24..bd5475a 100644
> --- a/hw/s390x/virtio-ccw.c
> +++ b/hw/s390x/virtio-ccw.c
> @@ -1658,6 +1658,57 @@ static const TypeInfo virtio_ccw_9p_info = {
>  };
>  #endif
>  
> +#ifdef CONFIG_VHOST_VSOCK
> +
> +static Property vhost_vsock_ccw_properties[] = {
> +    DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
> +    DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev,
> +                       VIRTIO_CCW_MAX_REV),
> +    DEFINE_PROP_END_OF_LIST(),
> +};
> +
> +static void vhost_vsock_ccw_realize(VirtioCcwDevice *ccw_dev, Error **errp)
> +{
> +    VHostVSockCCWState *dev = VHOST_VSOCK_CCW(ccw_dev);
> +    DeviceState *vdev = DEVICE(&dev->vdev);
> +    Error *err = NULL;
> +
> +    qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus));
> +    object_property_set_bool(OBJECT(vdev), true, "realized", &err);
> +    if (err) {
> +        error_propagate(errp, err);
> +    }
> +}
> +
> +static void vhost_vsock_ccw_class_init(ObjectClass *klass, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(klass);
> +    VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
> +
> +    k->realize = vhost_vsock_ccw_realize;
> +    k->exit = virtio_ccw_exit;
> +    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
> +    dc->props = vhost_vsock_ccw_properties;
> +    dc->reset = virtio_ccw_reset;
> +}
> +
> +static void vhost_vsock_ccw_instance_init(Object *obj)
> +{
> +    VHostVSockCCWState *dev = VHOST_VSOCK_CCW(obj);
> +
> +    virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
> +                                TYPE_VHOST_VSOCK);
> +}
> +
> +static const TypeInfo vhost_vsock_ccw_info = {
> +    .name          = TYPE_VHOST_VSOCK_CCW,
> +    .parent        = TYPE_VIRTIO_CCW_DEVICE,
> +    .instance_size = sizeof(VHostVSockCCWState),
> +    .instance_init = vhost_vsock_ccw_instance_init,
> +    .class_init    = vhost_vsock_ccw_class_init,
> +};
> +#endif
> +
>  static void virtio_ccw_register(void)
>  {
>      type_register_static(&virtio_ccw_bus_info);
> @@ -1674,6 +1725,9 @@ static void virtio_ccw_register(void)
>  #ifdef CONFIG_VIRTFS
>      type_register_static(&virtio_ccw_9p_info);
>  #endif
> +#ifdef CONFIG_VHOST_VSOCK
> +    type_register_static(&vhost_vsock_ccw_info);
> +#endif
>  }
>  
>  type_init(virtio_ccw_register)
> diff --git a/hw/s390x/virtio-ccw.h b/hw/s390x/virtio-ccw.h
> index 1c6bc86..904e357 100644
> --- a/hw/s390x/virtio-ccw.h
> +++ b/hw/s390x/virtio-ccw.h
> @@ -23,6 +23,9 @@
>  #include "hw/virtio/virtio-balloon.h"
>  #include "hw/virtio/virtio-rng.h"
>  #include "hw/virtio/virtio-bus.h"
> +#ifdef CONFIG_VHOST_VSOCK
> +#include "hw/virtio/vhost-vsock.h"
> +#endif /* CONFIG_VHOST_VSOCK */
>  
>  #include "hw/s390x/s390_flic.h"
>  #include "hw/s390x/css.h"
> @@ -197,4 +200,16 @@ typedef struct V9fsCCWState {
>  
>  #endif /* CONFIG_VIRTFS */
>  
> +#ifdef CONFIG_VHOST_VSOCK
> +#define TYPE_VHOST_VSOCK_CCW "vhost-vsock-ccw"
> +#define VHOST_VSOCK_CCW(obj) \
> +    OBJECT_CHECK(VHostVSockCCWState, (obj), TYPE_VHOST_VSOCK_CCW)
> +
> +typedef struct VHostVSockCCWState {
> +    VirtioCcwDevice parent_obj;
> +    VHostVSock vdev;
> +} VHostVSockCCWState;
> +
> +#endif /* CONFIG_VHOST_VSOCK */
> +
>  #endif
> diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs
> index 3e2b175..e716308 100644
> --- a/hw/virtio/Makefile.objs
> +++ b/hw/virtio/Makefile.objs
> @@ -5,3 +5,5 @@ common-obj-y += virtio-mmio.o
>  
>  obj-y += virtio.o virtio-balloon.o 
>  obj-$(CONFIG_LINUX) += vhost.o vhost-backend.o vhost-user.o
> +
> +obj-$(CONFIG_VHOST_VSOCK) += vhost-vsock.o
> diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c
> index 7681f15..272a5ec 100644
> --- a/hw/virtio/vhost-backend.c
> +++ b/hw/virtio/vhost-backend.c
> @@ -172,6 +172,19 @@ static int vhost_kernel_get_vq_index(struct vhost_dev *dev, int idx)
>      return idx - dev->vq_index;
>  }
>  
> +#ifdef CONFIG_VHOST_VSOCK
> +static int vhost_kernel_vsock_set_guest_cid(struct vhost_dev *dev,
> +                                            uint64_t guest_cid)
> +{
> +    return vhost_kernel_call(dev, VHOST_VSOCK_SET_GUEST_CID, &guest_cid);
> +}
> +
> +static int vhost_kernel_vsock_set_running(struct vhost_dev *dev, int start)
> +{
> +    return vhost_kernel_call(dev, VHOST_VSOCK_SET_RUNNING, &start);
> +}
> +#endif /* CONFIG_VHOST_VSOCK */
> +
>  static const VhostOps kernel_ops = {
>          .backend_type = VHOST_BACKEND_TYPE_KERNEL,
>          .vhost_backend_init = vhost_kernel_init,
> @@ -197,6 +210,10 @@ static const VhostOps kernel_ops = {
>          .vhost_set_owner = vhost_kernel_set_owner,
>          .vhost_reset_device = vhost_kernel_reset_device,
>          .vhost_get_vq_index = vhost_kernel_get_vq_index,
> +#ifdef CONFIG_VHOST_VSOCK
> +        .vhost_vsock_set_guest_cid = vhost_kernel_vsock_set_guest_cid,
> +        .vhost_vsock_set_running = vhost_kernel_vsock_set_running,
> +#endif /* CONFIG_VHOST_VSOCK */
>  };
>  
>  int vhost_set_backend_type(struct vhost_dev *dev, VhostBackendType backend_type)
> diff --git a/hw/virtio/vhost-vsock.c b/hw/virtio/vhost-vsock.c
> new file mode 100644
> index 0000000..bde2456
> --- /dev/null
> +++ b/hw/virtio/vhost-vsock.c
> @@ -0,0 +1,417 @@
> +/*
> + * Virtio vsock device
> + *
> + * Copyright 2015 Red Hat, Inc.
> + *
> + * Authors:
> + *  Stefan Hajnoczi <stefanha@redhat.com>
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or
> + * (at your option) any later version.  See the COPYING file in the
> + * top-level directory.
> + */
> +
> +#include <sys/ioctl.h>
> +#include "qemu/osdep.h"
> +#include "standard-headers/linux/virtio_vsock.h"
> +#include "qapi/error.h"
> +#include "hw/virtio/virtio-bus.h"
> +#include "hw/virtio/virtio-access.h"
> +#include "migration/migration.h"
> +#include "qemu/error-report.h"
> +#include "hw/virtio/vhost-vsock.h"
> +#include "qemu/iov.h"
> +#include "monitor/monitor.h"
> +
> +enum {
> +    VHOST_VSOCK_SAVEVM_VERSION = 0,
> +
> +    VHOST_VSOCK_QUEUE_SIZE = 128,
> +};
> +
> +static void vhost_vsock_get_config(VirtIODevice *vdev, uint8_t *config)
> +{
> +    VHostVSock *vsock = VHOST_VSOCK(vdev);
> +    struct virtio_vsock_config vsockcfg = {};
> +
> +    virtio_stq_p(vdev, &vsockcfg.guest_cid, vsock->conf.guest_cid);
> +    memcpy(config, &vsockcfg, sizeof(vsockcfg));
> +}
> +
> +static int vhost_vsock_set_guest_cid(VHostVSock *vsock)
> +{
> +    const VhostOps *vhost_ops = vsock->vhost_dev.vhost_ops;
> +    int ret;
> +
> +    if (!vhost_ops->vhost_vsock_set_guest_cid) {
> +        return -ENOSYS;
> +    }
> +
> +    ret = vhost_ops->vhost_vsock_set_guest_cid(&vsock->vhost_dev,
> +                                               vsock->conf.guest_cid);
> +    if (ret < 0) {
> +        return -errno;
> +    }
> +    return 0;
> +}
> +
> +static int vhost_vsock_set_running(VHostVSock *vsock, int start)
> +{
> +    const VhostOps *vhost_ops = vsock->vhost_dev.vhost_ops;
> +    int ret;
> +
> +    if (!vhost_ops->vhost_vsock_set_running) {
> +        return -ENOSYS;
> +    }
> +
> +    ret = vhost_ops->vhost_vsock_set_running(&vsock->vhost_dev, start);
> +    if (ret < 0) {
> +        return -errno;
> +    }
> +    return 0;
> +}
> +
> +static void vhost_vsock_start(VirtIODevice *vdev)
> +{
> +    VHostVSock *vsock = VHOST_VSOCK(vdev);
> +    BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
> +    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
> +    int ret;
> +    int i;
> +
> +    if (!k->set_guest_notifiers) {
> +        error_report("binding does not support guest notifiers");
> +        return;
> +    }
> +
> +    ret = vhost_dev_enable_notifiers(&vsock->vhost_dev, vdev);
> +    if (ret < 0) {
> +        error_report("Error enabling host notifiers: %d", -ret);
> +        return;
> +    }
> +
> +    ret = k->set_guest_notifiers(qbus->parent, vsock->vhost_dev.nvqs, true);
> +    if (ret < 0) {
> +        error_report("Error binding guest notifier: %d", -ret);
> +        goto err_host_notifiers;
> +    }
> +
> +    vsock->vhost_dev.acked_features = vdev->guest_features;
> +    ret = vhost_dev_start(&vsock->vhost_dev, vdev);
> +    if (ret < 0) {
> +        error_report("Error starting vhost: %d", -ret);
> +        goto err_guest_notifiers;
> +    }
> +
> +    ret = vhost_vsock_set_running(vsock, 1);
> +    if (ret < 0) {
> +        error_report("Error starting vhost vsock: %d", -ret);
> +        goto err_dev_start;
> +    }
> +
> +    /* guest_notifier_mask/pending not used yet, so just unmask
> +     * everything here.  virtio-pci will do the right thing by
> +     * enabling/disabling irqfd.
> +     */
> +    for (i = 0; i < vsock->vhost_dev.nvqs; i++) {
> +        vhost_virtqueue_mask(&vsock->vhost_dev, vdev, i, false);
> +    }
> +
> +    return;
> +
> +err_dev_start:
> +    vhost_dev_stop(&vsock->vhost_dev, vdev);
> +err_guest_notifiers:
> +    k->set_guest_notifiers(qbus->parent, vsock->vhost_dev.nvqs, false);
> +err_host_notifiers:
> +    vhost_dev_disable_notifiers(&vsock->vhost_dev, vdev);
> +}
> +
> +static void vhost_vsock_stop(VirtIODevice *vdev)
> +{
> +    VHostVSock *vsock = VHOST_VSOCK(vdev);
> +    BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
> +    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
> +    int ret;
> +
> +    if (!k->set_guest_notifiers) {
> +        return;
> +    }
> +
> +    ret = vhost_vsock_set_running(vsock, 0);
> +    if (ret < 0) {
> +        error_report("vhost vsock set running failed: %d", ret);
> +        return;
> +    }
> +
> +    vhost_dev_stop(&vsock->vhost_dev, vdev);
> +
> +    ret = k->set_guest_notifiers(qbus->parent, vsock->vhost_dev.nvqs, false);
> +    if (ret < 0) {
> +        error_report("vhost guest notifier cleanup failed: %d", ret);
> +        return;
> +    }
> +
> +    vhost_dev_disable_notifiers(&vsock->vhost_dev, vdev);
> +}
> +
> +static void vhost_vsock_set_status(VirtIODevice *vdev, uint8_t status)
> +{
> +    VHostVSock *vsock = VHOST_VSOCK(vdev);
> +    bool should_start = status & VIRTIO_CONFIG_S_DRIVER_OK;
> +
> +    if (!vdev->vm_running) {
> +        should_start = false;
> +    }
> +
> +    if (vsock->vhost_dev.started == should_start) {
> +        return;
> +    }
> +
> +    if (should_start) {
> +        vhost_vsock_start(vdev);
> +    } else {
> +        vhost_vsock_stop(vdev);
> +    }
> +}
> +
> +static uint64_t vhost_vsock_get_features(VirtIODevice *vdev,
> +                                         uint64_t requested_features,
> +                                         Error **errp)
> +{
> +    /* No feature bits used yet */
> +    return requested_features;
> +}
> +
> +static void vhost_vsock_handle_output(VirtIODevice *vdev, VirtQueue *vq)
> +{
> +    /* Do nothing */
> +}
> +
> +static void vhost_vsock_guest_notifier_mask(VirtIODevice *vdev, int idx,
> +                                            bool mask)
> +{
> +    VHostVSock *vsock = VHOST_VSOCK(vdev);
> +
> +    vhost_virtqueue_mask(&vsock->vhost_dev, vdev, idx, mask);
> +}
> +
> +static bool vhost_vsock_guest_notifier_pending(VirtIODevice *vdev, int idx)
> +{
> +    VHostVSock *vsock = VHOST_VSOCK(vdev);
> +
> +    return vhost_virtqueue_pending(&vsock->vhost_dev, idx);
> +}
> +
> +static void vhost_vsock_send_transport_reset(VHostVSock *vsock)
> +{
> +    VirtQueueElement *elem;
> +    VirtQueue *vq = vsock->event_vq;
> +    struct virtio_vsock_event event = {
> +        .id = cpu_to_le32(VIRTIO_VSOCK_EVENT_TRANSPORT_RESET),
> +    };
> +
> +    elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
> +    if (!elem) {
> +        error_report("vhost-vsock missed transport reset event");
> +        return;
> +    }
> +
> +    if (elem->out_num) {
> +        error_report("invalid vhost-vsock event virtqueue element with "
> +                     "out buffers");
> +        goto out;
> +    }
> +
> +    if (iov_from_buf(elem->in_sg, elem->in_num, 0,
> +                     &event, sizeof(event)) != sizeof(event)) {
> +        error_report("vhost-vsock event virtqueue element is too short");
> +        goto out;
> +    }
> +
> +    virtqueue_push(vq, elem, sizeof(event));
> +    virtio_notify(VIRTIO_DEVICE(vsock), vq);
> +
> +out:
> +    g_free(elem);
> +}
> +
> +static void vhost_vsock_save(QEMUFile *f, void *opaque, size_t size)
> +{
> +    VHostVSock *vsock = opaque;
> +    VirtIODevice *vdev = VIRTIO_DEVICE(vsock);
> +
> +    /* At this point, backend must be stopped, otherwise
> +     * it might keep writing to memory. */
> +    assert(!vsock->vhost_dev.started);
> +    virtio_save(vdev, f);
> +}
> +
> +static void vhost_vsock_post_load_timer_cleanup(VHostVSock *vsock)
> +{
> +    if (!vsock->post_load_timer) {
> +        return;
> +    }
> +
> +    timer_del(vsock->post_load_timer);
> +    timer_free(vsock->post_load_timer);
> +    vsock->post_load_timer = NULL;
> +}
> +
> +static void vhost_vsock_post_load_timer_cb(void *opaque)
> +{
> +    VHostVSock *vsock = opaque;
> +
> +    vhost_vsock_post_load_timer_cleanup(vsock);
> +    vhost_vsock_send_transport_reset(vsock);
> +}
> +
> +static int vhost_vsock_load(QEMUFile *f, void *opaque, size_t size)
> +{
> +    VHostVSock *vsock = opaque;
> +    VirtIODevice *vdev = VIRTIO_DEVICE(vsock);
> +    int ret;
> +
> +    ret = virtio_load(vdev, f, VHOST_VSOCK_SAVEVM_VERSION);
> +    if (ret) {
> +        return ret;
> +    }
> +
> +    if (virtio_queue_get_addr(vdev, 2)) {
> +        /* Defer transport reset event to a vm clock timer so that virtqueue
> +         * changes happen after migration has completed.
> +         */
> +        assert(!vsock->post_load_timer);
> +        vsock->post_load_timer =
> +            timer_new_ns(QEMU_CLOCK_VIRTUAL,
> +                         vhost_vsock_post_load_timer_cb,
> +                         vsock);
> +        timer_mod(vsock->post_load_timer, 1);
> +    }
> +
> +    return 0;
> +}
> +
> +VMSTATE_VIRTIO_DEVICE(vhost_vsock, VHOST_VSOCK_SAVEVM_VERSION,
> +                      vhost_vsock_load, vhost_vsock_save);
> +
> +static void vhost_vsock_device_realize(DeviceState *dev, Error **errp)
> +{
> +    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
> +    VHostVSock *vsock = VHOST_VSOCK(dev);
> +    int vhostfd;
> +    int ret;
> +
> +    /* Refuse to use reserved CID numbers */
> +    if (vsock->conf.guest_cid <= 2) {
> +        error_setg(errp, "guest-cid property must be greater than 2");
> +        return;
> +    }
> +
> +    if (vsock->conf.guest_cid > UINT32_MAX) {
> +        error_setg(errp, "guest-cid property must be a 32-bit number");
> +        return;
> +    }
> +
> +    if (vsock->conf.vhostfd) {
> +        vhostfd = monitor_fd_param(cur_mon, vsock->conf.vhostfd, errp);
> +        if (vhostfd == -1) {
> +            error_prepend(errp, "vhost-vsock: unable to parse vhostfd: ");
> +            return;
> +        }
> +    } else {
> +        vhostfd = open("/dev/vhost-vsock", O_RDWR);
> +        if (vhostfd < 0) {
> +            error_setg_errno(errp, -errno,
> +                             "vhost-vsock: failed to open vhost device");
> +            return;
> +        }
> +    }
> +
> +    virtio_init(vdev, "vhost-vsock", VIRTIO_ID_VSOCK,
> +                sizeof(struct virtio_vsock_config));
> +
> +    /* Receive and transmit queues belong to vhost */
> +    virtio_add_queue(vdev, VHOST_VSOCK_QUEUE_SIZE, vhost_vsock_handle_output);
> +    virtio_add_queue(vdev, VHOST_VSOCK_QUEUE_SIZE, vhost_vsock_handle_output);
> +
> +    /* The event queue belongs to QEMU */
> +    vsock->event_vq = virtio_add_queue(vdev, VHOST_VSOCK_QUEUE_SIZE,
> +                                       vhost_vsock_handle_output);
> +
> +    vsock->vhost_dev.nvqs = ARRAY_SIZE(vsock->vhost_vqs);
> +    vsock->vhost_dev.vqs = vsock->vhost_vqs;
> +    ret = vhost_dev_init(&vsock->vhost_dev, (void *)(uintptr_t)vhostfd,
> +                         VHOST_BACKEND_TYPE_KERNEL, 0);
> +    if (ret < 0) {
> +        error_setg_errno(errp, -ret, "vhost-vsock: vhost_dev_init failed");
> +        goto err_virtio;
> +    }
> +
> +    ret = vhost_vsock_set_guest_cid(vsock);
> +    if (ret < 0) {
> +        error_setg_errno(errp, -ret, "vhost-vsock: unable to set guest cid");
> +        goto err_vhost_dev;
> +    }
> +
> +    vsock->post_load_timer = NULL;
> +    return;
> +
> +err_vhost_dev:
> +    vhost_dev_cleanup(&vsock->vhost_dev);
> +err_virtio:
> +    virtio_cleanup(vdev);
> +    close(vhostfd);
> +    return;
> +}
> +
> +static void vhost_vsock_device_unrealize(DeviceState *dev, Error **errp)
> +{
> +    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
> +    VHostVSock *vsock = VHOST_VSOCK(dev);
> +
> +    vhost_vsock_post_load_timer_cleanup(vsock);
> +
> +    /* This will stop vhost backend if appropriate. */
> +    vhost_vsock_set_status(vdev, 0);
> +
> +    vhost_dev_cleanup(&vsock->vhost_dev);
> +    virtio_cleanup(vdev);
> +}
> +
> +static Property vhost_vsock_properties[] = {
> +    DEFINE_PROP_UINT64("guest-cid", VHostVSock, conf.guest_cid, 0),
> +    DEFINE_PROP_STRING("vhostfd", VHostVSock, conf.vhostfd),
> +    DEFINE_PROP_END_OF_LIST(),
> +};
> +
> +static void vhost_vsock_class_init(ObjectClass *klass, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(klass);
> +    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
> +
> +    dc->props = vhost_vsock_properties;
> +    dc->vmsd = &vmstate_virtio_vhost_vsock;
> +    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
> +    vdc->realize = vhost_vsock_device_realize;
> +    vdc->unrealize = vhost_vsock_device_unrealize;
> +    vdc->get_features = vhost_vsock_get_features;
> +    vdc->get_config = vhost_vsock_get_config;
> +    vdc->set_status = vhost_vsock_set_status;
> +    vdc->guest_notifier_mask = vhost_vsock_guest_notifier_mask;
> +    vdc->guest_notifier_pending = vhost_vsock_guest_notifier_pending;
> +}
> +
> +static const TypeInfo vhost_vsock_info = {
> +    .name = TYPE_VHOST_VSOCK,
> +    .parent = TYPE_VIRTIO_DEVICE,
> +    .instance_size = sizeof(VHostVSock),
> +    .class_init = vhost_vsock_class_init,
> +};
> +
> +static void vhost_vsock_register_types(void)
> +{
> +    type_register_static(&vhost_vsock_info);
> +}
> +
> +type_init(vhost_vsock_register_types)
> diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
> index 755f921..ac42c54 100644
> --- a/hw/virtio/virtio-pci.c
> +++ b/hw/virtio/virtio-pci.c
> @@ -2055,6 +2055,54 @@ static const TypeInfo vhost_scsi_pci_info = {
>  };
>  #endif
>  
> +/* vhost-vsock-pci */
> +
> +#ifdef CONFIG_VHOST_VSOCK
> +static Property vhost_vsock_pci_properties[] = {
> +    DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 3),
> +    DEFINE_PROP_END_OF_LIST(),
> +};
> +
> +static void vhost_vsock_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
> +{
> +    VHostVSockPCI *dev = VHOST_VSOCK_PCI(vpci_dev);
> +    DeviceState *vdev = DEVICE(&dev->vdev);
> +
> +    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
> +    object_property_set_bool(OBJECT(vdev), true, "realized", errp);
> +}
> +
> +static void vhost_vsock_pci_class_init(ObjectClass *klass, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(klass);
> +    VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
> +    PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
> +    k->realize = vhost_vsock_pci_realize;
> +    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
> +    dc->props = vhost_vsock_pci_properties;
> +    pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
> +    pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_VSOCK;
> +    pcidev_k->revision = 0x00;
> +    pcidev_k->class_id = PCI_CLASS_COMMUNICATION_OTHER;
> +}
> +
> +static void vhost_vsock_pci_instance_init(Object *obj)
> +{
> +    VHostVSockPCI *dev = VHOST_VSOCK_PCI(obj);
> +
> +    virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
> +                                TYPE_VHOST_VSOCK);
> +}
> +
> +static const TypeInfo vhost_vsock_pci_info = {
> +    .name          = TYPE_VHOST_VSOCK_PCI,
> +    .parent        = TYPE_VIRTIO_PCI,
> +    .instance_size = sizeof(VHostVSockPCI),
> +    .instance_init = vhost_vsock_pci_instance_init,
> +    .class_init    = vhost_vsock_pci_class_init,
> +};
> +#endif
> +
>  /* virtio-balloon-pci */
>  
>  static Property virtio_balloon_pci_properties[] = {
> @@ -2485,6 +2533,9 @@ static void virtio_pci_register_types(void)
>  #ifdef CONFIG_VHOST_SCSI
>      type_register_static(&vhost_scsi_pci_info);
>  #endif
> +#ifdef CONFIG_VHOST_VSOCK
> +    type_register_static(&vhost_vsock_pci_info);
> +#endif
>  }
>  
>  type_init(virtio_pci_register_types)
> diff --git a/hw/virtio/virtio-pci.h b/hw/virtio/virtio-pci.h
> index 25fbf8a..efd27f7 100644
> --- a/hw/virtio/virtio-pci.h
> +++ b/hw/virtio/virtio-pci.h
> @@ -31,6 +31,9 @@
>  #ifdef CONFIG_VHOST_SCSI
>  #include "hw/virtio/vhost-scsi.h"
>  #endif
> +#ifdef CONFIG_VHOST_VSOCK
> +#include "hw/virtio/vhost-vsock.h"
> +#endif
>  
>  typedef struct VirtIOPCIProxy VirtIOPCIProxy;
>  typedef struct VirtIOBlkPCI VirtIOBlkPCI;
> @@ -44,6 +47,7 @@ typedef struct VirtIOInputPCI VirtIOInputPCI;
>  typedef struct VirtIOInputHIDPCI VirtIOInputHIDPCI;
>  typedef struct VirtIOInputHostPCI VirtIOInputHostPCI;
>  typedef struct VirtIOGPUPCI VirtIOGPUPCI;
> +typedef struct VHostVSockPCI VHostVSockPCI;
>  
>  /* virtio-pci-bus */
>  
> @@ -324,6 +328,20 @@ struct VirtIOGPUPCI {
>      VirtIOGPU vdev;
>  };
>  
> +#ifdef CONFIG_VHOST_VSOCK
> +/*
> + * vhost-vsock-pci: This extends VirtioPCIProxy.
> + */
> +#define TYPE_VHOST_VSOCK_PCI "vhost-vsock-pci"
> +#define VHOST_VSOCK_PCI(obj) \
> +        OBJECT_CHECK(VHostVSockPCI, (obj), TYPE_VHOST_VSOCK_PCI)
> +
> +struct VHostVSockPCI {
> +    VirtIOPCIProxy parent_obj;
> +    VHostVSock vdev;
> +};
> +#endif
> +
>  /* Virtio ABI version, if we increment this, we break the guest driver. */
>  #define VIRTIO_PCI_ABI_VERSION          0
>  
> diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
> index 929ec2f..e8b83bb 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_VIRTIO_VSOCK       0x1012
>  
>  #define PCI_VENDOR_ID_REDHAT             0x1b36
>  #define PCI_DEVICE_ID_REDHAT_BRIDGE      0x0001
> diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h
> index cf7f0b5..6e90703 100644
> --- a/include/hw/virtio/vhost-backend.h
> +++ b/include/hw/virtio/vhost-backend.h
> @@ -73,6 +73,9 @@ typedef int (*vhost_migration_done_op)(struct vhost_dev *dev,
>  typedef bool (*vhost_backend_can_merge_op)(struct vhost_dev *dev,
>                                             uint64_t start1, uint64_t size1,
>                                             uint64_t start2, uint64_t size2);
> +typedef int (*vhost_vsock_set_guest_cid_op)(struct vhost_dev *dev,
> +                                            uint64_t guest_cid);
> +typedef int (*vhost_vsock_set_running_op)(struct vhost_dev *dev, int start);
>  
>  typedef struct VhostOps {
>      VhostBackendType backend_type;
> @@ -102,6 +105,8 @@ typedef struct VhostOps {
>      vhost_requires_shm_log_op vhost_requires_shm_log;
>      vhost_migration_done_op vhost_migration_done;
>      vhost_backend_can_merge_op vhost_backend_can_merge;
> +    vhost_vsock_set_guest_cid_op vhost_vsock_set_guest_cid;
> +    vhost_vsock_set_running_op vhost_vsock_set_running;
>  } VhostOps;
>  
>  extern const VhostOps user_ops;
> diff --git a/include/hw/virtio/vhost-vsock.h b/include/hw/virtio/vhost-vsock.h
> new file mode 100644
> index 0000000..7b9205f
> --- /dev/null
> +++ b/include/hw/virtio/vhost-vsock.h
> @@ -0,0 +1,41 @@
> +/*
> + * Vhost vsock virtio device
> + *
> + * Copyright 2015 Red Hat, Inc.
> + *
> + * Authors:
> + *  Stefan Hajnoczi <stefanha@redhat.com>
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or
> + * (at your option) any later version.  See the COPYING file in the
> + * top-level directory.
> + */
> +
> +#ifndef _QEMU_VHOST_VSOCK_H
> +#define _QEMU_VHOST_VSOCK_H
> +
> +#include "hw/virtio/virtio.h"
> +#include "hw/virtio/vhost.h"
> +
> +#define TYPE_VHOST_VSOCK "vhost-vsock-device"
> +#define VHOST_VSOCK(obj) \
> +        OBJECT_CHECK(VHostVSock, (obj), TYPE_VHOST_VSOCK)
> +
> +typedef struct {
> +    uint64_t guest_cid;
> +    char *vhostfd;
> +} VHostVSockConf;
> +
> +typedef struct {
> +    /*< private >*/
> +    VirtIODevice parent;
> +    VHostVSockConf conf;
> +    struct vhost_virtqueue vhost_vqs[2];
> +    struct vhost_dev vhost_dev;
> +    VirtQueue *event_vq;
> +    QEMUTimer *post_load_timer;
> +
> +    /*< public >*/
> +} VHostVSock;
> +
> +#endif /* _QEMU_VHOST_VSOCK_H */
> -- 
> 2.7.4

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Qemu-devel] [PATCH for-2.8 2/2] vhost-vsock: add virtio sockets device
  2016-09-09 21:07   ` Michael S. Tsirkin
@ 2016-09-12 14:56     ` Claudio Imbrenda
  0 siblings, 0 replies; 7+ messages in thread
From: Claudio Imbrenda @ 2016-09-12 14:56 UTC (permalink / raw)
  To: Michael S. Tsirkin, Stefan Hajnoczi
  Cc: qemu-devel, Christoffer Dall, Alex Bennée, marius vlad,
	Greg Kurz, Ian Campbell

On 09/09/16 23:07, Michael S. Tsirkin wrote:
[...]
> Seems to fail build:
>
> /scm/qemu/hw/s390x/virtio-ccw.c:1664:4: error: ‘VirtioCcwDevice {aka
> struct VirtioCcwDevice}’ has no member named ‘bus_id’
>      DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
>     ^
> /scm/qemu/hw/s390x/virtio-ccw.c:1664:49: error: ‘VirtioCcwDevice {aka
> struct VirtioCcwDevice}’ has no member named ‘bus_id’
>      DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
>

Yeah, I had noticed that too; I sent this one-liner to correct that
issue on August 23rd; since it's small, I'll copypaste it here (modulo
automatic linewraps):

--- virtio-ccw.c~       2016-08-23 16:37:14.000000000 +0200
+++ virtio-ccw.c        2016-08-23 16:41:10.587853314 +0200
@@ -1661,7 +1661,7 @@
 #ifdef CONFIG_VHOST_VSOCK

 static Property vhost_vsock_ccw_properties[] = {
-    DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
+    DEFINE_PROP_CSS_DEV_ID("devno", VirtioCcwDevice, parent_obj.bus_id),
     DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev,
                        VIRTIO_CCW_MAX_REV),
     DEFINE_PROP_END_OF_LIST(),


hope it helps,

Claudio

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2016-09-12 14:57 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-08-16 12:27 [Qemu-devel] [PATCH for-2.8 0/2] vhost-vsock: add vhost-vsock device Stefan Hajnoczi
2016-08-16 12:27 ` [Qemu-devel] [PATCH for-2.8 1/2] linux-headers: add virtio vsock headers Stefan Hajnoczi
2016-08-16 12:27 ` [Qemu-devel] [PATCH for-2.8 2/2] vhost-vsock: add virtio sockets device Stefan Hajnoczi
2016-08-23 17:45   ` Claudio Imbrenda
2016-08-24 16:00     ` Cornelia Huck
2016-09-09 21:07   ` Michael S. Tsirkin
2016-09-12 14:56     ` Claudio Imbrenda

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.