@@ -259,6 +259,8 @@ void virtio_set_guest_features(struct kvm *kvm, struct virtio_device *vdev,
void virtio_notify_status(struct kvm *kvm, struct virtio_device *vdev,
void *dev, u8 status);
void virtio_vhost_init(struct kvm *kvm, int vhost_fd);
+void virtio_vhost_set_vring(struct kvm *kvm, int vhost_fd, u32 index,
+ struct virt_queue *queue);
int virtio_transport_parser(const struct option *opt, const char *arg, int unset);
@@ -600,10 +600,8 @@ static bool is_ctrl_vq(struct net_dev *ndev, u32 vq)
static int init_vq(struct kvm *kvm, void *dev, u32 vq)
{
- struct vhost_vring_state state = { .index = vq };
struct vhost_vring_file file = { .index = vq };
struct net_dev_queue *net_queue;
- struct vhost_vring_addr addr;
struct net_dev *ndev = dev;
struct virt_queue *queue;
int r;
@@ -634,28 +632,7 @@ static int init_vq(struct kvm *kvm, void *dev, u32 vq)
return 0;
}
- if (queue->endian != VIRTIO_ENDIAN_HOST)
- die_perror("VHOST requires the same endianness in guest and host");
-
- state.num = queue->vring.num;
- r = ioctl(ndev->vhost_fd, VHOST_SET_VRING_NUM, &state);
- if (r < 0)
- die_perror("VHOST_SET_VRING_NUM failed");
- state.num = 0;
- r = ioctl(ndev->vhost_fd, VHOST_SET_VRING_BASE, &state);
- if (r < 0)
- die_perror("VHOST_SET_VRING_BASE failed");
-
- addr = (struct vhost_vring_addr) {
- .index = vq,
- .desc_user_addr = (u64)(unsigned long)queue->vring.desc,
- .avail_user_addr = (u64)(unsigned long)queue->vring.avail,
- .used_user_addr = (u64)(unsigned long)queue->vring.used,
- };
-
- r = ioctl(ndev->vhost_fd, VHOST_SET_VRING_ADDR, &addr);
- if (r < 0)
- die_perror("VHOST_SET_VRING_ADDR failed");
+ virtio_vhost_set_vring(kvm, ndev->vhost_fd, vq, queue);
file.fd = ndev->tap_fd;
r = ioctl(ndev->vhost_fd, VHOST_NET_SET_BACKEND, &file);
@@ -72,11 +72,8 @@ static void notify_status(struct kvm *kvm, void *dev, u32 status)
static int init_vq(struct kvm *kvm, void *dev, u32 vq)
{
- struct vhost_vring_state state = { .index = vq };
- struct vhost_vring_addr addr;
struct scsi_dev *sdev = dev;
struct virt_queue *queue;
- int r;
compat__remove_message(compat_id);
@@ -87,26 +84,7 @@ static int init_vq(struct kvm *kvm, void *dev, u32 vq)
if (sdev->vhost_fd == 0)
return 0;
- state.num = queue->vring.num;
- r = ioctl(sdev->vhost_fd, VHOST_SET_VRING_NUM, &state);
- if (r < 0)
- die_perror("VHOST_SET_VRING_NUM failed");
- state.num = 0;
- r = ioctl(sdev->vhost_fd, VHOST_SET_VRING_BASE, &state);
- if (r < 0)
- die_perror("VHOST_SET_VRING_BASE failed");
-
- addr = (struct vhost_vring_addr) {
- .index = vq,
- .desc_user_addr = (u64)(unsigned long)queue->vring.desc,
- .avail_user_addr = (u64)(unsigned long)queue->vring.avail,
- .used_user_addr = (u64)(unsigned long)queue->vring.used,
- };
-
- r = ioctl(sdev->vhost_fd, VHOST_SET_VRING_ADDR, &addr);
- if (r < 0)
- die_perror("VHOST_SET_VRING_ADDR failed");
-
+ virtio_vhost_set_vring(kvm, sdev->vhost_fd, vq, queue);
return 0;
}
@@ -1,7 +1,8 @@
+#include "kvm/virtio.h"
+
#include <linux/kvm.h>
#include <linux/vhost.h>
#include <linux/list.h>
-#include "kvm/virtio.h"
void virtio_vhost_init(struct kvm *kvm, int vhost_fd)
{
@@ -34,3 +35,33 @@ void virtio_vhost_init(struct kvm *kvm, int vhost_fd)
free(mem);
}
+
+void virtio_vhost_set_vring(struct kvm *kvm, int vhost_fd, u32 index,
+ struct virt_queue *queue)
+{
+ int r;
+ struct vhost_vring_addr addr = {
+ .index = index,
+ .desc_user_addr = (u64)(unsigned long)queue->vring.desc,
+ .avail_user_addr = (u64)(unsigned long)queue->vring.avail,
+ .used_user_addr = (u64)(unsigned long)queue->vring.used,
+ };
+ struct vhost_vring_state state = { .index = index };
+
+ if (queue->endian != VIRTIO_ENDIAN_HOST)
+ die("VHOST requires the same endianness in guest and host");
+
+ state.num = queue->vring.num;
+ r = ioctl(vhost_fd, VHOST_SET_VRING_NUM, &state);
+ if (r < 0)
+ die_perror("VHOST_SET_VRING_NUM failed");
+
+ state.num = 0;
+ r = ioctl(vhost_fd, VHOST_SET_VRING_BASE, &state);
+ if (r < 0)
+ die_perror("VHOST_SET_VRING_BASE failed");
+
+ r = ioctl(vhost_fd, VHOST_SET_VRING_ADDR, &addr);
+ if (r < 0)
+ die_perror("VHOST_SET_VRING_ADDR failed");
+}
@@ -62,44 +62,18 @@ static bool is_event_vq(u32 vq)
static int init_vq(struct kvm *kvm, void *dev, u32 vq)
{
- struct vhost_vring_state state = { .index = vq };
- struct vhost_vring_addr addr;
struct vsock_dev *vdev = dev;
struct virt_queue *queue;
- int r;
compat__remove_message(compat_id);
queue = &vdev->vqs[vq];
virtio_init_device_vq(kvm, &vdev->vdev, queue, VIRTIO_VSOCK_QUEUE_SIZE);
- if (vdev->vhost_fd == -1)
+ if (vdev->vhost_fd == -1 || is_event_vq(vq))
return 0;
- if (is_event_vq(vq))
- return 0;
-
- state.num = queue->vring.num;
- r = ioctl(vdev->vhost_fd, VHOST_SET_VRING_NUM, &state);
- if (r < 0)
- die_perror("VHOST_SET_VRING_NUM failed");
-
- state.num = 0;
- r = ioctl(vdev->vhost_fd, VHOST_SET_VRING_BASE, &state);
- if (r < 0)
- die_perror("VHOST_SET_VRING_BASE failed");
-
- addr = (struct vhost_vring_addr) {
- .index = vq,
- .desc_user_addr = (u64)(unsigned long)queue->vring.desc,
- .avail_user_addr = (u64)(unsigned long)queue->vring.avail,
- .used_user_addr = (u64)(unsigned long)queue->vring.used,
- };
-
- r = ioctl(vdev->vhost_fd, VHOST_SET_VRING_ADDR, &addr);
- if (r < 0)
- die_perror("VHOST_SET_VRING_ADDR failed");
-
+ virtio_vhost_set_vring(kvm, vdev->vhost_fd, vq, queue);
return 0;
}