@@ -338,11 +338,12 @@ static void handle_output(VirtIODevice *vdev, VirtQueue *vq)
while (virtqueue_pop(vq, &elem)) {
VirtIOSerialPort *port;
- size_t ret;
+ size_t len;
+ unsigned int i;
+ len = 0;
port = find_port_by_vq(vser, vq);
if (!port) {
- ret = 0;
goto next_buf;
}
@@ -352,16 +353,23 @@ static void handle_output(VirtIODevice *vdev, VirtQueue *vq)
* with it. Just ignore the data in that case.
*/
if (!port->info->have_data) {
- ret = 0;
goto next_buf;
}
- /* The guest always sends only one sg */
- ret = port->info->have_data(port, elem.out_sg[0].iov_base,
- elem.out_sg[0].iov_len);
+ for (i = 0; i < elem.out_num; i++) {
+ size_t ret;
+
+ ret = port->info->have_data(port, elem.out_sg[0].iov_base,
+ elem.out_sg[0].iov_len);
+ if (ret < elem.out_sg[0].iov_len) {
+ /* We couldn't write the entire iov; stop processing now */
+ break;
+ }
+ len += ret;
+ }
next_buf:
- virtqueue_push(vq, &elem, ret);
+ virtqueue_push(vq, &elem, len);
}
virtio_notify(vdev, vq);
}
Current guests don't send more than one iov but it can change later. Ensure we handle that case. Signed-off-by: Amit Shah <amit.shah@redhat.com> CC: Avi Kivity <avi@redhat.com> --- hw/virtio-serial-bus.c | 22 +++++++++++++++------- 1 files changed, 15 insertions(+), 7 deletions(-)