virtio_ccw: add support for 64 bit features.
authorMichael S. Tsirkin <mst@redhat.com>
Thu, 27 Nov 2014 11:54:28 +0000 (13:54 +0200)
committerMichael S. Tsirkin <mst@redhat.com>
Tue, 9 Dec 2014 10:05:24 +0000 (12:05 +0200)
Negotiate full 64 bit features.
Change u32 to u64, make sure to use 1ULL everywhere.

Note: devices guarantee that VERSION_1 is clear unless
revision 1 is negotiated.

Note: We don't need to re-setup the ccw, but we do it
for clarity.

Based on patches by Rusty, Thomas Huth and Cornelia.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: David Hildebrand <dahi@linux.vnet.ibm.com>
drivers/s390/kvm/virtio_ccw.c

index 244d611..65d0c80 100644 (file)
@@ -664,7 +664,8 @@ static u64 virtio_ccw_get_features(struct virtio_device *vdev)
 {
        struct virtio_ccw_device *vcdev = to_vc_device(vdev);
        struct virtio_feature_desc *features;
-       int ret, rc;
+       int ret;
+       u64 rc;
        struct ccw1 *ccw;
 
        ccw = kzalloc(sizeof(*ccw), GFP_DMA | GFP_KERNEL);
@@ -677,7 +678,6 @@ static u64 virtio_ccw_get_features(struct virtio_device *vdev)
                goto out_free;
        }
        /* Read the feature bits from the host. */
-       /* TODO: Features > 32 bits */
        features->index = 0;
        ccw->cmd_code = CCW_CMD_READ_FEAT;
        ccw->flags = 0;
@@ -691,6 +691,16 @@ static u64 virtio_ccw_get_features(struct virtio_device *vdev)
 
        rc = le32_to_cpu(features->features);
 
+       /* Read second half of the feature bits from the host. */
+       features->index = 1;
+       ccw->cmd_code = CCW_CMD_READ_FEAT;
+       ccw->flags = 0;
+       ccw->count = sizeof(*features);
+       ccw->cda = (__u32)(unsigned long)features;
+       ret = ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_READ_FEAT);
+       if (ret == 0)
+               rc |= (u64)le32_to_cpu(features->features) << 32;
+
 out_free:
        kfree(features);
        kfree(ccw);
@@ -714,12 +724,18 @@ static void virtio_ccw_finalize_features(struct virtio_device *vdev)
        /* Give virtio_ring a chance to accept features. */
        vring_transport_features(vdev);
 
-       /* Make sure we don't have any features > 32 bits! */
-       BUG_ON((u32)vdev->features != vdev->features);
-
        features->index = 0;
-       features->features = cpu_to_le32(vdev->features);
-       /* Write the feature bits to the host. */
+       features->features = cpu_to_le32((u32)vdev->features);
+       /* Write the first half of the feature bits to the host. */
+       ccw->cmd_code = CCW_CMD_WRITE_FEAT;
+       ccw->flags = 0;
+       ccw->count = sizeof(*features);
+       ccw->cda = (__u32)(unsigned long)features;
+       ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_WRITE_FEAT);
+
+       features->index = 1;
+       features->features = cpu_to_le32(vdev->features >> 32);
+       /* Write the second half of the feature bits to the host. */
        ccw->cmd_code = CCW_CMD_WRITE_FEAT;
        ccw->flags = 0;
        ccw->count = sizeof(*features);