* [PATCH 0/2] virtio_ring: reject a split ring size that is not a power of two again
@ 2026-11-11 17:29 Stjepan Poljak
2026-11-11 17:29 ` [PATCH 1/2] " Stjepan Poljak
2026-11-11 17:29 ` [PATCH 2/2] tools/virtio: vringh_test: check that a split ring must be a power of two Stjepan Poljak
0 siblings, 2 replies; 4+ messages in thread
From: Stjepan Poljak @ 2026-11-11 17:29 UTC (permalink / raw)
To: Michael S. Tsirkin, Jason Wang
Cc: Eugenio Pérez, Xuan Zhuo, Andy Lutomirski, Bjorn Andersson,
Mathieu Poirier, virtualization, linux-remoteproc, linux-kernel
The split ring indexes its rings with num - 1 as a mask, so its size
must be a power of two. vring_new_virtqueue() lost that check in v4.6,
with commit 2a2d1382fe9d ("virtio: Add improved queue allocation API"),
and remoteproc passes it a ring size taken from firmware. A firmware
that asks for, e.g. 100 entries gets a ring on which the driver and
the device disagree on where the buffers are, so the device can read
the wrong ones. The only thing remoteproc checks is that ring size
and alignment are not zero. The other caller, mlxbf-tmfifo, uses a
hardcoded size of 1024, so it is not affected unless that value is
changed.
Patch 1 puts the check back; patch 2 adds a vringh_test case for it.
Tested in userspace with tools/virtio only, not on remoteproc hardware.
Stjepan Poljak (2):
virtio_ring: reject a split ring size that is not a power of two again
tools/virtio: vringh_test: check that a split ring must be a power of
two
drivers/virtio/virtio_ring.c | 6 ++++++
tools/virtio/vringh_test.c | 11 +++++++++++
2 files changed, 17 insertions(+)
base-commit: 1a577f9402c1780cc1e663f48d5dd54c02051b09
--
2.53.0
^ permalink raw reply [flat|nested] 4+ messages in thread* [PATCH 1/2] virtio_ring: reject a split ring size that is not a power of two again 2026-11-11 17:29 [PATCH 0/2] virtio_ring: reject a split ring size that is not a power of two again Stjepan Poljak @ 2026-11-11 17:29 ` Stjepan Poljak 2026-11-11 21:51 ` Francesco Valla 2026-11-11 17:29 ` [PATCH 2/2] tools/virtio: vringh_test: check that a split ring must be a power of two Stjepan Poljak 1 sibling, 1 reply; 4+ messages in thread From: Stjepan Poljak @ 2026-11-11 17:29 UTC (permalink / raw) To: Michael S. Tsirkin, Jason Wang Cc: Eugenio Pérez, Xuan Zhuo, Andy Lutomirski, Bjorn Andersson, Mathieu Poirier, virtualization, linux-remoteproc, linux-kernel The split ring indexes its avail and used rings with num - 1 as a mask, so its size must be a power of two. Commit 2a2d1382fe9d ("virtio: Add improved queue allocation API") moved that check from vring_new_virtqueue() into the new allocation path, which vring_new_virtqueue() does not use. remoteproc calls vring_new_virtqueue() with a ring size from the firmware, checked only to be non-zero. With 100 entries, for example, the driver would put buffers 4 and 8 in avail slot 0. The device would look for them at slots 4 and 8, possibly reading the wrong data. Put the check back for the split ring; the packed ring has no such restriction. Fixes: 2a2d1382fe9d ("virtio: Add improved queue allocation API") Signed-off-by: Stjepan Poljak <stjepan.poljak@gmail.com> --- remoteproc still reports this as -ENOMEM, although the "Bad virtqueue length" warning names the cause. Returning an error pointer from vring_new_virtqueue() is left for later; the same change for vring_create_virtqueue() is here: https://lore.kernel.org/r/20261106055635.3019889-1-stjepan.poljak@gmail.com --- drivers/virtio/virtio_ring.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index f683a2d6a200..8da9bd0e70f4 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -3513,6 +3513,12 @@ struct virtqueue *vring_new_virtqueue(unsigned int index, name, map); } + /* The split ring indexes its rings with num - 1 as a mask. */ + if (!is_power_of_2(num)) { + dev_warn(&vdev->dev, "Bad virtqueue length %u\n", num); + return NULL; + } + vring_init(&vring_split.vring, num, pages, vring_align); return __vring_new_virtqueue_split(index, &vring_split, vdev, weak_barriers, context, notify, callback, name, base-commit: 1a577f9402c1780cc1e663f48d5dd54c02051b09 -- 2.53.0 ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH 1/2] virtio_ring: reject a split ring size that is not a power of two again 2026-11-11 17:29 ` [PATCH 1/2] " Stjepan Poljak @ 2026-11-11 21:51 ` Francesco Valla 0 siblings, 0 replies; 4+ messages in thread From: Francesco Valla @ 2026-11-11 21:51 UTC (permalink / raw) To: Stjepan Poljak Cc: Michael S. Tsirkin, Jason Wang, Eugenio Pérez, Xuan Zhuo, Andy Lutomirski, Bjorn Andersson, Mathieu Poirier, virtualization, linux-remoteproc, linux-kernel Hi Stjepan, On Wed, Nov 11, 2026 at 06:29:37PM +0100, Stjepan Poljak wrote: > The split ring indexes its avail and used rings with num - 1 as a mask, > so its size must be a power of two. Commit 2a2d1382fe9d ("virtio: Add > improved queue allocation API") moved that check from > vring_new_virtqueue() into the new allocation path, which > vring_new_virtqueue() does not use. > > remoteproc calls vring_new_virtqueue() with a ring size from the > firmware, checked only to be non-zero. With 100 entries, for example, > the driver would put buffers 4 and 8 in avail slot 0. The device would > look for them at slots 4 and 8, possibly reading the wrong data. > Good catch - I think I encountered something like this during my experiments with virtio-over-remoteproc and ascribed it to a different cause. > Put the check back for the split ring; the packed ring has no such > restriction. > > Fixes: 2a2d1382fe9d ("virtio: Add improved queue allocation API") > Signed-off-by: Stjepan Poljak <stjepan.poljak@gmail.com> > --- > remoteproc still reports this as -ENOMEM, although the "Bad virtqueue > length" warning names the cause. Returning an error pointer from > vring_new_virtqueue() is left for later; the same change for > vring_create_virtqueue() is here: > https://lore.kernel.org/r/20261106055635.3019889-1-stjepan.poljak@gmail.com > --- > drivers/virtio/virtio_ring.c | 6 ++++++ > 1 file changed, 6 insertions(+) > > diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c > index f683a2d6a200..8da9bd0e70f4 100644 > --- a/drivers/virtio/virtio_ring.c > +++ b/drivers/virtio/virtio_ring.c > @@ -3513,6 +3513,12 @@ struct virtqueue *vring_new_virtqueue(unsigned int index, > name, map); > } > > + /* The split ring indexes its rings with num - 1 as a mask. */ > + if (!is_power_of_2(num)) { > + dev_warn(&vdev->dev, "Bad virtqueue length %u\n", num); This is definitely and error, and should be logged as such (I know, the same message is printed as a warn in vring_alloc_queue_split(), but we have no ABI to align to here). Also, consider to adopt a message a bit more descriptive; maybe something like this is sufficient: "Bad virtqueue length %u (not a power of two)\n" > + return NULL; > + } > + > vring_init(&vring_split.vring, num, pages, vring_align); > return __vring_new_virtqueue_split(index, &vring_split, vdev, weak_barriers, > context, notify, callback, name, > > base-commit: 1a577f9402c1780cc1e663f48d5dd54c02051b09 > -- > 2.53.0 > > Thank you! Regards, Francesco ^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 2/2] tools/virtio: vringh_test: check that a split ring must be a power of two 2026-11-11 17:29 [PATCH 0/2] virtio_ring: reject a split ring size that is not a power of two again Stjepan Poljak 2026-11-11 17:29 ` [PATCH 1/2] " Stjepan Poljak @ 2026-11-11 17:29 ` Stjepan Poljak 1 sibling, 0 replies; 4+ messages in thread From: Stjepan Poljak @ 2026-11-11 17:29 UTC (permalink / raw) To: Michael S. Tsirkin, Jason Wang Cc: Eugenio Pérez, Xuan Zhuo, Andy Lutomirski, Bjorn Andersson, Mathieu Poirier, virtualization, linux-remoteproc, linux-kernel vring_new_virtqueue() used to accept a split ring of any size, although the ring is indexed with num - 1 as a mask. Check that it now refuses one size short of RINGSIZE. Without the preceding fix, vringh_test fails with: vringh_test: vring_new_virtqueue accepted size 255 With it, vring_new_virtqueue() prints "Bad virtqueue length 255" and the rest of the test runs as before. Signed-off-by: Stjepan Poljak <stjepan.poljak@gmail.com> --- tools/virtio/vringh_test.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tools/virtio/vringh_test.c b/tools/virtio/vringh_test.c index 2a5d7f7d2d6c..75c66385502d 100644 --- a/tools/virtio/vringh_test.c +++ b/tools/virtio/vringh_test.c @@ -494,6 +494,17 @@ int main(int argc, char *argv[]) __user_addr_max = __user_addr_min + USER_MEM; memset(__user_addr_min, 0, vring_size(RINGSIZE, ALIGN)); + /* + * The split ring indexes its rings with num - 1 as a mask, so a + * size that is not a power of two must be refused. + */ + vq = vring_new_virtqueue(0, RINGSIZE - 1, ALIGN, &vdev, true, false, + __user_addr_min, + never_notify_host, never_callback_guest, + "guest vq"); + if (vq) + errx(1, "vring_new_virtqueue accepted size %u", RINGSIZE - 1); + /* Set up guest side. */ vq = vring_new_virtqueue(0, RINGSIZE, ALIGN, &vdev, true, false, __user_addr_min, -- 2.53.0 ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-11-11 21:51 UTC | newest] Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2026-11-11 17:29 [PATCH 0/2] virtio_ring: reject a split ring size that is not a power of two again Stjepan Poljak 2026-11-11 17:29 ` [PATCH 1/2] " Stjepan Poljak 2026-11-11 21:51 ` Francesco Valla 2026-11-11 17:29 ` [PATCH 2/2] tools/virtio: vringh_test: check that a split ring must be a power of two Stjepan Poljak
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®