The VHOST_VRING* ioctls are common to all device types, move them to virtio/vhost.c Reviewed-by: Andre Przywara <andre.przywara@xxxxxxx> Signed-off-by: Jean-Philippe Brucker <jean-philippe@xxxxxxxxxx> --- include/kvm/virtio.h | 2 ++ virtio/net.c | 25 +------------------------ virtio/scsi.c | 24 +----------------------- virtio/vhost.c | 33 ++++++++++++++++++++++++++++++++- virtio/vsock.c | 30 ++---------------------------- 5 files changed, 38 insertions(+), 76 deletions(-) diff --git a/include/kvm/virtio.h b/include/kvm/virtio.h index 4cc2e3d2..daea8554 100644 --- a/include/kvm/virtio.h +++ b/include/kvm/virtio.h @@ -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); diff --git a/virtio/net.c b/virtio/net.c index 65fdbd17..b7c64a08 100644 --- a/virtio/net.c +++ b/virtio/net.c @@ -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); diff --git a/virtio/scsi.c b/virtio/scsi.c index 621a8334..6aa0909f 100644 --- a/virtio/scsi.c +++ b/virtio/scsi.c @@ -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; } diff --git a/virtio/vhost.c b/virtio/vhost.c index f9f72f51..afe37465 100644 --- a/virtio/vhost.c +++ b/virtio/vhost.c @@ -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"); +} diff --git a/virtio/vsock.c b/virtio/vsock.c index 4b8be8d7..2f7906f2 100644 --- a/virtio/vsock.c +++ b/virtio/vsock.c @@ -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; } -- 2.40.1