Commit ad2aa042 authored by Pierre Morel's avatar Pierre Morel Committed by Michael S. Tsirkin

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: default avatarPierre Morel <pmorel@linux.vnet.ibm.com>
Signed-off-by: default avatarCornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
parent fd2e8d43
...@@ -400,12 +400,16 @@ static bool virtio_ccw_kvm_notify(struct virtqueue *vq) ...@@ -400,12 +400,16 @@ static bool virtio_ccw_kvm_notify(struct virtqueue *vq)
static int virtio_ccw_read_vq_conf(struct virtio_ccw_device *vcdev, static int virtio_ccw_read_vq_conf(struct virtio_ccw_device *vcdev,
struct ccw1 *ccw, int index) struct ccw1 *ccw, int index)
{ {
int ret;
vcdev->config_block->index = index; vcdev->config_block->index = index;
ccw->cmd_code = CCW_CMD_READ_VQ_CONF; ccw->cmd_code = CCW_CMD_READ_VQ_CONF;
ccw->flags = 0; ccw->flags = 0;
ccw->count = sizeof(struct vq_config_block); ccw->count = sizeof(struct vq_config_block);
ccw->cda = (__u32)(unsigned long)(vcdev->config_block); ccw->cda = (__u32)(unsigned long)(vcdev->config_block);
ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_READ_VQ_CONF); ret = ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_READ_VQ_CONF);
if (ret)
return ret;
return vcdev->config_block->num; return vcdev->config_block->num;
} }
...@@ -503,6 +507,10 @@ static struct virtqueue *virtio_ccw_setup_vq(struct virtio_device *vdev, ...@@ -503,6 +507,10 @@ static struct virtqueue *virtio_ccw_setup_vq(struct virtio_device *vdev,
goto out_err; goto out_err;
} }
info->num = virtio_ccw_read_vq_conf(vcdev, ccw, i); info->num = virtio_ccw_read_vq_conf(vcdev, ccw, i);
if (info->num < 0) {
err = info->num;
goto out_err;
}
size = PAGE_ALIGN(vring_size(info->num, KVM_VIRTIO_CCW_RING_ALIGN)); size = PAGE_ALIGN(vring_size(info->num, KVM_VIRTIO_CCW_RING_ALIGN));
info->queue = alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO); info->queue = alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO);
if (info->queue == NULL) { if (info->queue == NULL) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment