diff mbox series

[kvmtool,02/16] virtio/vhost: Factor vring operation

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

Commit Message

Jean-Philippe Brucker April 19, 2023, 1:21 p.m. UTC
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(-)

Comments

Andre Przywara April 20, 2023, 2:11 p.m. UTC | #1
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 mbox series

Patch

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;
 }