Hi Rusty, Would you be so kind and consider getting those two small fixes into 3.7 merge? All credits go to Brian, all shame on me :-) Cheers! Pawel Brian Foley (2): virtio_mmio: fix off by one error allocating queue virtio_mmio: Don't attempt to create empty virtqueues drivers/virtio/virtio_mmio.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) -- 1.7.9.5
Pawel Moll
2012-Sep-24 13:33 UTC
[PATCH 1/2] virtio_mmio: fix off by one error allocating queue
From: Brian Foley <brian.foley at arm.com> vm_setup_vq fails to allow VirtQueues needing only 2 pages of storage, as it should. Found with a kernel using 64kB pages, but can be provoked if a virtio device reports QueueNumMax where the descriptor table and available ring fit in one page, and the used ring on the second (<= 227 descriptors with 4kB pages and <= 3640 with 64kB pages.) Signed-off-by: Brian Foley <brian.foley at arm.com> Signed-off-by: Pawel Moll <pawel.moll at arm.com> --- drivers/virtio/virtio_mmio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c index 453db0c..58e2d78 100644 --- a/drivers/virtio/virtio_mmio.c +++ b/drivers/virtio/virtio_mmio.c @@ -335,8 +335,8 @@ static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned index, while (1) { size = PAGE_ALIGN(vring_size(info->num, VIRTIO_MMIO_VRING_ALIGN)); - /* Already smallest possible allocation? */ - if (size <= VIRTIO_MMIO_VRING_ALIGN * 2) { + /* Did the last iter shrink the queue below minimum size? */ + if (size < VIRTIO_MMIO_VRING_ALIGN * 2) { err = -ENOMEM; goto error_alloc_pages; } -- 1.7.9.5
Pawel Moll
2012-Sep-24 13:33 UTC
[PATCH 2/2] virtio_mmio: Don't attempt to create empty virtqueues
From: Brian Foley <brian.foley at arm.com> If a virtio device reports a QueueNumMax of 0, vring_new_virtqueue() doesn't check this, and thanks to an unsigned (i < num - 1) loop guard, scribbles over memory when initialising the free list. Avoid by not trying to create zero-descriptor queues, as there's no way to do any I/O with one. Signed-off-by: Brian Foley <brian.foley at arm.com> Signed-off-by: Pawel Moll <pawel.moll at arm.com> --- drivers/virtio/virtio_mmio.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c index 58e2d78..6979c1b 100644 --- a/drivers/virtio/virtio_mmio.c +++ b/drivers/virtio/virtio_mmio.c @@ -332,6 +332,16 @@ static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned index, * and two rings (which makes it "alignment_size * 2") */ info->num = readl(vm_dev->base + VIRTIO_MMIO_QUEUE_NUM_MAX); + + /* If the device reports a 0 entry queue, we won't be able to + * use it to perform I/O, and vring_new_virtqueue() can't create + * empty queues anyway, so don't bother to set up the device. + */ + if (info->num == 0) { + err = -ENOENT; + goto error_alloc_pages; + } + while (1) { size = PAGE_ALIGN(vring_size(info->num, VIRTIO_MMIO_VRING_ALIGN)); -- 1.7.9.5
Pawel Moll <pawel.moll at arm.com> writes:> Hi Rusty, > > Would you be so kind and consider getting those two small fixes into > 3.7 merge? All credits go to Brian, all shame on me :-)Should these also be cc'd to stable at kernel.org? Cheers, Rusty.
Seemingly Similar Threads
- [PATCH 0/2] virtio-mmio updates for 3.7
- [PATCH v2] virtio-mmio: Update the device to OASIS spec version
- [PATCH v2] virtio-mmio: Update the device to OASIS spec version
- [RFC] virtio-mmio: Update the device to OASIS spec version
- [RFC] virtio-mmio: Update the device to OASIS spec version