aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/s390/kvm/virtio_ccw.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/drivers/s390/kvm/virtio_ccw.c b/drivers/s390/kvm/virtio_ccw.c
index 6f1fa1773e76..f8d8fdb26b72 100644
--- a/drivers/s390/kvm/virtio_ccw.c
+++ b/drivers/s390/kvm/virtio_ccw.c
@@ -65,6 +65,7 @@ struct virtio_ccw_device {
65 bool is_thinint; 65 bool is_thinint;
66 bool going_away; 66 bool going_away;
67 bool device_lost; 67 bool device_lost;
68 unsigned int config_ready;
68 void *airq_info; 69 void *airq_info;
69}; 70};
70 71
@@ -833,8 +834,11 @@ static void virtio_ccw_get_config(struct virtio_device *vdev,
833 if (ret) 834 if (ret)
834 goto out_free; 835 goto out_free;
835 836
836 memcpy(vcdev->config, config_area, sizeof(vcdev->config)); 837 memcpy(vcdev->config, config_area, offset + len);
837 memcpy(buf, &vcdev->config[offset], len); 838 if (buf)
839 memcpy(buf, &vcdev->config[offset], len);
840 if (vcdev->config_ready < offset + len)
841 vcdev->config_ready = offset + len;
838 842
839out_free: 843out_free:
840 kfree(config_area); 844 kfree(config_area);
@@ -857,6 +861,9 @@ static void virtio_ccw_set_config(struct virtio_device *vdev,
857 if (!config_area) 861 if (!config_area)
858 goto out_free; 862 goto out_free;
859 863
864 /* Make sure we don't overwrite fields. */
865 if (vcdev->config_ready < offset)
866 virtio_ccw_get_config(vdev, 0, NULL, offset);
860 memcpy(&vcdev->config[offset], buf, len); 867 memcpy(&vcdev->config[offset], buf, len);
861 /* Write the config area to the host. */ 868 /* Write the config area to the host. */
862 memcpy(config_area, vcdev->config, sizeof(vcdev->config)); 869 memcpy(config_area, vcdev->config, sizeof(vcdev->config));