Commit fc0b9b0e authored by Stefan Hajnoczi's avatar Stefan Hajnoczi Committed by Michael S. Tsirkin
Browse files

vhost-vsock: add virtio sockets device

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: default avatarStefan Hajnoczi <stefanha@redhat.com>
[mst: rebase to master]
Reviewed-by: default avatarMichael S. Tsirkin <mst@redhat.com>
Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
parent 947b205f
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -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"
@@ -4883,6 +4889,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>"
@@ -5264,6 +5271,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
+54 −0
Original line number Diff line number Diff line
@@ -1658,6 +1658,57 @@ static const TypeInfo virtio_ccw_9p_info = {
};
#endif

#ifdef CONFIG_VHOST_VSOCK

static Property vhost_vsock_ccw_properties[] = {
    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(),
};

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)
+15 −0
Original line number Diff line number Diff line
@@ -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
+2 −0
Original line number Diff line number Diff line
@@ -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
+17 −0
Original line number Diff line number Diff line
@@ -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)
Loading