Message ID | 20230419132119.124457-3-jean-philippe@linaro.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Fix vhost-net, scsi and vsock | expand |
On Wed, 19 Apr 2023 14:21:06 +0100 Jean-Philippe Brucker <jean-philippe@linaro.org> wrote: > The VHOST_VRING* ioctls are common to all device types, move them to > virtio/vhost.c > > Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org> Verified that the moved-in and moved-out code is equivalent: Reviewed-by: Andre Przywara <andre.przywara@arm.com> Cheers, Andre > --- > 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 cd72bf11..c8fd69e0 100644 > --- a/include/kvm/virtio.h > +++ b/include/kvm/virtio.h > @@ -248,6 +248,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 6b44754f..021c81d3 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 4dee24a0..674aad34 100644 > --- a/virtio/scsi.c > +++ b/virtio/scsi.c > @@ -74,11 +74,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); > > @@ -89,26 +86,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; > } >
diff --git a/include/kvm/virtio.h b/include/kvm/virtio.h index cd72bf11..c8fd69e0 100644 --- a/include/kvm/virtio.h +++ b/include/kvm/virtio.h @@ -248,6 +248,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 6b44754f..021c81d3 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 4dee24a0..674aad34 100644 --- a/virtio/scsi.c +++ b/virtio/scsi.c @@ -74,11 +74,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); @@ -89,26 +86,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; }
The VHOST_VRING* ioctls are common to all device types, move them to virtio/vhost.c Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org> --- 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(-)