virtio-vsock
virtio-vsock
virtio-vsock provides a way for applications running on a guest VM and the host system to communicate with each other using the standard socket interface (socket
, connect
, bind
, listen
, accept
). It defines a new socket address family (AF_VSOCK
) and uses a (context id, port) pair of integers for identifying processes. The host system always has 2 as its context id while each guest VM is assigned a unique context id on startup.
vhost
virtio-vsock is a vhost-based virtio device. This means that the host kernel manages all the data transfer while the hypervisor is only responsible for dealing with control information. This diagram gives a high-level overview:
An irqfd
is a mechanism for injecting a specific interrupt into the guest VM using an eventfd. The hypervisor creates an eventfd and uses a KVM ioctl to associate it with a particular interrupt for the guest VM. Writes to this eventfd then trigger that interrupt in the guest.
An ioeventfd
does the same thing but reversed. The hypervisor creates an eventfd and associates it with a particular region of the guest VM's memory. Writes to this memory region by the guest VM will make the eventfd readable without blocking.
irqfd
and ioeventfd
are used to implement I/O for virtualized devices that does not block the guest VM cpu from running.
For vhost devices, the hypervisor performs some additional steps. It notifies the vhost kernel module about the ioeventfd
and the irqfd
for the device as well as the guest memory regions assigned for the virtual queues for that device. The vhost kernel module then takes care of listening on the ioeventfd
, processing the requests from the guest VM, and triggering an interrupt in the guest on completion of the request through the irqfd
.
vsock
vsock provides a new backend for the guest VM‘s networking stack that talks to the vhost_vsock host kernel module. The host kernel module in turn uses the host kernel’s networking stack to transfer data from the application in the guest VM to an application on the host system.
hw/block/vhost-user-blk.c:318: ret = vhost_dev_init(&s->dev, &s->vhost_user, VHOST_BACKEND_TYPE_USER, 0); hw/virtio/vhost-vsock.c:345: ret = vhost_dev_init(&vsock->vhost_dev, (void *)(uintptr_t)vhostfd, hw/virtio/vhost-vsock.c:348: error_setg_errno(errp, -ret, "vhost-vsock: vhost_dev_init failed"); hw/virtio/vhost-user-fs.c:384: ret = vhost_dev_init(&fs->vhost_dev, &fs->vhost_user, hw/virtio/vhost-user-fs.c:387: error_setg_errno(errp, -ret, "vhost_dev_init failed"); hw/virtio/vhost.c:1180:int vhost_dev_init(struct vhost_dev *hdev, void *opaque, hw/scsi/vhost-user-scsi.c:97: ret = vhost_dev_init(&vsc->dev, &s->vhost_user, hw/scsi/vhost-scsi.c:190: ret = vhost_dev_init(&vsc->dev, (void *)(uintptr_t)vhostfd, hw/net/vhost_net.c:174: r = vhost_dev_init(&net->dev, options->opaque, include/hw/virtio/vhost.h:96:int vhost_dev_init(struct vhost_dev *hdev, void *opaque,