virtio_ccw: finalize_features error handling
authorCornelia Huck <cornelia.huck@de.ibm.com>
Tue, 9 Dec 2014 10:46:59 +0000 (11:46 +0100)
committerMichael S. Tsirkin <mst@redhat.com>
Tue, 9 Dec 2014 19:42:06 +0000 (21:42 +0200)
We previously tried to use device even if finalize_features failed, but
that's wrong since driver and device are now out of sync.

Fail probe if we detect failures during finalize_features.

Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
drivers/s390/kvm/virtio_ccw.c

index f92b9e6..71d7802 100644 (file)
@@ -757,6 +757,7 @@ static int virtio_ccw_finalize_features(struct virtio_device *vdev)
        struct virtio_ccw_device *vcdev = to_vc_device(vdev);
        struct virtio_feature_desc *features;
        struct ccw1 *ccw;
+       int ret;
 
        if (vcdev->revision >= 1 &&
            !__virtio_test_bit(vdev, VIRTIO_F_VERSION_1)) {
@@ -767,12 +768,13 @@ static int virtio_ccw_finalize_features(struct virtio_device *vdev)
 
        ccw = kzalloc(sizeof(*ccw), GFP_DMA | GFP_KERNEL);
        if (!ccw)
-               return 0;
+               return -ENOMEM;
 
        features = kzalloc(sizeof(*features), GFP_DMA | GFP_KERNEL);
-       if (!features)
+       if (!features) {
+               ret = -ENOMEM;
                goto out_free;
-
+       }
        /* Give virtio_ring a chance to accept features. */
        vring_transport_features(vdev);
 
@@ -783,7 +785,9 @@ static int virtio_ccw_finalize_features(struct virtio_device *vdev)
        ccw->flags = 0;
        ccw->count = sizeof(*features);
        ccw->cda = (__u32)(unsigned long)features;
-       ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_WRITE_FEAT);
+       ret = ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_WRITE_FEAT);
+       if (ret)
+               goto out_free;
 
        if (vcdev->revision == 0)
                goto out_free;
@@ -795,13 +799,13 @@ static int virtio_ccw_finalize_features(struct virtio_device *vdev)
        ccw->flags = 0;
        ccw->count = sizeof(*features);
        ccw->cda = (__u32)(unsigned long)features;
-       ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_WRITE_FEAT);
+       ret = ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_WRITE_FEAT);
 
 out_free:
        kfree(features);
        kfree(ccw);
 
-       return 0;
+       return ret;
 }
 
 static void virtio_ccw_get_config(struct virtio_device *vdev,