From 732c56e9845a5594a686eb4635397e91593dd4e1 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 27 Nov 2014 13:54:28 +0200 Subject: [PATCH] virtio_ccw: add support for 64 bit features. 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 Signed-off-by: Cornelia Huck Signed-off-by: Michael S. Tsirkin Reviewed-by: David Hildebrand --- drivers/s390/kvm/virtio_ccw.c | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/drivers/s390/kvm/virtio_ccw.c b/drivers/s390/kvm/virtio_ccw.c index 244d611a0df2..65d0c80236ee 100644 --- a/drivers/s390/kvm/virtio_ccw.c +++ b/drivers/s390/kvm/virtio_ccw.c @@ -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);