aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/kvm
diff options
context:
space:
mode:
authorMichael S. Tsirkin <mst@redhat.com>2014-11-27 06:54:28 -0500
committerMichael S. Tsirkin <mst@redhat.com>2014-12-09 05:05:24 -0500
commit732c56e9845a5594a686eb4635397e91593dd4e1 (patch)
treec54a3dccf5e47c6a2a185a78ad825e165fbd1e23 /drivers/s390/kvm
parent93d389f82078cf7197152fb10d21977da0883420 (diff)
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 <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>
Diffstat (limited to 'drivers/s390/kvm')
-rw-r--r--drivers/s390/kvm/virtio_ccw.c30
1 files 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)
664{ 664{
665 struct virtio_ccw_device *vcdev = to_vc_device(vdev); 665 struct virtio_ccw_device *vcdev = to_vc_device(vdev);
666 struct virtio_feature_desc *features; 666 struct virtio_feature_desc *features;
667 int ret, rc; 667 int ret;
668 u64 rc;
668 struct ccw1 *ccw; 669 struct ccw1 *ccw;
669 670
670 ccw = kzalloc(sizeof(*ccw), GFP_DMA | GFP_KERNEL); 671 ccw = kzalloc(sizeof(*ccw), GFP_DMA | GFP_KERNEL);
@@ -677,7 +678,6 @@ static u64 virtio_ccw_get_features(struct virtio_device *vdev)
677 goto out_free; 678 goto out_free;
678 } 679 }
679 /* Read the feature bits from the host. */ 680 /* Read the feature bits from the host. */
680 /* TODO: Features > 32 bits */
681 features->index = 0; 681 features->index = 0;
682 ccw->cmd_code = CCW_CMD_READ_FEAT; 682 ccw->cmd_code = CCW_CMD_READ_FEAT;
683 ccw->flags = 0; 683 ccw->flags = 0;
@@ -691,6 +691,16 @@ static u64 virtio_ccw_get_features(struct virtio_device *vdev)
691 691
692 rc = le32_to_cpu(features->features); 692 rc = le32_to_cpu(features->features);
693 693
694 /* Read second half of the feature bits from the host. */
695 features->index = 1;
696 ccw->cmd_code = CCW_CMD_READ_FEAT;
697 ccw->flags = 0;
698 ccw->count = sizeof(*features);
699 ccw->cda = (__u32)(unsigned long)features;
700 ret = ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_READ_FEAT);
701 if (ret == 0)
702 rc |= (u64)le32_to_cpu(features->features) << 32;
703
694out_free: 704out_free:
695 kfree(features); 705 kfree(features);
696 kfree(ccw); 706 kfree(ccw);
@@ -714,12 +724,18 @@ static void virtio_ccw_finalize_features(struct virtio_device *vdev)
714 /* Give virtio_ring a chance to accept features. */ 724 /* Give virtio_ring a chance to accept features. */
715 vring_transport_features(vdev); 725 vring_transport_features(vdev);
716 726
717 /* Make sure we don't have any features > 32 bits! */
718 BUG_ON((u32)vdev->features != vdev->features);
719
720 features->index = 0; 727 features->index = 0;
721 features->features = cpu_to_le32(vdev->features); 728 features->features = cpu_to_le32((u32)vdev->features);
722 /* Write the feature bits to the host. */ 729 /* Write the first half of the feature bits to the host. */
730 ccw->cmd_code = CCW_CMD_WRITE_FEAT;
731 ccw->flags = 0;
732 ccw->count = sizeof(*features);
733 ccw->cda = (__u32)(unsigned long)features;
734 ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_WRITE_FEAT);
735
736 features->index = 1;
737 features->features = cpu_to_le32(vdev->features >> 32);
738 /* Write the second half of the feature bits to the host. */
723 ccw->cmd_code = CCW_CMD_WRITE_FEAT; 739 ccw->cmd_code = CCW_CMD_WRITE_FEAT;
724 ccw->flags = 0; 740 ccw->flags = 0;
725 ccw->count = sizeof(*features); 741 ccw->count = sizeof(*features);