| From cf94db21905333e610e479688add629397a4b384 Mon Sep 17 00:00:00 2001 |
| From: Cornelia Huck <cohuck@redhat.com> |
| Date: Mon, 8 Apr 2019 14:33:22 +0200 |
| Subject: virtio: Honour 'may_reduce_num' in vring_create_virtqueue |
| |
| From: Cornelia Huck <cohuck@redhat.com> |
| |
| commit cf94db21905333e610e479688add629397a4b384 upstream. |
| |
| vring_create_virtqueue() allows the caller to specify via the |
| may_reduce_num parameter whether the vring code is allowed to |
| allocate a smaller ring than specified. |
| |
| However, the split ring allocation code tries to allocate a |
| smaller ring on allocation failure regardless of what the |
| caller specified. This may cause trouble for e.g. virtio-pci |
| in legacy mode, which does not support ring resizing. (The |
| packed ring code does not resize in any case.) |
| |
| Let's fix this by bailing out immediately in the split ring code |
| if the requested size cannot be allocated and may_reduce_num has |
| not been specified. |
| |
| While at it, fix a typo in the usage instructions. |
| |
| Fixes: 2a2d1382fe9d ("virtio: Add improved queue allocation API") |
| Cc: stable@vger.kernel.org # v4.6+ |
| Signed-off-by: Cornelia Huck <cohuck@redhat.com> |
| Signed-off-by: Michael S. Tsirkin <mst@redhat.com> |
| Reviewed-by: Halil Pasic <pasic@linux.ibm.com> |
| Reviewed-by: Jens Freimann <jfreimann@redhat.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/virtio/virtio_ring.c | 2 ++ |
| include/linux/virtio_ring.h | 2 +- |
| 2 files changed, 3 insertions(+), 1 deletion(-) |
| |
| --- a/drivers/virtio/virtio_ring.c |
| +++ b/drivers/virtio/virtio_ring.c |
| @@ -871,6 +871,8 @@ static struct virtqueue *vring_create_vi |
| GFP_KERNEL|__GFP_NOWARN|__GFP_ZERO); |
| if (queue) |
| break; |
| + if (!may_reduce_num) |
| + return NULL; |
| } |
| |
| if (!num) |
| --- a/include/linux/virtio_ring.h |
| +++ b/include/linux/virtio_ring.h |
| @@ -63,7 +63,7 @@ struct virtqueue; |
| /* |
| * Creates a virtqueue and allocates the descriptor ring. If |
| * may_reduce_num is set, then this may allocate a smaller ring than |
| - * expected. The caller should query virtqueue_get_ring_size to learn |
| + * expected. The caller should query virtqueue_get_vring_size to learn |
| * the actual size of the ring. |
| */ |
| struct virtqueue *vring_create_virtqueue(unsigned int index, |