]> rtime.felk.cvut.cz Git - zynq/linux.git/blobdiff - drivers/s390/kvm/virtio_ccw.c
Merge tag 'v4.0.8' into xlnx_4.0.8-rt6
[zynq/linux.git] / drivers / s390 / kvm / virtio_ccw.c
index 71d7802aa8b48b75aee89ea2aae167436c746d65..57171173739faf956a5b6e490c0a6bac87f5150a 100644 (file)
@@ -65,6 +65,7 @@ struct virtio_ccw_device {
        bool is_thinint;
        bool going_away;
        bool device_lost;
+       unsigned int config_ready;
        void *airq_info;
 };
 
@@ -833,8 +834,11 @@ static void virtio_ccw_get_config(struct virtio_device *vdev,
        if (ret)
                goto out_free;
 
-       memcpy(vcdev->config, config_area, sizeof(vcdev->config));
-       memcpy(buf, &vcdev->config[offset], len);
+       memcpy(vcdev->config, config_area, offset + len);
+       if (buf)
+               memcpy(buf, &vcdev->config[offset], len);
+       if (vcdev->config_ready < offset + len)
+               vcdev->config_ready = offset + len;
 
 out_free:
        kfree(config_area);
@@ -857,6 +861,9 @@ static void virtio_ccw_set_config(struct virtio_device *vdev,
        if (!config_area)
                goto out_free;
 
+       /* Make sure we don't overwrite fields. */
+       if (vcdev->config_ready < offset)
+               virtio_ccw_get_config(vdev, 0, NULL, offset);
        memcpy(&vcdev->config[offset], buf, len);
        /* Write the config area to the host. */
        memcpy(config_area, vcdev->config, sizeof(vcdev->config));