diff options
author | Pierre Morel <pmorel@linux.vnet.ibm.com> | 2015-09-10 10:35:08 -0400 |
---|---|---|
committer | Michael S. Tsirkin <mst@redhat.com> | 2015-09-16 05:48:08 -0400 |
commit | ad2aa04218de9bd734d593adb0ac59854ec0cb68 (patch) | |
tree | 9450fac88940838127f0170f2bd3d22e323e0bc9 | |
parent | fd2e8d4300c56f9660679d629c449118e14c00cd (diff) |
virtio/s390: handle failures of READ_VQ_CONF ccw
In virtio_ccw_read_vq_conf() the return value of ccw_io_helper()
was not checked.
If the configuration could not be read properly, we'd wrongly assume a
queue size of 0.
Let's propagate any I/O error to virtio_ccw_setup_vq() so it may
properly fail.
Signed-off-by: Pierre Morel <pmorel@linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
-rw-r--r-- | drivers/s390/virtio/virtio_ccw.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/drivers/s390/virtio/virtio_ccw.c b/drivers/s390/virtio/virtio_ccw.c index f8d8fdb26b72..e9fae30fafda 100644 --- a/drivers/s390/virtio/virtio_ccw.c +++ b/drivers/s390/virtio/virtio_ccw.c | |||
@@ -400,12 +400,16 @@ static bool virtio_ccw_kvm_notify(struct virtqueue *vq) | |||
400 | static int virtio_ccw_read_vq_conf(struct virtio_ccw_device *vcdev, | 400 | static int virtio_ccw_read_vq_conf(struct virtio_ccw_device *vcdev, |
401 | struct ccw1 *ccw, int index) | 401 | struct ccw1 *ccw, int index) |
402 | { | 402 | { |
403 | int ret; | ||
404 | |||
403 | vcdev->config_block->index = index; | 405 | vcdev->config_block->index = index; |
404 | ccw->cmd_code = CCW_CMD_READ_VQ_CONF; | 406 | ccw->cmd_code = CCW_CMD_READ_VQ_CONF; |
405 | ccw->flags = 0; | 407 | ccw->flags = 0; |
406 | ccw->count = sizeof(struct vq_config_block); | 408 | ccw->count = sizeof(struct vq_config_block); |
407 | ccw->cda = (__u32)(unsigned long)(vcdev->config_block); | 409 | ccw->cda = (__u32)(unsigned long)(vcdev->config_block); |
408 | ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_READ_VQ_CONF); | 410 | ret = ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_READ_VQ_CONF); |
411 | if (ret) | ||
412 | return ret; | ||
409 | return vcdev->config_block->num; | 413 | return vcdev->config_block->num; |
410 | } | 414 | } |
411 | 415 | ||
@@ -503,6 +507,10 @@ static struct virtqueue *virtio_ccw_setup_vq(struct virtio_device *vdev, | |||
503 | goto out_err; | 507 | goto out_err; |
504 | } | 508 | } |
505 | info->num = virtio_ccw_read_vq_conf(vcdev, ccw, i); | 509 | info->num = virtio_ccw_read_vq_conf(vcdev, ccw, i); |
510 | if (info->num < 0) { | ||
511 | err = info->num; | ||
512 | goto out_err; | ||
513 | } | ||
506 | size = PAGE_ALIGN(vring_size(info->num, KVM_VIRTIO_CCW_RING_ALIGN)); | 514 | size = PAGE_ALIGN(vring_size(info->num, KVM_VIRTIO_CCW_RING_ALIGN)); |
507 | info->queue = alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO); | 515 | info->queue = alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO); |
508 | if (info->queue == NULL) { | 516 | if (info->queue == NULL) { |