|
@@ -288,14 +288,20 @@ static int virtio_ccw_handle_set_vq(SubchDev *sch, CCW1 ccw, bool check_len,
|
|
return -EFAULT;
|
|
return -EFAULT;
|
|
}
|
|
}
|
|
if (is_legacy) {
|
|
if (is_legacy) {
|
|
- ccw_dstream_read(&sch->cds, linfo);
|
|
|
|
|
|
+ ret = ccw_dstream_read(&sch->cds, linfo);
|
|
|
|
+ if (ret) {
|
|
|
|
+ return ret;
|
|
|
|
+ }
|
|
linfo.queue = be64_to_cpu(linfo.queue);
|
|
linfo.queue = be64_to_cpu(linfo.queue);
|
|
linfo.align = be32_to_cpu(linfo.align);
|
|
linfo.align = be32_to_cpu(linfo.align);
|
|
linfo.index = be16_to_cpu(linfo.index);
|
|
linfo.index = be16_to_cpu(linfo.index);
|
|
linfo.num = be16_to_cpu(linfo.num);
|
|
linfo.num = be16_to_cpu(linfo.num);
|
|
ret = virtio_ccw_set_vqs(sch, NULL, &linfo);
|
|
ret = virtio_ccw_set_vqs(sch, NULL, &linfo);
|
|
} else {
|
|
} else {
|
|
- ccw_dstream_read(&sch->cds, info);
|
|
|
|
|
|
+ ret = ccw_dstream_read(&sch->cds, info);
|
|
|
|
+ if (ret) {
|
|
|
|
+ return ret;
|
|
|
|
+ }
|
|
info.desc = be64_to_cpu(info.desc);
|
|
info.desc = be64_to_cpu(info.desc);
|
|
info.index = be16_to_cpu(info.index);
|
|
info.index = be16_to_cpu(info.index);
|
|
info.num = be16_to_cpu(info.num);
|
|
info.num = be16_to_cpu(info.num);
|
|
@@ -371,7 +377,10 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
|
|
VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
|
|
VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
|
|
|
|
|
|
ccw_dstream_advance(&sch->cds, sizeof(features.features));
|
|
ccw_dstream_advance(&sch->cds, sizeof(features.features));
|
|
- ccw_dstream_read(&sch->cds, features.index);
|
|
|
|
|
|
+ ret = ccw_dstream_read(&sch->cds, features.index);
|
|
|
|
+ if (ret) {
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
if (features.index == 0) {
|
|
if (features.index == 0) {
|
|
if (dev->revision >= 1) {
|
|
if (dev->revision >= 1) {
|
|
/* Don't offer legacy features for modern devices. */
|
|
/* Don't offer legacy features for modern devices. */
|
|
@@ -392,9 +401,10 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
|
|
}
|
|
}
|
|
ccw_dstream_rewind(&sch->cds);
|
|
ccw_dstream_rewind(&sch->cds);
|
|
features.features = cpu_to_le32(features.features);
|
|
features.features = cpu_to_le32(features.features);
|
|
- ccw_dstream_write(&sch->cds, features.features);
|
|
|
|
- sch->curr_status.scsw.count = ccw.count - sizeof(features);
|
|
|
|
- ret = 0;
|
|
|
|
|
|
+ ret = ccw_dstream_write(&sch->cds, features.features);
|
|
|
|
+ if (!ret) {
|
|
|
|
+ sch->curr_status.scsw.count = ccw.count - sizeof(features);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
case CCW_CMD_WRITE_FEAT:
|
|
case CCW_CMD_WRITE_FEAT:
|
|
@@ -411,7 +421,10 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
|
|
if (!ccw.cda) {
|
|
if (!ccw.cda) {
|
|
ret = -EFAULT;
|
|
ret = -EFAULT;
|
|
} else {
|
|
} else {
|
|
- ccw_dstream_read(&sch->cds, features);
|
|
|
|
|
|
+ ret = ccw_dstream_read(&sch->cds, features);
|
|
|
|
+ if (ret) {
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
features.features = le32_to_cpu(features.features);
|
|
features.features = le32_to_cpu(features.features);
|
|
if (features.index == 0) {
|
|
if (features.index == 0) {
|
|
virtio_set_features(vdev,
|
|
virtio_set_features(vdev,
|
|
@@ -454,9 +467,10 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
|
|
ret = -EFAULT;
|
|
ret = -EFAULT;
|
|
} else {
|
|
} else {
|
|
virtio_bus_get_vdev_config(&dev->bus, vdev->config);
|
|
virtio_bus_get_vdev_config(&dev->bus, vdev->config);
|
|
- ccw_dstream_write_buf(&sch->cds, vdev->config, len);
|
|
|
|
- sch->curr_status.scsw.count = ccw.count - len;
|
|
|
|
- ret = 0;
|
|
|
|
|
|
+ ret = ccw_dstream_write_buf(&sch->cds, vdev->config, len);
|
|
|
|
+ if (ret) {
|
|
|
|
+ sch->curr_status.scsw.count = ccw.count - len;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
case CCW_CMD_WRITE_CONF:
|
|
case CCW_CMD_WRITE_CONF:
|
|
@@ -511,7 +525,10 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
|
|
if (!ccw.cda) {
|
|
if (!ccw.cda) {
|
|
ret = -EFAULT;
|
|
ret = -EFAULT;
|
|
} else {
|
|
} else {
|
|
- ccw_dstream_read(&sch->cds, status);
|
|
|
|
|
|
+ ret = ccw_dstream_read(&sch->cds, status);
|
|
|
|
+ if (ret) {
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
if (!(status & VIRTIO_CONFIG_S_DRIVER_OK)) {
|
|
if (!(status & VIRTIO_CONFIG_S_DRIVER_OK)) {
|
|
virtio_ccw_stop_ioeventfd(dev);
|
|
virtio_ccw_stop_ioeventfd(dev);
|
|
}
|
|
}
|
|
@@ -554,7 +571,10 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
|
|
if (!ccw.cda) {
|
|
if (!ccw.cda) {
|
|
ret = -EFAULT;
|
|
ret = -EFAULT;
|
|
} else {
|
|
} else {
|
|
- ccw_dstream_read(&sch->cds, indicators);
|
|
|
|
|
|
+ ret = ccw_dstream_read(&sch->cds, indicators);
|
|
|
|
+ if (ret) {
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
indicators = be64_to_cpu(indicators);
|
|
indicators = be64_to_cpu(indicators);
|
|
dev->indicators = get_indicator(indicators, sizeof(uint64_t));
|
|
dev->indicators = get_indicator(indicators, sizeof(uint64_t));
|
|
sch->curr_status.scsw.count = ccw.count - sizeof(indicators);
|
|
sch->curr_status.scsw.count = ccw.count - sizeof(indicators);
|
|
@@ -575,7 +595,10 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
|
|
if (!ccw.cda) {
|
|
if (!ccw.cda) {
|
|
ret = -EFAULT;
|
|
ret = -EFAULT;
|
|
} else {
|
|
} else {
|
|
- ccw_dstream_read(&sch->cds, indicators);
|
|
|
|
|
|
+ ret = ccw_dstream_read(&sch->cds, indicators);
|
|
|
|
+ if (ret) {
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
indicators = be64_to_cpu(indicators);
|
|
indicators = be64_to_cpu(indicators);
|
|
dev->indicators2 = get_indicator(indicators, sizeof(uint64_t));
|
|
dev->indicators2 = get_indicator(indicators, sizeof(uint64_t));
|
|
sch->curr_status.scsw.count = ccw.count - sizeof(indicators);
|
|
sch->curr_status.scsw.count = ccw.count - sizeof(indicators);
|
|
@@ -596,7 +619,10 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
|
|
if (!ccw.cda) {
|
|
if (!ccw.cda) {
|
|
ret = -EFAULT;
|
|
ret = -EFAULT;
|
|
} else {
|
|
} else {
|
|
- ccw_dstream_read(&sch->cds, vq_config.index);
|
|
|
|
|
|
+ ret = ccw_dstream_read(&sch->cds, vq_config.index);
|
|
|
|
+ if (ret) {
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
vq_config.index = be16_to_cpu(vq_config.index);
|
|
vq_config.index = be16_to_cpu(vq_config.index);
|
|
if (vq_config.index >= VIRTIO_QUEUE_MAX) {
|
|
if (vq_config.index >= VIRTIO_QUEUE_MAX) {
|
|
ret = -EINVAL;
|
|
ret = -EINVAL;
|
|
@@ -605,9 +631,10 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
|
|
vq_config.num_max = virtio_queue_get_num(vdev,
|
|
vq_config.num_max = virtio_queue_get_num(vdev,
|
|
vq_config.index);
|
|
vq_config.index);
|
|
vq_config.num_max = cpu_to_be16(vq_config.num_max);
|
|
vq_config.num_max = cpu_to_be16(vq_config.num_max);
|
|
- ccw_dstream_write(&sch->cds, vq_config.num_max);
|
|
|
|
- sch->curr_status.scsw.count = ccw.count - sizeof(vq_config);
|
|
|
|
- ret = 0;
|
|
|
|
|
|
+ ret = ccw_dstream_write(&sch->cds, vq_config.num_max);
|
|
|
|
+ if (!ret) {
|
|
|
|
+ sch->curr_status.scsw.count = ccw.count - sizeof(vq_config);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
case CCW_CMD_SET_IND_ADAPTER:
|
|
case CCW_CMD_SET_IND_ADAPTER:
|
|
@@ -664,7 +691,10 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
|
|
ret = -EFAULT;
|
|
ret = -EFAULT;
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
- ccw_dstream_read_buf(&sch->cds, &revinfo, 4);
|
|
|
|
|
|
+ ret = ccw_dstream_read_buf(&sch->cds, &revinfo, 4);
|
|
|
|
+ if (ret < 0) {
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
revinfo.revision = be16_to_cpu(revinfo.revision);
|
|
revinfo.revision = be16_to_cpu(revinfo.revision);
|
|
revinfo.length = be16_to_cpu(revinfo.length);
|
|
revinfo.length = be16_to_cpu(revinfo.length);
|
|
if (ccw.count < len + revinfo.length ||
|
|
if (ccw.count < len + revinfo.length ||
|