aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean-Philippe Brucker <jean-philippe@linaro.org>2023-06-06 14:04:11 +0100
committerWill Deacon <will@kernel.org>2023-06-08 22:39:03 +0100
commit745221e582f7c81ff2911599d2620ac541d0f671 (patch)
tree929b348b8a8e5a43bdb8cdb2ab839b88a4d32424
parentf84ab9eb74fcd7db332c5b915c7d60cae44f8958 (diff)
downloadkvmtool-745221e582f7c81ff2911599d2620ac541d0f671.tar.gz
virtio/vhost: Factor vring operation
The VHOST_VRING* ioctls are common to all device types, move them to virtio/vhost.c Reviewed-by: Andre Przywara <andre.przywara@arm.com> Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org> Link: https://lore.kernel.org/r/20230606130426.978945-3-jean-philippe@linaro.org Signed-off-by: Will Deacon <will@kernel.org>
-rw-r--r--include/kvm/virtio.h2
-rw-r--r--virtio/net.c25
-rw-r--r--virtio/scsi.c24
-rw-r--r--virtio/vhost.c33
-rw-r--r--virtio/vsock.c30
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;
}