aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/drivers/virtio_uml.c
diff options
context:
space:
mode:
authorBenjamin Berg <[email protected]>2024-11-03 21:28:54 +0000
committerJohannes Berg <[email protected]>2024-11-07 17:05:07 +0000
commit1d4d0ef84a7f386205ad141ff8727e027b0581e4 (patch)
tree1bc20377b909d42e08c88e38283a1eac85cfb4fa /arch/um/drivers/virtio_uml.c
parentum: virtio_uml: fix call_fd IRQ allocation (diff)
downloadkernel-1d4d0ef84a7f386205ad141ff8727e027b0581e4.tar.gz
kernel-1d4d0ef84a7f386205ad141ff8727e027b0581e4.zip
um: virtio_uml: query the number of vqs if supported
When the VHOST_USER_PROTOCOL_F_MQ protocol feature flag is set, we can query the maximum number of virtual queues. Do so when supported and extend the check to verify that we are not trying to allocate more queues. Signed-off-by: Benjamin Berg <[email protected]> Link: https://patch.msgid.link/[email protected] [add a message to the WARN_ON] Signed-off-by: Johannes Berg <[email protected]>
Diffstat (limited to 'arch/um/drivers/virtio_uml.c')
-rw-r--r--arch/um/drivers/virtio_uml.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/arch/um/drivers/virtio_uml.c b/arch/um/drivers/virtio_uml.c
index 0f9efee4c671..cc3be48a9d6e 100644
--- a/arch/um/drivers/virtio_uml.c
+++ b/arch/um/drivers/virtio_uml.c
@@ -56,6 +56,7 @@ struct virtio_uml_device {
int sock, req_fd, irq;
u64 features;
u64 protocol_features;
+ u64 max_vqs;
u8 status;
u8 registered:1;
u8 suspended:1;
@@ -341,6 +342,17 @@ static int vhost_user_set_protocol_features(struct virtio_uml_device *vu_dev,
protocol_features);
}
+static int vhost_user_get_queue_num(struct virtio_uml_device *vu_dev,
+ u64 *queue_num)
+{
+ int rc = vhost_user_send_no_payload(vu_dev, true,
+ VHOST_USER_GET_QUEUE_NUM);
+
+ if (rc)
+ return rc;
+ return vhost_user_recv_u64(vu_dev, queue_num);
+}
+
static void vhost_user_reply(struct virtio_uml_device *vu_dev,
struct vhost_user_msg *msg, int response)
{
@@ -514,6 +526,15 @@ static int vhost_user_init(struct virtio_uml_device *vu_dev)
return rc;
}
+ if (vu_dev->protocol_features &
+ BIT_ULL(VHOST_USER_PROTOCOL_F_MQ)) {
+ rc = vhost_user_get_queue_num(vu_dev, &vu_dev->max_vqs);
+ if (rc)
+ return rc;
+ } else {
+ vu_dev->max_vqs = U64_MAX;
+ }
+
return 0;
}
@@ -1018,7 +1039,9 @@ static int vu_find_vqs(struct virtio_device *vdev, unsigned nvqs,
struct virtqueue *vq;
/* not supported for now */
- if (WARN_ON(nvqs > 64))
+ if (WARN(nvqs > 64 || nvqs > vu_dev->max_vqs,
+ "%d VQs requested, only up to 64 or %lld supported\n",
+ nvqs, vu_dev->max_vqs))
return -EINVAL;
rc = vhost_user_set_mem_table(vu_dev);