* [Qemu-devel] [PATCH 00/17] v4: virtio-serial fixes, new abi for port discovery
@ 2010-03-31 7:33 Amit Shah
2010-03-31 7:33 ` [Qemu-devel] [PATCH 01/17] virtio-serial: save/load: Ensure target has enough ports Amit Shah
` (2 more replies)
0 siblings, 3 replies; 23+ messages in thread
From: Amit Shah @ 2010-03-31 7:33 UTC (permalink / raw)
To: qemu list; +Cc: Amit Shah, Michael S. Tsirkin, Gerd Hoffmann, Juan Quintela
Hello,
These patches rework the way ports are announced to the guests. A
control message is used to let the guest know a new port is
added. Initial port discovery and port hot-plug work via this way now.
This was done to have the host and guest port numbering in sync to
avoid surprises after several hotplug/unplug operations and
migrations.
The ability to assign a particular port number to ports is also added
so that management software can control the placement of ports.
Differences from v3:
- Removed the QMP events (will ride on top of new infrastructure by
Luiz)
- Add flow control: ports can signal to the virtio-serial code to stop
sending data till it's ready to accept more.
- A fix for not abusing the virtqueue_push() api: we should signal to
the guest the number of bytes written for guest to consume. We were
using the number to signify the bytes consumed by hosts.
- Juan's comment about re-using control queue buffers
Overall:
- Users can set the port id they wish to instantiate ports at by using
the ,nr= parameter to 'virtserialport' and 'virtconsole' devices
- Migration fixes: refuse migration when:
- number of active ports is different between the src and destination
- max_nr_ports a device can support on the src is more
- If a qemu chardev connection to a port is closed on the dest while
it was open on the src, inform the guest about this. (Also do the
same for port closed on src but open on dest.)
- Use control messages for relaying new port information instead of
config space (changes abi)
- Propagate error message from guest in instantiating a port or a
device to the user.
- Handle scatter/gather for control output and data output from the
guest
- Fix abuse of virtio api in the virtqueue_push() function
- Add an API for the ports for flow control: ports can signal when
they're ready to accept data / stop sending data.
Amit Shah (17):
virtio-serial: save/load: Ensure target has enough ports
virtio-serial: save/load: Ensure nr_ports on src and dest are same.
virtio-serial: save/load: Ensure we have hot-plugged ports
instantiated
virtio-serial: save/load: Send target host connection status if
different
virtio-serial: Use control messages to notify guest of new ports
virtio-serial: whitespace: match surrounding code
virtio-serial: Remove redundant check for 0-sized write request
virtio-serial: Update copyright year to 2010
virtio-serial: Propagate errors in initialising ports / devices in
guest
virtio-serial: Send out guest data to ports only if port is opened
iov: Introduce a new file for helpers around iovs, add iov_from_buf()
iov: Add iov_to_buf and iov_size helpers
virtio-serial: Handle scatter-gather buffers for control messages
virtio-serial: Handle scatter/gather input from the guest
virtio-serial: Apps should consume all data that guest sends out /
Fix virtio api abuse
virtio-serial: Discard data that guest sends us when ports aren't
connected
virtio-serial: Implement flow control for individual ports
Makefile.objs | 1 +
hw/iov.c | 70 ++++++++++
hw/iov.h | 19 +++
hw/virtio-balloon.c | 35 +-----
hw/virtio-console.c | 11 +-
hw/virtio-net.c | 20 +---
hw/virtio-serial-bus.c | 326 +++++++++++++++++++++++++++++++++++------------
hw/virtio-serial.h | 34 ++++--
8 files changed, 368 insertions(+), 148 deletions(-)
create mode 100644 hw/iov.c
create mode 100644 hw/iov.h
^ permalink raw reply [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH 01/17] virtio-serial: save/load: Ensure target has enough ports
2010-03-31 7:33 [Qemu-devel] [PATCH 00/17] v4: virtio-serial fixes, new abi for port discovery Amit Shah
@ 2010-03-31 7:33 ` Amit Shah
2010-03-31 7:33 ` [Qemu-devel] [PATCH 02/17] virtio-serial: save/load: Ensure nr_ports on src and dest are same Amit Shah
2010-03-31 11:38 ` [Qemu-devel] Re: [PATCH 00/17] v4: virtio-serial fixes, new abi for port discovery Juan Quintela
2010-04-01 7:10 ` [Qemu-devel] " Gerd Hoffmann
2 siblings, 1 reply; 23+ messages in thread
From: Amit Shah @ 2010-03-31 7:33 UTC (permalink / raw)
To: qemu list; +Cc: Amit Shah, Michael S. Tsirkin, Gerd Hoffmann, Juan Quintela
The target could be started with max_nr_ports for a virtio-serial device
lesser than what was available on the source machine. Fail the migration
in such a case.
Signed-off-by: Amit Shah <amit.shah@redhat.com>
Reported-by: Juan Quintela <quintela@redhat.com>
---
hw/virtio-serial-bus.c | 13 +++++++++++--
1 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index 17c1ec1..9a7f0c1 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -374,10 +374,13 @@ static void virtio_serial_save(QEMUFile *f, void *opaque)
/* Items in struct VirtIOSerial */
+ qemu_put_be32s(f, &s->bus->max_nr_ports);
+
/* Do this because we might have hot-unplugged some ports */
nr_active_ports = 0;
- QTAILQ_FOREACH(port, &s->ports, next)
+ QTAILQ_FOREACH(port, &s->ports, next) {
nr_active_ports++;
+ }
qemu_put_be32s(f, &nr_active_ports);
@@ -399,7 +402,7 @@ static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id)
{
VirtIOSerial *s = opaque;
VirtIOSerialPort *port;
- uint32_t nr_active_ports;
+ uint32_t max_nr_ports, nr_active_ports;
unsigned int i;
if (version_id > 2) {
@@ -420,6 +423,12 @@ static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id)
/* Items in struct VirtIOSerial */
+ qemu_get_be32s(f, &max_nr_ports);
+ if (max_nr_ports > s->bus->max_nr_ports) {
+ /* Source could have more ports than us. Fail migration. */
+ return -EINVAL;
+ }
+
qemu_get_be32s(f, &nr_active_ports);
/* Items in struct VirtIOSerialPort */
--
1.6.2.5
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH 02/17] virtio-serial: save/load: Ensure nr_ports on src and dest are same.
2010-03-31 7:33 ` [Qemu-devel] [PATCH 01/17] virtio-serial: save/load: Ensure target has enough ports Amit Shah
@ 2010-03-31 7:33 ` Amit Shah
2010-03-31 7:33 ` [Qemu-devel] [PATCH 03/17] virtio-serial: save/load: Ensure we have hot-plugged ports instantiated Amit Shah
0 siblings, 1 reply; 23+ messages in thread
From: Amit Shah @ 2010-03-31 7:33 UTC (permalink / raw)
To: qemu list; +Cc: Amit Shah, Michael S. Tsirkin, Gerd Hoffmann, Juan Quintela
The number of ports on the source as well as the destination machines
should match. If they don't, it means some ports that got hotplugged on
the source aren't instantiated on the destination. Or that ports that
were hot-unplugged on the source are created on the destination.
Signed-off-by: Amit Shah <amit.shah@redhat.com>
Reported-by: Juan Quintela <quintela@redhat.com>
---
hw/virtio-serial-bus.c | 18 ++++++++++++++++--
1 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index 9a7f0c1..d31e62d 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -402,7 +402,7 @@ static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id)
{
VirtIOSerial *s = opaque;
VirtIOSerialPort *port;
- uint32_t max_nr_ports, nr_active_ports;
+ uint32_t max_nr_ports, nr_active_ports, nr_ports;
unsigned int i;
if (version_id > 2) {
@@ -419,7 +419,21 @@ static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id)
/* The config space */
qemu_get_be16s(f, &s->config.cols);
qemu_get_be16s(f, &s->config.rows);
- s->config.nr_ports = qemu_get_be32(f);
+ nr_ports = qemu_get_be32(f);
+
+ if (nr_ports != s->config.nr_ports) {
+ /*
+ * Source hot-plugged/unplugged ports and we don't have all of
+ * them here.
+ *
+ * Note: This condition cannot check for all hotplug/unplug
+ * events: eg, if one port was hot-plugged and one was
+ * unplugged, the nr_ports remains the same but the port id's
+ * would have changed and we won't catch it here. A later
+ * check for !find_port_by_id() will confirm if this happened.
+ */
+ return -EINVAL;
+ }
/* Items in struct VirtIOSerial */
--
1.6.2.5
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH 03/17] virtio-serial: save/load: Ensure we have hot-plugged ports instantiated
2010-03-31 7:33 ` [Qemu-devel] [PATCH 02/17] virtio-serial: save/load: Ensure nr_ports on src and dest are same Amit Shah
@ 2010-03-31 7:33 ` Amit Shah
2010-03-31 7:33 ` [Qemu-devel] [PATCH 04/17] virtio-serial: save/load: Send target host connection status if different Amit Shah
0 siblings, 1 reply; 23+ messages in thread
From: Amit Shah @ 2010-03-31 7:33 UTC (permalink / raw)
To: qemu list; +Cc: Amit Shah, Michael S. Tsirkin, Gerd Hoffmann, Juan Quintela
If some ports that were hot-plugged on the source are not available on
the destination, fail migration instead of trying to deref a NULL
pointer.
Signed-off-by: Amit Shah <amit.shah@redhat.com>
Reported-by: Juan Quintela <quintela@redhat.com>
---
hw/virtio-serial-bus.c | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index d31e62d..5316ef6 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -451,6 +451,13 @@ static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id)
id = qemu_get_be32(f);
port = find_port_by_id(s, id);
+ if (!port) {
+ /*
+ * The requested port was hot-plugged on the source but we
+ * don't have it
+ */
+ return -EINVAL;
+ }
port->guest_connected = qemu_get_byte(f);
}
--
1.6.2.5
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH 04/17] virtio-serial: save/load: Send target host connection status if different
2010-03-31 7:33 ` [Qemu-devel] [PATCH 03/17] virtio-serial: save/load: Ensure we have hot-plugged ports instantiated Amit Shah
@ 2010-03-31 7:33 ` Amit Shah
2010-03-31 7:33 ` [Qemu-devel] [PATCH 05/17] virtio-serial: Use control messages to notify guest of new ports Amit Shah
0 siblings, 1 reply; 23+ messages in thread
From: Amit Shah @ 2010-03-31 7:33 UTC (permalink / raw)
To: qemu list; +Cc: Amit Shah, Michael S. Tsirkin, Gerd Hoffmann, Juan Quintela
If the host connection to a port is closed on the destination machine
after migration, whereas the connection was open on the source, the
guest has to be informed of that.
Similar for a host connection open on the destination.
Signed-off-by: Amit Shah <amit.shah@redhat.com>
---
hw/virtio-serial-bus.c | 11 +++++++++++
1 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index 5316ef6..484dc94 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -395,6 +395,7 @@ static void virtio_serial_save(QEMUFile *f, void *opaque)
*/
qemu_put_be32s(f, &port->id);
qemu_put_byte(f, port->guest_connected);
+ qemu_put_byte(f, port->host_connected);
}
}
@@ -448,6 +449,7 @@ static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id)
/* Items in struct VirtIOSerialPort */
for (i = 0; i < nr_active_ports; i++) {
uint32_t id;
+ bool host_connected;
id = qemu_get_be32(f);
port = find_port_by_id(s, id);
@@ -460,6 +462,15 @@ static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id)
}
port->guest_connected = qemu_get_byte(f);
+ host_connected = qemu_get_byte(f);
+ if (host_connected != port->host_connected) {
+ /*
+ * We have to let the guest know of the host connection
+ * status change
+ */
+ send_control_event(port, VIRTIO_CONSOLE_PORT_OPEN,
+ port->host_connected);
+ }
}
return 0;
--
1.6.2.5
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH 05/17] virtio-serial: Use control messages to notify guest of new ports
2010-03-31 7:33 ` [Qemu-devel] [PATCH 04/17] virtio-serial: save/load: Send target host connection status if different Amit Shah
@ 2010-03-31 7:33 ` Amit Shah
2010-03-31 7:33 ` [Qemu-devel] [PATCH 06/17] virtio-serial: whitespace: match surrounding code Amit Shah
0 siblings, 1 reply; 23+ messages in thread
From: Amit Shah @ 2010-03-31 7:33 UTC (permalink / raw)
To: qemu list; +Cc: Amit Shah, Michael S. Tsirkin, Gerd Hoffmann, Juan Quintela
Allow the port 'id's to be set by a user on the command line. This is
needed by management apps that will want a stable port numbering scheme
for hot-plug/unplug and migration.
Since the port numbers are shared with the guest (to identify ports in
control messages), we just send a control message to the guest
indicating addition of new ports (hot-plug) or notifying the guest of
the available ports when the guest sends us a DEVICE_READY control
message.
Signed-off-by: Amit Shah <amit.shah@redhat.com>
---
hw/virtio-console.c | 2 +
hw/virtio-serial-bus.c | 181 +++++++++++++++++++++++++++++++-----------------
hw/virtio-serial.h | 17 +++--
3 files changed, 130 insertions(+), 70 deletions(-)
diff --git a/hw/virtio-console.c b/hw/virtio-console.c
index bd44ec6..17b221d 100644
--- a/hw/virtio-console.c
+++ b/hw/virtio-console.c
@@ -99,6 +99,7 @@ static VirtIOSerialPortInfo virtconsole_info = {
.exit = virtconsole_exitfn,
.qdev.props = (Property[]) {
DEFINE_PROP_UINT8("is_console", VirtConsole, port.is_console, 1),
+ DEFINE_PROP_UINT32("nr", VirtConsole, port.id, VIRTIO_CONSOLE_BAD_ID),
DEFINE_PROP_CHR("chardev", VirtConsole, chr),
DEFINE_PROP_STRING("name", VirtConsole, port.name),
DEFINE_PROP_END_OF_LIST(),
@@ -133,6 +134,7 @@ static VirtIOSerialPortInfo virtserialport_info = {
.init = virtserialport_initfn,
.exit = virtconsole_exitfn,
.qdev.props = (Property[]) {
+ DEFINE_PROP_UINT32("nr", VirtConsole, port.id, VIRTIO_CONSOLE_BAD_ID),
DEFINE_PROP_CHR("chardev", VirtConsole, chr),
DEFINE_PROP_STRING("name", VirtConsole, port.name),
DEFINE_PROP_END_OF_LIST(),
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index 484dc94..00e8616 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -41,6 +41,10 @@ struct VirtIOSerial {
VirtIOSerialBus *bus;
QTAILQ_HEAD(, VirtIOSerialPort) ports;
+
+ /* bitmap for identifying active ports */
+ uint32_t *ports_map;
+
struct virtio_console_config config;
};
@@ -48,6 +52,10 @@ static VirtIOSerialPort *find_port_by_id(VirtIOSerial *vser, uint32_t id)
{
VirtIOSerialPort *port;
+ if (id == VIRTIO_CONSOLE_BAD_ID) {
+ return NULL;
+ }
+
QTAILQ_FOREACH(port, &vser->ports, next) {
if (port->id == id)
return port;
@@ -208,14 +216,25 @@ static void handle_control_message(VirtIOSerial *vser, void *buf)
size_t buffer_len;
gcpkt = buf;
- port = find_port_by_id(vser, ldl_p(&gcpkt->id));
- if (!port)
- return;
cpkt.event = lduw_p(&gcpkt->event);
cpkt.value = lduw_p(&gcpkt->value);
+ port = find_port_by_id(vser, ldl_p(&gcpkt->id));
+ if (!port && cpkt.event != VIRTIO_CONSOLE_DEVICE_READY)
+ return;
+
switch(cpkt.event) {
+ case VIRTIO_CONSOLE_DEVICE_READY:
+ /*
+ * The device is up, we can now tell the device about all the
+ * ports we have here.
+ */
+ QTAILQ_FOREACH(port, &vser->ports, next) {
+ send_control_event(port, VIRTIO_CONSOLE_PORT_ADD, 1);
+ }
+ break;
+
case VIRTIO_CONSOLE_PORT_READY:
/*
* Now that we know the guest asked for the port name, we're
@@ -370,13 +389,16 @@ static void virtio_serial_save(QEMUFile *f, void *opaque)
/* The config space */
qemu_put_be16s(f, &s->config.cols);
qemu_put_be16s(f, &s->config.rows);
- qemu_put_be32s(f, &s->config.nr_ports);
- /* Items in struct VirtIOSerial */
+ qemu_put_be32s(f, &s->config.max_nr_ports);
+
+ /* The ports map */
- qemu_put_be32s(f, &s->bus->max_nr_ports);
+ qemu_put_buffer(f, (uint8_t *)s->ports_map,
+ sizeof(uint32_t) * (s->config.max_nr_ports + 31) / 32);
+
+ /* Ports */
- /* Do this because we might have hot-unplugged some ports */
nr_active_ports = 0;
QTAILQ_FOREACH(port, &s->ports, next) {
nr_active_ports++;
@@ -388,11 +410,6 @@ static void virtio_serial_save(QEMUFile *f, void *opaque)
* Items in struct VirtIOSerialPort.
*/
QTAILQ_FOREACH(port, &s->ports, next) {
- /*
- * We put the port number because we may not have an active
- * port at id 0 that's reserved for a console port, or in case
- * of ports that might have gotten unplugged
- */
qemu_put_be32s(f, &port->id);
qemu_put_byte(f, port->guest_connected);
qemu_put_byte(f, port->host_connected);
@@ -403,7 +420,8 @@ static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id)
{
VirtIOSerial *s = opaque;
VirtIOSerialPort *port;
- uint32_t max_nr_ports, nr_active_ports, nr_ports;
+ size_t ports_map_size;
+ uint32_t max_nr_ports, nr_active_ports, *ports_map;
unsigned int i;
if (version_id > 2) {
@@ -420,29 +438,28 @@ static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id)
/* The config space */
qemu_get_be16s(f, &s->config.cols);
qemu_get_be16s(f, &s->config.rows);
- nr_ports = qemu_get_be32(f);
- if (nr_ports != s->config.nr_ports) {
- /*
- * Source hot-plugged/unplugged ports and we don't have all of
- * them here.
- *
- * Note: This condition cannot check for all hotplug/unplug
- * events: eg, if one port was hot-plugged and one was
- * unplugged, the nr_ports remains the same but the port id's
- * would have changed and we won't catch it here. A later
- * check for !find_port_by_id() will confirm if this happened.
- */
+ qemu_get_be32s(f, &max_nr_ports);
+ if (max_nr_ports > s->config.max_nr_ports) {
+ /* Source could have had more ports than us. Fail migration. */
return -EINVAL;
}
- /* Items in struct VirtIOSerial */
+ ports_map_size = sizeof(uint32_t) * (max_nr_ports + 31) / 32;
+ ports_map = qemu_malloc(ports_map_size);
+ qemu_get_buffer(f, (uint8_t *)ports_map, ports_map_size);
- qemu_get_be32s(f, &max_nr_ports);
- if (max_nr_ports > s->bus->max_nr_ports) {
- /* Source could have more ports than us. Fail migration. */
- return -EINVAL;
+ for (i = 0; i < (max_nr_ports + 31) / 32; i++) {
+ if (ports_map[i] != s->ports_map[i]) {
+ /*
+ * Ports active on source and destination don't
+ * match. Fail migration.
+ */
+ qemu_free(ports_map);
+ return -EINVAL;
+ }
}
+ qemu_free(ports_map);
qemu_get_be32s(f, &nr_active_ports);
@@ -453,13 +470,6 @@ static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id)
id = qemu_get_be32(f);
port = find_port_by_id(s, id);
- if (!port) {
- /*
- * The requested port was hot-plugged on the source but we
- * don't have it
- */
- return -EINVAL;
- }
port->guest_connected = qemu_get_byte(f);
host_connected = qemu_get_byte(f);
@@ -472,7 +482,6 @@ static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id)
port->host_connected);
}
}
-
return 0;
}
@@ -507,6 +516,50 @@ static void virtser_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent)
indent, "", port->host_connected);
}
+/* This function is only used if a port id is not provided by the user */
+static uint32_t find_free_port_id(VirtIOSerial *vser)
+{
+ unsigned int i;
+
+ for (i = 0; i < (vser->config.max_nr_ports + 31) / 32; i++) {
+ uint32_t map, bit;
+
+ map = vser->ports_map[i];
+ bit = ffs(~map);
+ if (bit) {
+ return (bit - 1) + i * 32;
+ }
+ }
+ return VIRTIO_CONSOLE_BAD_ID;
+}
+
+static void mark_port_added(VirtIOSerial *vser, uint32_t port_id)
+{
+ unsigned int i;
+
+ i = port_id / 32;
+ vser->ports_map[i] |= 1U << (port_id % 32);
+}
+
+static void add_port(VirtIOSerial *vser, uint32_t port_id)
+{
+ mark_port_added(vser, port_id);
+
+ send_control_event(find_port_by_id(vser, port_id),
+ VIRTIO_CONSOLE_PORT_ADD, 1);
+}
+
+static void remove_port(VirtIOSerial *vser, uint32_t port_id)
+{
+ unsigned int i;
+
+ i = port_id / 32;
+ vser->ports_map[i] &= ~(1U << (port_id % 32));
+
+ send_control_event(find_port_by_id(vser, port_id),
+ VIRTIO_CONSOLE_PORT_REMOVE, 1);
+}
+
static int virtser_port_qdev_init(DeviceState *qdev, DeviceInfo *base)
{
VirtIOSerialDevice *dev = DO_UPCAST(VirtIOSerialDevice, qdev, qdev);
@@ -525,19 +578,36 @@ static int virtser_port_qdev_init(DeviceState *qdev, DeviceInfo *base)
*/
plugging_port0 = port->is_console && !find_port_by_id(port->vser, 0);
- if (port->vser->config.nr_ports == bus->max_nr_ports && !plugging_port0) {
- error_report("virtio-serial-bus: Maximum device limit reached");
+ if (find_port_by_id(port->vser, port->id)) {
+ error_report("virtio-serial-bus: A port already exists at id %u\n",
+ port->id);
return -1;
}
- dev->info = info;
+ if (port->id == VIRTIO_CONSOLE_BAD_ID) {
+ if (plugging_port0) {
+ port->id = 0;
+ } else {
+ port->id = find_free_port_id(port->vser);
+ if (port->id == VIRTIO_CONSOLE_BAD_ID) {
+ error_report("virtio-serial-bus: Maximum port limit for this device reached\n");
+ return -1;
+ }
+ }
+ }
+
+ if (port->id >= port->vser->config.max_nr_ports) {
+ error_report("virtio-serial-bus: Out-of-range port id specified, max. allowed: %u\n",
+ port->vser->config.max_nr_ports - 1);
+ return -1;
+ }
+
+ dev->info = info;
ret = info->init(dev);
if (ret) {
return ret;
}
- port->id = plugging_port0 ? 0 : port->vser->config.nr_ports++;
-
if (!use_multiport(port->vser)) {
/*
* Allow writes to guest in this case; we have no way of
@@ -550,6 +620,8 @@ static int virtser_port_qdev_init(DeviceState *qdev, DeviceInfo *base)
port->ivq = port->vser->ivqs[port->id];
port->ovq = port->vser->ovqs[port->id];
+ add_port(port->vser, port->id);
+
/* Send an update to the guest about this new port added */
virtio_notify_config(&port->vser->vdev);
@@ -562,26 +634,8 @@ static int virtser_port_qdev_exit(DeviceState *qdev)
VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, &dev->qdev);
VirtIOSerial *vser = port->vser;
- send_control_event(port, VIRTIO_CONSOLE_PORT_REMOVE, 1);
+ remove_port(port->vser, port->id);
- /*
- * Don't decrement nr_ports here; thus we keep a linearly
- * increasing port id. Not utilising an id again saves us a couple
- * of complications:
- *
- * - Not having to bother about sending the port id to the guest
- * kernel on hotplug or on addition of new ports; the guest can
- * also linearly increment the port number. This is preferable
- * because the config space won't have the need to store a
- * ports_map.
- *
- * - Extra state to be stored for all the "holes" that got created
- * so that we keep filling in the ids from the least available
- * index.
- *
- * When such a functionality is desired, a control message to add
- * a port can be introduced.
- */
QTAILQ_REMOVE(&vser->ports, port, next);
if (port->info->exit)
@@ -641,11 +695,12 @@ VirtIODevice *virtio_serial_init(DeviceState *dev, uint32_t max_nr_ports)
}
vser->config.max_nr_ports = max_nr_ports;
+ vser->ports_map = qemu_mallocz((max_nr_ports + 31) / 32);
/*
* Reserve location 0 for a console port for backward compat
* (old kernel, new qemu)
*/
- vser->config.nr_ports = 1;
+ mark_port_added(vser, 0);
vser->vdev.get_features = get_features;
vser->vdev.get_config = get_config;
diff --git a/hw/virtio-serial.h b/hw/virtio-serial.h
index f297b00..0548689 100644
--- a/hw/virtio-serial.h
+++ b/hw/virtio-serial.h
@@ -27,6 +27,8 @@
/* Features supported */
#define VIRTIO_CONSOLE_F_MULTIPORT 1
+#define VIRTIO_CONSOLE_BAD_ID (~(uint32_t)0)
+
struct virtio_console_config {
/*
* These two fields are used by VIRTIO_CONSOLE_F_SIZE which
@@ -36,7 +38,6 @@ struct virtio_console_config {
uint16_t rows;
uint32_t max_nr_ports;
- uint32_t nr_ports;
} __attribute__((packed));
struct virtio_console_control {
@@ -46,12 +47,14 @@ struct virtio_console_control {
};
/* Some events for the internal messages (control packets) */
-#define VIRTIO_CONSOLE_PORT_READY 0
-#define VIRTIO_CONSOLE_CONSOLE_PORT 1
-#define VIRTIO_CONSOLE_RESIZE 2
-#define VIRTIO_CONSOLE_PORT_OPEN 3
-#define VIRTIO_CONSOLE_PORT_NAME 4
-#define VIRTIO_CONSOLE_PORT_REMOVE 5
+#define VIRTIO_CONSOLE_DEVICE_READY 0
+#define VIRTIO_CONSOLE_PORT_ADD 1
+#define VIRTIO_CONSOLE_PORT_REMOVE 2
+#define VIRTIO_CONSOLE_PORT_READY 3
+#define VIRTIO_CONSOLE_CONSOLE_PORT 4
+#define VIRTIO_CONSOLE_RESIZE 5
+#define VIRTIO_CONSOLE_PORT_OPEN 6
+#define VIRTIO_CONSOLE_PORT_NAME 7
/* == In-qemu interface == */
--
1.6.2.5
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH 06/17] virtio-serial: whitespace: match surrounding code
2010-03-31 7:33 ` [Qemu-devel] [PATCH 05/17] virtio-serial: Use control messages to notify guest of new ports Amit Shah
@ 2010-03-31 7:33 ` Amit Shah
2010-03-31 7:33 ` [Qemu-devel] [PATCH 07/17] virtio-serial: Remove redundant check for 0-sized write request Amit Shah
0 siblings, 1 reply; 23+ messages in thread
From: Amit Shah @ 2010-03-31 7:33 UTC (permalink / raw)
To: qemu list; +Cc: Amit Shah, Michael S. Tsirkin, Gerd Hoffmann, Juan Quintela
The virtio-serial code doesn't mix declarations and definitions, so
separate them out on different lines.
Signed-off-by: Amit Shah <amit.shah@redhat.com>
---
hw/virtio-serial-bus.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index 00e8616..80f0259 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -354,7 +354,10 @@ static void handle_input(VirtIODevice *vdev, VirtQueue *vq)
static uint32_t get_features(VirtIODevice *vdev, uint32_t features)
{
- VirtIOSerial *vser = DO_UPCAST(VirtIOSerial, vdev, vdev);
+ VirtIOSerial *vser;
+
+ vser = DO_UPCAST(VirtIOSerial, vdev, vdev);
+
if (vser->bus->max_nr_ports > 1) {
features |= (1 << VIRTIO_CONSOLE_F_MULTIPORT);
}
--
1.6.2.5
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH 07/17] virtio-serial: Remove redundant check for 0-sized write request
2010-03-31 7:33 ` [Qemu-devel] [PATCH 06/17] virtio-serial: whitespace: match surrounding code Amit Shah
@ 2010-03-31 7:33 ` Amit Shah
2010-03-31 7:33 ` [Qemu-devel] [PATCH 08/17] virtio-serial: Update copyright year to 2010 Amit Shah
0 siblings, 1 reply; 23+ messages in thread
From: Amit Shah @ 2010-03-31 7:33 UTC (permalink / raw)
To: qemu list; +Cc: Amit Shah, Michael S. Tsirkin, Gerd Hoffmann, Juan Quintela
The check for a 0-sized write request to a guest port is not necessary;
the while loop below won't be executed in this case and all will be
fine.
Signed-off-by: Amit Shah <amit.shah@redhat.com>
---
hw/virtio-serial-bus.c | 3 ---
1 files changed, 0 insertions(+), 3 deletions(-)
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index 80f0259..4435c62 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -91,9 +91,6 @@ static size_t write_to_port(VirtIOSerialPort *port,
if (!virtio_queue_ready(vq)) {
return 0;
}
- if (!size) {
- return 0;
- }
while (offset < size) {
int i;
--
1.6.2.5
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH 08/17] virtio-serial: Update copyright year to 2010
2010-03-31 7:33 ` [Qemu-devel] [PATCH 07/17] virtio-serial: Remove redundant check for 0-sized write request Amit Shah
@ 2010-03-31 7:33 ` Amit Shah
2010-03-31 7:34 ` [Qemu-devel] [PATCH 09/17] virtio-serial: Propagate errors in initialising ports / devices in guest Amit Shah
0 siblings, 1 reply; 23+ messages in thread
From: Amit Shah @ 2010-03-31 7:33 UTC (permalink / raw)
To: qemu list; +Cc: Amit Shah, Michael S. Tsirkin, Gerd Hoffmann, Juan Quintela
Signed-off-by: Amit Shah <amit.shah@redhat.com>
---
hw/virtio-console.c | 2 +-
hw/virtio-serial-bus.c | 2 +-
hw/virtio-serial.h | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/hw/virtio-console.c b/hw/virtio-console.c
index 17b221d..bbbb6b8 100644
--- a/hw/virtio-console.c
+++ b/hw/virtio-console.c
@@ -1,7 +1,7 @@
/*
* Virtio Console and Generic Serial Port Devices
*
- * Copyright Red Hat, Inc. 2009
+ * Copyright Red Hat, Inc. 2009, 2010
*
* Authors:
* Amit Shah <amit.shah@redhat.com>
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index 4435c62..a19e751 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -1,7 +1,7 @@
/*
* A bus for connecting virtio serial and console ports
*
- * Copyright (C) 2009 Red Hat, Inc.
+ * Copyright (C) 2009, 2010 Red Hat, Inc.
*
* Author(s):
* Amit Shah <amit.shah@redhat.com>
diff --git a/hw/virtio-serial.h b/hw/virtio-serial.h
index 0548689..f023873 100644
--- a/hw/virtio-serial.h
+++ b/hw/virtio-serial.h
@@ -2,7 +2,7 @@
* Virtio Serial / Console Support
*
* Copyright IBM, Corp. 2008
- * Copyright Red Hat, Inc. 2009
+ * Copyright Red Hat, Inc. 2009, 2010
*
* Authors:
* Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
--
1.6.2.5
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH 09/17] virtio-serial: Propagate errors in initialising ports / devices in guest
2010-03-31 7:33 ` [Qemu-devel] [PATCH 08/17] virtio-serial: Update copyright year to 2010 Amit Shah
@ 2010-03-31 7:34 ` Amit Shah
2010-03-31 7:34 ` [Qemu-devel] [PATCH 10/17] virtio-serial: Send out guest data to ports only if port is opened Amit Shah
0 siblings, 1 reply; 23+ messages in thread
From: Amit Shah @ 2010-03-31 7:34 UTC (permalink / raw)
To: qemu list; +Cc: Amit Shah, Michael S. Tsirkin, Gerd Hoffmann, Juan Quintela
If adding of ports or devices in the guest fails we can send out a QMP
event so that management software can deal with it.
Signed-off-by: Amit Shah <amit.shah@redhat.com>
---
hw/virtio-serial-bus.c | 10 ++++++++++
1 files changed, 10 insertions(+), 0 deletions(-)
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index a19e751..33083af 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -223,6 +223,11 @@ static void handle_control_message(VirtIOSerial *vser, void *buf)
switch(cpkt.event) {
case VIRTIO_CONSOLE_DEVICE_READY:
+ if (!cpkt.value) {
+ error_report("virtio-serial-bus: Guest failure in adding device %s\n",
+ vser->bus->qbus.name);
+ break;
+ }
/*
* The device is up, we can now tell the device about all the
* ports we have here.
@@ -233,6 +238,11 @@ static void handle_control_message(VirtIOSerial *vser, void *buf)
break;
case VIRTIO_CONSOLE_PORT_READY:
+ if (!cpkt.value) {
+ error_report("virtio-serial-bus: Guest failure in adding port %u for device %s\n",
+ port->id, vser->bus->qbus.name);
+ break;
+ }
/*
* Now that we know the guest asked for the port name, we're
* sure the guest has initialised whatever state is necessary
--
1.6.2.5
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH 10/17] virtio-serial: Send out guest data to ports only if port is opened
2010-03-31 7:34 ` [Qemu-devel] [PATCH 09/17] virtio-serial: Propagate errors in initialising ports / devices in guest Amit Shah
@ 2010-03-31 7:34 ` Amit Shah
2010-03-31 7:34 ` [Qemu-devel] [PATCH 11/17] iov: Introduce a new file for helpers around iovs, add iov_from_buf() Amit Shah
0 siblings, 1 reply; 23+ messages in thread
From: Amit Shah @ 2010-03-31 7:34 UTC (permalink / raw)
To: qemu list; +Cc: Amit Shah, Michael S. Tsirkin, Gerd Hoffmann, Juan Quintela
Data should be written only when ports are open.
Signed-off-by: Amit Shah <amit.shah@redhat.com>
---
hw/virtio-serial-bus.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index 33083af..236e300 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -335,6 +335,11 @@ static void handle_output(VirtIODevice *vdev, VirtQueue *vq)
goto next_buf;
}
+ if (!port->host_connected) {
+ ret = 0;
+ goto next_buf;
+ }
+
/*
* A port may not have any handler registered for consuming the
* data that the guest sends or it may not have a chardev associated
--
1.6.2.5
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH 11/17] iov: Introduce a new file for helpers around iovs, add iov_from_buf()
2010-03-31 7:34 ` [Qemu-devel] [PATCH 10/17] virtio-serial: Send out guest data to ports only if port is opened Amit Shah
@ 2010-03-31 7:34 ` Amit Shah
2010-03-31 7:34 ` [Qemu-devel] [PATCH 12/17] iov: Add iov_to_buf and iov_size helpers Amit Shah
0 siblings, 1 reply; 23+ messages in thread
From: Amit Shah @ 2010-03-31 7:34 UTC (permalink / raw)
To: qemu list; +Cc: Amit Shah, Michael S. Tsirkin, Gerd Hoffmann, Juan Quintela
The virtio-net code uses iov_fill() which fills an iov from a linear
buffer. The virtio-serial-bus code does something similar in an
open-coded function.
Create a new iov.c file that has iov_from_buf().
Convert virtio-net and virtio-serial-bus over to use this functionality.
virtio-net used ints to hold sizes, the new function is going to use
size_t types.
Later commits will add the opposite functionality -- going from an iov
to a linear buffer.
Signed-off-by: Amit Shah <amit.shah@redhat.com>
---
Makefile.objs | 1 +
hw/iov.c | 33 +++++++++++++++++++++++++++++++++
hw/iov.h | 16 ++++++++++++++++
hw/virtio-net.c | 20 +++-----------------
hw/virtio-serial-bus.c | 15 +++++++--------
5 files changed, 60 insertions(+), 25 deletions(-)
create mode 100644 hw/iov.c
create mode 100644 hw/iov.h
diff --git a/Makefile.objs b/Makefile.objs
index 233fbba..2ab09d7 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -129,6 +129,7 @@ user-obj-y += cutils.o cache-utils.o
hw-obj-y =
hw-obj-y += vl.o loader.o
+hw-obj-y += iov.o
hw-obj-y += virtio.o virtio-console.o
hw-obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o
hw-obj-y += fw_cfg.o pci.o pci_host.o pcie_host.o
diff --git a/hw/iov.c b/hw/iov.c
new file mode 100644
index 0000000..07bd499
--- /dev/null
+++ b/hw/iov.c
@@ -0,0 +1,33 @@
+/*
+ * Helpers for getting linearized buffers from iov / filling buffers into iovs
+ *
+ * Copyright IBM, Corp. 2007, 2008
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * Author(s):
+ * Anthony Liguori <aliguori@us.ibm.com>
+ * Amit Shah <amit.shah@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ */
+
+#include "iov.h"
+
+size_t iov_from_buf(struct iovec *iov, unsigned int iovcnt,
+ const void *buf, size_t size)
+{
+ size_t offset;
+ unsigned int i;
+
+ offset = 0;
+ for (i = 0; offset < size && i < iovcnt; i++) {
+ size_t len;
+
+ len = MIN(iov[i].iov_len, size - offset);
+
+ memcpy(iov[i].iov_base, buf + offset, len);
+ offset += len;
+ }
+ return offset;
+}
diff --git a/hw/iov.h b/hw/iov.h
new file mode 100644
index 0000000..5e3e541
--- /dev/null
+++ b/hw/iov.h
@@ -0,0 +1,16 @@
+/*
+ * Helpers for getting linearized buffers from iov / filling buffers into iovs
+ *
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * Author(s):
+ * Amit Shah <amit.shah@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ */
+
+#include "qemu-common.h"
+
+size_t iov_from_buf(struct iovec *iov, unsigned int iovcnt,
+ const void *buf, size_t size);
diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index be33c68..273e7f9 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -11,6 +11,7 @@
*
*/
+#include "iov.h"
#include "virtio.h"
#include "net.h"
#include "net/checksum.h"
@@ -423,21 +424,6 @@ static void work_around_broken_dhclient(struct virtio_net_hdr *hdr,
}
}
-static int iov_fill(struct iovec *iov, int iovcnt, const void *buf, int count)
-{
- int offset, i;
-
- offset = i = 0;
- while (offset < count && i < iovcnt) {
- int len = MIN(iov[i].iov_len, count - offset);
- memcpy(iov[i].iov_base, buf + offset, len);
- offset += len;
- i++;
- }
-
- return offset;
-}
-
static int receive_header(VirtIONet *n, struct iovec *iov, int iovcnt,
const void *buf, size_t size, size_t hdr_len)
{
@@ -573,8 +559,8 @@ static ssize_t virtio_net_receive(VLANClientState *nc, const uint8_t *buf, size_
}
/* copy in packet. ugh */
- len = iov_fill(sg, elem.in_num,
- buf + offset, size - offset);
+ len = iov_from_buf(sg, elem.in_num,
+ buf + offset, size - offset);
total += len;
/* signal other side */
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index 236e300..ee45146 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -15,6 +15,7 @@
* the COPYING file in the top-level directory.
*/
+#include "iov.h"
#include "monitor.h"
#include "qemu-queue.h"
#include "sysbus.h"
@@ -84,27 +85,25 @@ static size_t write_to_port(VirtIOSerialPort *port,
{
VirtQueueElement elem;
VirtQueue *vq;
- size_t offset = 0;
- size_t len = 0;
+ size_t offset;
vq = port->ivq;
if (!virtio_queue_ready(vq)) {
return 0;
}
+ offset = 0;
while (offset < size) {
- int i;
+ size_t len;
if (!virtqueue_pop(vq, &elem)) {
break;
}
- for (i = 0; offset < size && i < elem.in_num; i++) {
- len = MIN(elem.in_sg[i].iov_len, size - offset);
+ len = iov_from_buf(elem.in_sg, elem.in_num,
+ buf + offset, size - offset);
+ offset += len;
- memcpy(elem.in_sg[i].iov_base, buf + offset, len);
- offset += len;
- }
virtqueue_push(vq, &elem, len);
}
--
1.6.2.5
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH 12/17] iov: Add iov_to_buf and iov_size helpers
2010-03-31 7:34 ` [Qemu-devel] [PATCH 11/17] iov: Introduce a new file for helpers around iovs, add iov_from_buf() Amit Shah
@ 2010-03-31 7:34 ` Amit Shah
2010-03-31 7:34 ` [Qemu-devel] [PATCH 13/17] virtio-serial: Handle scatter-gather buffers for control messages Amit Shah
0 siblings, 1 reply; 23+ messages in thread
From: Amit Shah @ 2010-03-31 7:34 UTC (permalink / raw)
To: qemu list; +Cc: Amit Shah, Michael S. Tsirkin, Gerd Hoffmann, Juan Quintela
iov_to_buf() puts the buffer contents in the iov in a linearized buffer.
iov_size() gets the length of the contents in the iov.
The iov_to_buf() function is the memcpy_to_iovec() function that was
used in virtio-ballon.c.
Signed-off-by: Amit Shah <amit.shah@redhat.com>
---
hw/iov.c | 37 +++++++++++++++++++++++++++++++++++++
hw/iov.h | 3 +++
hw/virtio-balloon.c | 35 ++++-------------------------------
3 files changed, 44 insertions(+), 31 deletions(-)
diff --git a/hw/iov.c b/hw/iov.c
index 07bd499..588cd04 100644
--- a/hw/iov.c
+++ b/hw/iov.c
@@ -31,3 +31,40 @@ size_t iov_from_buf(struct iovec *iov, unsigned int iovcnt,
}
return offset;
}
+
+size_t iov_to_buf(const struct iovec *iov, const unsigned int iovcnt,
+ void *buf, size_t offset, size_t size)
+{
+ uint8_t *ptr;
+ size_t iov_off, buf_off;
+ unsigned int i;
+
+ ptr = buf;
+ iov_off = 0;
+ buf_off = 0;
+ for (i = 0; i < iovcnt && size; i++) {
+ if (offset < (iov_off + iov[i].iov_len)) {
+ size_t len = MIN((iov_off + iov[i].iov_len) - offset , size);
+
+ memcpy(ptr + buf_off, iov[i].iov_base + (offset - iov_off), len);
+
+ buf_off += len;
+ offset += len;
+ size -= len;
+ }
+ iov_off += iov[i].iov_len;
+ }
+ return buf_off;
+}
+
+size_t iov_size(const struct iovec *iov, const unsigned int iovcnt)
+{
+ size_t len;
+ unsigned int i;
+
+ len = 0;
+ for (i = 0; i < iovcnt; i++) {
+ len += iov[i].iov_len;
+ }
+ return len;
+}
diff --git a/hw/iov.h b/hw/iov.h
index 5e3e541..60a8547 100644
--- a/hw/iov.h
+++ b/hw/iov.h
@@ -14,3 +14,6 @@
size_t iov_from_buf(struct iovec *iov, unsigned int iovcnt,
const void *buf, size_t size);
+size_t iov_to_buf(const struct iovec *iov, const unsigned int iovcnt,
+ void *buf, size_t offset, size_t size);
+size_t iov_size(const struct iovec *iov, const unsigned int iovcnt);
diff --git a/hw/virtio-balloon.c b/hw/virtio-balloon.c
index f55f7ec..152af80 100644
--- a/hw/virtio-balloon.c
+++ b/hw/virtio-balloon.c
@@ -11,6 +11,7 @@
*
*/
+#include "iov.h"
#include "qemu-common.h"
#include "virtio.h"
#include "pc.h"
@@ -92,33 +93,6 @@ static QObject *get_stats_qobject(VirtIOBalloon *dev)
return QOBJECT(dict);
}
-/* FIXME: once we do a virtio refactoring, this will get subsumed into common
- * code */
-static size_t memcpy_from_iovector(void *data, size_t offset, size_t size,
- struct iovec *iov, int iovlen)
-{
- int i;
- uint8_t *ptr = data;
- size_t iov_off = 0;
- size_t data_off = 0;
-
- for (i = 0; i < iovlen && size; i++) {
- if (offset < (iov_off + iov[i].iov_len)) {
- size_t len = MIN((iov_off + iov[i].iov_len) - offset , size);
-
- memcpy(ptr + data_off, iov[i].iov_base + (offset - iov_off), len);
-
- data_off += len;
- offset += len;
- size -= len;
- }
-
- iov_off += iov[i].iov_len;
- }
-
- return data_off;
-}
-
static void virtio_balloon_handle_output(VirtIODevice *vdev, VirtQueue *vq)
{
VirtIOBalloon *s = to_virtio_balloon(vdev);
@@ -128,8 +102,7 @@ static void virtio_balloon_handle_output(VirtIODevice *vdev, VirtQueue *vq)
size_t offset = 0;
uint32_t pfn;
- while (memcpy_from_iovector(&pfn, offset, 4,
- elem.out_sg, elem.out_num) == 4) {
+ while (iov_to_buf(elem.out_sg, elem.out_num, &pfn, offset, 4) == 4) {
ram_addr_t pa;
ram_addr_t addr;
@@ -181,8 +154,8 @@ static void virtio_balloon_receive_stats(VirtIODevice *vdev, VirtQueue *vq)
*/
reset_stats(s);
- while (memcpy_from_iovector(&stat, offset, sizeof(stat), elem->out_sg,
- elem->out_num) == sizeof(stat)) {
+ while (iov_to_buf(elem->out_sg, elem->out_num, &stat, offset, sizeof(stat))
+ == sizeof(stat)) {
uint16_t tag = tswap16(stat.tag);
uint64_t val = tswap64(stat.val);
--
1.6.2.5
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH 13/17] virtio-serial: Handle scatter-gather buffers for control messages
2010-03-31 7:34 ` [Qemu-devel] [PATCH 12/17] iov: Add iov_to_buf and iov_size helpers Amit Shah
@ 2010-03-31 7:34 ` Amit Shah
2010-03-31 7:34 ` [Qemu-devel] [PATCH 14/17] virtio-serial: Handle scatter/gather input from the guest Amit Shah
0 siblings, 1 reply; 23+ messages in thread
From: Amit Shah @ 2010-03-31 7:34 UTC (permalink / raw)
To: qemu list
Cc: Amit Shah, Avi Kivity, Michael S. Tsirkin, Gerd Hoffmann,
Juan Quintela
Current control messages are small enough to not be split into multiple
buffers but we could run into such a situation in the future or a
malicious guest could cause such a situation.
So handle the entire iov request for control messages.
Also ensure the size of the control request is >= what we expect
otherwise we risk accessing memory that we don't own.
Signed-off-by: Amit Shah <amit.shah@redhat.com>
CC: Avi Kivity <avi@redhat.com>
Reported-by: Avi Kivity <avi@redhat.com>
---
hw/virtio-serial-bus.c | 34 +++++++++++++++++++++++++++++++---
1 files changed, 31 insertions(+), 3 deletions(-)
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index ee45146..88fb723 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -204,7 +204,7 @@ size_t virtio_serial_guest_ready(VirtIOSerialPort *port)
}
/* Guest wants to notify us of some event */
-static void handle_control_message(VirtIOSerial *vser, void *buf)
+static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len)
{
struct VirtIOSerialPort *port;
struct virtio_console_control cpkt, *gcpkt;
@@ -213,6 +213,11 @@ static void handle_control_message(VirtIOSerial *vser, void *buf)
gcpkt = buf;
+ if (len < sizeof(cpkt)) {
+ /* The guest sent an invalid control packet */
+ return;
+ }
+
cpkt.event = lduw_p(&gcpkt->event);
cpkt.value = lduw_p(&gcpkt->value);
@@ -306,12 +311,35 @@ static void control_out(VirtIODevice *vdev, VirtQueue *vq)
{
VirtQueueElement elem;
VirtIOSerial *vser;
+ uint8_t *buf;
+ size_t len;
vser = DO_UPCAST(VirtIOSerial, vdev, vdev);
+ len = 0;
+ buf = NULL;
while (virtqueue_pop(vq, &elem)) {
- handle_control_message(vser, elem.out_sg[0].iov_base);
- virtqueue_push(vq, &elem, elem.out_sg[0].iov_len);
+ size_t cur_len, copied;
+
+ cur_len = iov_size(elem.out_sg, elem.out_num);
+ /*
+ * Allocate a new buf only if we didn't have one previously or
+ * if the size of the buf differs
+ */
+ if (cur_len > len) {
+ if (len) {
+ qemu_free(buf);
+ }
+ buf = qemu_malloc(cur_len);
+ len = cur_len;
+ }
+ copied = iov_to_buf(elem.out_sg, elem.out_num, buf, 0, len);
+
+ handle_control_message(vser, buf, copied);
+ virtqueue_push(vq, &elem, copied);
+ }
+ if (len) {
+ qemu_free(buf);
}
virtio_notify(vdev, vq);
}
--
1.6.2.5
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH 14/17] virtio-serial: Handle scatter/gather input from the guest
2010-03-31 7:34 ` [Qemu-devel] [PATCH 13/17] virtio-serial: Handle scatter-gather buffers for control messages Amit Shah
@ 2010-03-31 7:34 ` Amit Shah
2010-03-31 7:34 ` [Qemu-devel] [PATCH 15/17] virtio-serial: Apps should consume all data that guest sends out / Fix virtio api abuse Amit Shah
0 siblings, 1 reply; 23+ messages in thread
From: Amit Shah @ 2010-03-31 7:34 UTC (permalink / raw)
To: qemu list
Cc: Amit Shah, Avi Kivity, Michael S. Tsirkin, Gerd Hoffmann,
Juan Quintela
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 | 12 ++++++++----
1 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index 88fb723..49a6baa 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -354,7 +354,8 @@ static void handle_output(VirtIODevice *vdev, VirtQueue *vq)
while (virtqueue_pop(vq, &elem)) {
VirtIOSerialPort *port;
- size_t ret;
+ uint8_t *buf;
+ size_t ret, buf_size;
port = find_port_by_vq(vser, vq);
if (!port) {
@@ -377,9 +378,12 @@ static void handle_output(VirtIODevice *vdev, VirtQueue *vq)
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);
+ buf_size = iov_size(elem.out_sg, elem.out_num);
+ buf = qemu_malloc(buf_size);
+ ret = iov_to_buf(elem.out_sg, elem.out_num, buf, 0, buf_size);
+
+ ret = port->info->have_data(port, buf, ret);
+ qemu_free(buf);
next_buf:
virtqueue_push(vq, &elem, ret);
--
1.6.2.5
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH 15/17] virtio-serial: Apps should consume all data that guest sends out / Fix virtio api abuse
2010-03-31 7:34 ` [Qemu-devel] [PATCH 14/17] virtio-serial: Handle scatter/gather input from the guest Amit Shah
@ 2010-03-31 7:34 ` Amit Shah
2010-03-31 7:34 ` [Qemu-devel] [PATCH 16/17] virtio-serial: Discard data that guest sends us when ports aren't connected Amit Shah
2010-03-31 13:53 ` [Qemu-devel] [PATCH 15/17] virtio-serial: Apps should consume all data that guest sends out / Fix virtio api abuse Gerd Hoffmann
0 siblings, 2 replies; 23+ messages in thread
From: Amit Shah @ 2010-03-31 7:34 UTC (permalink / raw)
To: qemu list; +Cc: Amit Shah, Michael S. Tsirkin, Gerd Hoffmann, Juan Quintela
We cannot indicate to the guest how much data was consumed by an app for
out_bufs. So we just have to assume the apps will consume all the data
that are handed over to them.
Fix the virtio api abuse in control_out() and handle_output().
Signed-off-by: Amit Shah <amit.shah@redhat.com>
---
hw/virtio-console.c | 7 ++-----
hw/virtio-serial-bus.c | 6 +++---
hw/virtio-serial.h | 6 +++---
3 files changed, 8 insertions(+), 11 deletions(-)
diff --git a/hw/virtio-console.c b/hw/virtio-console.c
index bbbb6b8..caea11f 100644
--- a/hw/virtio-console.c
+++ b/hw/virtio-console.c
@@ -20,14 +20,11 @@ typedef struct VirtConsole {
/* Callback function that's called when the guest sends us data */
-static size_t flush_buf(VirtIOSerialPort *port, const uint8_t *buf, size_t len)
+static void flush_buf(VirtIOSerialPort *port, const uint8_t *buf, size_t len)
{
VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
- ssize_t ret;
- ret = qemu_chr_write(vcon->chr, buf, len);
-
- return ret < 0 ? 0 : ret;
+ qemu_chr_write(vcon->chr, buf, len);
}
/* Readiness of the guest to accept data on a port */
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index 49a6baa..7ac46f5 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -336,7 +336,7 @@ static void control_out(VirtIODevice *vdev, VirtQueue *vq)
copied = iov_to_buf(elem.out_sg, elem.out_num, buf, 0, len);
handle_control_message(vser, buf, copied);
- virtqueue_push(vq, &elem, copied);
+ virtqueue_push(vq, &elem, 0);
}
if (len) {
qemu_free(buf);
@@ -382,11 +382,11 @@ static void handle_output(VirtIODevice *vdev, VirtQueue *vq)
buf = qemu_malloc(buf_size);
ret = iov_to_buf(elem.out_sg, elem.out_num, buf, 0, buf_size);
- ret = port->info->have_data(port, buf, ret);
+ port->info->have_data(port, buf, ret);
qemu_free(buf);
next_buf:
- virtqueue_push(vq, &elem, ret);
+ virtqueue_push(vq, &elem, 0);
}
virtio_notify(vdev, vq);
}
diff --git a/hw/virtio-serial.h b/hw/virtio-serial.h
index f023873..62d76a2 100644
--- a/hw/virtio-serial.h
+++ b/hw/virtio-serial.h
@@ -136,10 +136,10 @@ struct VirtIOSerialPortInfo {
/*
* Guest wrote some data to the port. This data is handed over to
- * the app via this callback. The app should return the number of
- * bytes it successfully consumed.
+ * the app via this callback. The app is supposed to consume all
+ * the data that is presented to it.
*/
- size_t (*have_data)(VirtIOSerialPort *port, const uint8_t *buf, size_t len);
+ void (*have_data)(VirtIOSerialPort *port, const uint8_t *buf, size_t len);
};
/* Interface to the virtio-serial bus */
--
1.6.2.5
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH 16/17] virtio-serial: Discard data that guest sends us when ports aren't connected
2010-03-31 7:34 ` [Qemu-devel] [PATCH 15/17] virtio-serial: Apps should consume all data that guest sends out / Fix virtio api abuse Amit Shah
@ 2010-03-31 7:34 ` Amit Shah
2010-03-31 7:34 ` [Qemu-devel] [PATCH 17/17] virtio-serial: Implement flow control for individual ports Amit Shah
2010-03-31 11:07 ` [Qemu-devel] Re: [PATCH 16/17] virtio-serial: Discard data that guest sends us when ports aren't connected Juan Quintela
2010-03-31 13:53 ` [Qemu-devel] [PATCH 15/17] virtio-serial: Apps should consume all data that guest sends out / Fix virtio api abuse Gerd Hoffmann
1 sibling, 2 replies; 23+ messages in thread
From: Amit Shah @ 2010-03-31 7:34 UTC (permalink / raw)
To: qemu list; +Cc: Amit Shah, Michael S. Tsirkin, Gerd Hoffmann, Juan Quintela
Before the earlier patch, we relied on incorrect virtio api usage to
signal to the guest that a particular buffer wasn't consumed by the
host.
After fixing that, we now just discard the data the guest sends us while
a host port is disconnected or doesn't have a handler registered for
consuming data.
This commit really doesn't change anything from the current behaviour,
just makes the code slightly better by spinning off data handling to
ports in another function.
Signed-off-by: Amit Shah <amit.shah@redhat.com>
---
hw/virtio-serial-bus.c | 68 ++++++++++++++++++++++--------------------------
1 files changed, 31 insertions(+), 37 deletions(-)
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index 7ac46f5..757de7c 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -111,6 +111,29 @@ static size_t write_to_port(VirtIOSerialPort *port,
return offset;
}
+static void flush_queued_data(VirtIOSerialPort *port, bool discard)
+{
+ VirtQueue *vq;
+ VirtQueueElement elem;
+
+ vq = port->ovq;
+ while (virtqueue_pop(vq, &elem)) {
+ uint8_t *buf;
+ size_t ret, buf_size;
+
+ if (!discard) {
+ buf_size = iov_size(elem.out_sg, elem.out_num);
+ buf = qemu_malloc(buf_size);
+ ret = iov_to_buf(elem.out_sg, elem.out_num, buf, 0, buf_size);
+
+ port->info->have_data(port, buf, ret);
+ qemu_free(buf);
+ }
+ virtqueue_push(vq, &elem, 0);
+ }
+ virtio_notify(&port->vser->vdev, vq);
+}
+
static size_t send_control_msg(VirtIOSerialPort *port, void *buf, size_t len)
{
VirtQueueElement elem;
@@ -348,47 +371,18 @@ static void control_out(VirtIODevice *vdev, VirtQueue *vq)
static void handle_output(VirtIODevice *vdev, VirtQueue *vq)
{
VirtIOSerial *vser;
- VirtQueueElement elem;
+ VirtIOSerialPort *port;
+ bool discard;
vser = DO_UPCAST(VirtIOSerial, vdev, vdev);
+ port = find_port_by_vq(vser, vq);
- while (virtqueue_pop(vq, &elem)) {
- VirtIOSerialPort *port;
- uint8_t *buf;
- size_t ret, buf_size;
-
- port = find_port_by_vq(vser, vq);
- if (!port) {
- ret = 0;
- goto next_buf;
- }
-
- if (!port->host_connected) {
- ret = 0;
- goto next_buf;
- }
-
- /*
- * A port may not have any handler registered for consuming the
- * data that the guest sends or it may not have a chardev associated
- * with it. Just ignore the data in that case.
- */
- if (!port->info->have_data) {
- ret = 0;
- goto next_buf;
- }
-
- buf_size = iov_size(elem.out_sg, elem.out_num);
- buf = qemu_malloc(buf_size);
- ret = iov_to_buf(elem.out_sg, elem.out_num, buf, 0, buf_size);
-
- port->info->have_data(port, buf, ret);
- qemu_free(buf);
-
- next_buf:
- virtqueue_push(vq, &elem, 0);
+ discard = false;
+ if (!port || !port->host_connected || !port->info->have_data) {
+ discard = true;
}
- virtio_notify(vdev, vq);
+
+ flush_queued_data(port, discard);
}
static void handle_input(VirtIODevice *vdev, VirtQueue *vq)
--
1.6.2.5
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH 17/17] virtio-serial: Implement flow control for individual ports
2010-03-31 7:34 ` [Qemu-devel] [PATCH 16/17] virtio-serial: Discard data that guest sends us when ports aren't connected Amit Shah
@ 2010-03-31 7:34 ` Amit Shah
2010-03-31 11:07 ` [Qemu-devel] Re: [PATCH 16/17] virtio-serial: Discard data that guest sends us when ports aren't connected Juan Quintela
1 sibling, 0 replies; 23+ messages in thread
From: Amit Shah @ 2010-03-31 7:34 UTC (permalink / raw)
To: qemu list; +Cc: Amit Shah, Michael S. Tsirkin, Gerd Hoffmann, Juan Quintela
Individual ports can now signal to the virtio-serial core to stop
sending data if the ports cannot immediately handle new data. When a
port later unthrottles, any data queued up in the virtqueue are sent to
the port.
Signed-off-by: Amit Shah <amit.shah@redhat.com>
---
hw/virtio-serial-bus.c | 24 ++++++++++++++++++++++++
hw/virtio-serial.h | 9 +++++++++
2 files changed, 33 insertions(+), 0 deletions(-)
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index 757de7c..7b57ed8 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -187,6 +187,11 @@ int virtio_serial_close(VirtIOSerialPort *port)
port->host_connected = false;
send_control_event(port, VIRTIO_CONSOLE_PORT_OPEN, 0);
+ /*
+ * If there's any data the guest sent which the app didn't
+ * consume, discard it.
+ */
+ flush_queued_data(port, true);
return 0;
}
@@ -226,6 +231,21 @@ size_t virtio_serial_guest_ready(VirtIOSerialPort *port)
return 0;
}
+void virtio_serial_throttle_port(VirtIOSerialPort *port, bool throttle)
+{
+ if (!port) {
+ return;
+ }
+
+ if (throttle) {
+ port->throttled = true;
+ return;
+ }
+
+ port->throttled = false;
+ flush_queued_data(port, false);
+}
+
/* Guest wants to notify us of some event */
static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len)
{
@@ -382,6 +402,10 @@ static void handle_output(VirtIODevice *vdev, VirtQueue *vq)
discard = true;
}
+ if (!discard && port->throttled) {
+ return;
+ }
+
flush_queued_data(port, discard);
}
diff --git a/hw/virtio-serial.h b/hw/virtio-serial.h
index 62d76a2..a93b545 100644
--- a/hw/virtio-serial.h
+++ b/hw/virtio-serial.h
@@ -110,6 +110,8 @@ struct VirtIOSerialPort {
bool guest_connected;
/* Is this device open for IO on the host? */
bool host_connected;
+ /* Do apps not want to receive data? */
+ bool throttled;
};
struct VirtIOSerialPortInfo {
@@ -173,4 +175,11 @@ ssize_t virtio_serial_write(VirtIOSerialPort *port, const uint8_t *buf,
*/
size_t virtio_serial_guest_ready(VirtIOSerialPort *port);
+/*
+ * Flow control: Ports can signal to the virtio-serial core to stop
+ * sending data or re-start sending data, depending on the 'throttle'
+ * value here.
+ */
+void virtio_serial_throttle_port(VirtIOSerialPort *port, bool throttle);
+
#endif
--
1.6.2.5
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] Re: [PATCH 16/17] virtio-serial: Discard data that guest sends us when ports aren't connected
2010-03-31 7:34 ` [Qemu-devel] [PATCH 16/17] virtio-serial: Discard data that guest sends us when ports aren't connected Amit Shah
2010-03-31 7:34 ` [Qemu-devel] [PATCH 17/17] virtio-serial: Implement flow control for individual ports Amit Shah
@ 2010-03-31 11:07 ` Juan Quintela
1 sibling, 0 replies; 23+ messages in thread
From: Juan Quintela @ 2010-03-31 11:07 UTC (permalink / raw)
To: Amit Shah; +Cc: Gerd Hoffmann, qemu list, Michael S. Tsirkin
Amit Shah <amit.shah@redhat.com> wrote:
Hi
> + buf_size = iov_size(elem.out_sg, elem.out_num);
> + buf = qemu_malloc(buf_size);
> + ret = iov_to_buf(elem.out_sg, elem.out_num, buf, 0, buf_size);
This is independent of the this series, but I think this idiom is going
to be very common, perhaps having a helper that does it makes sense?
Later, Juan.
^ permalink raw reply [flat|nested] 23+ messages in thread
* [Qemu-devel] Re: [PATCH 00/17] v4: virtio-serial fixes, new abi for port discovery
2010-03-31 7:33 [Qemu-devel] [PATCH 00/17] v4: virtio-serial fixes, new abi for port discovery Amit Shah
2010-03-31 7:33 ` [Qemu-devel] [PATCH 01/17] virtio-serial: save/load: Ensure target has enough ports Amit Shah
@ 2010-03-31 11:38 ` Juan Quintela
2010-04-01 7:10 ` [Qemu-devel] " Gerd Hoffmann
2 siblings, 0 replies; 23+ messages in thread
From: Juan Quintela @ 2010-03-31 11:38 UTC (permalink / raw)
To: Amit Shah; +Cc: Gerd Hoffmann, qemu list, Michael S. Tsirkin
Amit Shah <amit.shah@redhat.com> wrote:
> Hello,
>
> These patches rework the way ports are announced to the guests. A
> control message is used to let the guest know a new port is
> added. Initial port discovery and port hot-plug work via this way now.
>
> This was done to have the host and guest port numbering in sync to
> avoid surprises after several hotplug/unplug operations and
> migrations.
>
> The ability to assign a particular port number to ports is also added
> so that management software can control the placement of ports.
>
> Differences from v3:
> - Removed the QMP events (will ride on top of new infrastructure by
> Luiz)
>
> - Add flow control: ports can signal to the virtio-serial code to stop
> sending data till it's ready to accept more.
>
> - A fix for not abusing the virtqueue_push() api: we should signal to
> the guest the number of bytes written for guest to consume. We were
> using the number to signify the bytes consumed by hosts.
>
> - Juan's comment about re-using control queue buffers
>
> Overall:
> - Users can set the port id they wish to instantiate ports at by using
> the ,nr= parameter to 'virtserialport' and 'virtconsole' devices
>
> - Migration fixes: refuse migration when:
> - number of active ports is different between the src and destination
> - max_nr_ports a device can support on the src is more
>
> - If a qemu chardev connection to a port is closed on the dest while
> it was open on the src, inform the guest about this. (Also do the
> same for port closed on src but open on dest.)
>
> - Use control messages for relaying new port information instead of
> config space (changes abi)
>
> - Propagate error message from guest in instantiating a port or a
> device to the user.
>
> - Handle scatter/gather for control output and data output from the
> guest
>
> - Fix abuse of virtio api in the virtqueue_push() function
>
> - Add an API for the ports for flow control: ports can signal when
> they're ready to accept data / stop sending data.
Reviewed-by: Juan Quintela <quintela@redhat.com>
Later, Juan.
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Qemu-devel] [PATCH 15/17] virtio-serial: Apps should consume all data that guest sends out / Fix virtio api abuse
2010-03-31 7:34 ` [Qemu-devel] [PATCH 15/17] virtio-serial: Apps should consume all data that guest sends out / Fix virtio api abuse Amit Shah
2010-03-31 7:34 ` [Qemu-devel] [PATCH 16/17] virtio-serial: Discard data that guest sends us when ports aren't connected Amit Shah
@ 2010-03-31 13:53 ` Gerd Hoffmann
2010-03-31 14:06 ` Amit Shah
1 sibling, 1 reply; 23+ messages in thread
From: Gerd Hoffmann @ 2010-03-31 13:53 UTC (permalink / raw)
To: Amit Shah; +Cc: Juan Quintela, qemu list, Michael S. Tsirkin
> /* Callback function that's called when the guest sends us data */
> -static size_t flush_buf(VirtIOSerialPort *port, const uint8_t *buf, size_t len)
> +static void flush_buf(VirtIOSerialPort *port, const uint8_t *buf, size_t len)
> {
> VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
> - ssize_t ret;
>
> - ret = qemu_chr_write(vcon->chr, buf, len);
> -
> - return ret< 0 ? 0 : ret;
> + qemu_chr_write(vcon->chr, buf, len);
> }
Ok, so we loose data in case qemu_chr_write wasn't able to write out all
data? Nice opportunity to show flow control in action here ;)
On failed+partial writes just put the remaining data into a buffer and
throttle the port until all buffered data has been successfully written
to the chardev.
Incremental patch is fine to avoid the chicken-egg issue (throttling is
added by patch #17).
cheers,
Gerd
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Qemu-devel] [PATCH 15/17] virtio-serial: Apps should consume all data that guest sends out / Fix virtio api abuse
2010-03-31 13:53 ` [Qemu-devel] [PATCH 15/17] virtio-serial: Apps should consume all data that guest sends out / Fix virtio api abuse Gerd Hoffmann
@ 2010-03-31 14:06 ` Amit Shah
0 siblings, 0 replies; 23+ messages in thread
From: Amit Shah @ 2010-03-31 14:06 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: Juan Quintela, qemu list, Michael S. Tsirkin
On (Wed) Mar 31 2010 [15:53:59], Gerd Hoffmann wrote:
>> /* Callback function that's called when the guest sends us data */
>> -static size_t flush_buf(VirtIOSerialPort *port, const uint8_t *buf, size_t len)
>> +static void flush_buf(VirtIOSerialPort *port, const uint8_t *buf, size_t len)
>> {
>> VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
>> - ssize_t ret;
>>
>> - ret = qemu_chr_write(vcon->chr, buf, len);
>> -
>> - return ret< 0 ? 0 : ret;
>> + qemu_chr_write(vcon->chr, buf, len);
>> }
>
> Ok, so we loose data in case qemu_chr_write wasn't able to write out all
> data? Nice opportunity to show flow control in action here ;)
>
> On failed+partial writes just put the remaining data into a buffer and
> throttle the port until all buffered data has been successfully written
> to the chardev.
>
> Incremental patch is fine to avoid the chicken-egg issue (throttling is
> added by patch #17).
Yes, that's what I intend to do in a later patch (series).
Amit
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Qemu-devel] [PATCH 00/17] v4: virtio-serial fixes, new abi for port discovery
2010-03-31 7:33 [Qemu-devel] [PATCH 00/17] v4: virtio-serial fixes, new abi for port discovery Amit Shah
2010-03-31 7:33 ` [Qemu-devel] [PATCH 01/17] virtio-serial: save/load: Ensure target has enough ports Amit Shah
2010-03-31 11:38 ` [Qemu-devel] Re: [PATCH 00/17] v4: virtio-serial fixes, new abi for port discovery Juan Quintela
@ 2010-04-01 7:10 ` Gerd Hoffmann
2 siblings, 0 replies; 23+ messages in thread
From: Gerd Hoffmann @ 2010-04-01 7:10 UTC (permalink / raw)
To: Amit Shah; +Cc: Juan Quintela, qemu list, Michael S. Tsirkin
On 03/31/10 09:33, Amit Shah wrote:
> Hello,
>
> These patches rework the way ports are announced to the guests. A
> control message is used to let the guest know a new port is
> added. Initial port discovery and port hot-plug work via this way now.
>
> This was done to have the host and guest port numbering in sync to
> avoid surprises after several hotplug/unplug operations and
> migrations.
>
> The ability to assign a particular port number to ports is also added
> so that management software can control the placement of ports.
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
cheers,
Gerd
^ permalink raw reply [flat|nested] 23+ messages in thread
end of thread, other threads:[~2010-04-01 7:11 UTC | newest]
Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-03-31 7:33 [Qemu-devel] [PATCH 00/17] v4: virtio-serial fixes, new abi for port discovery Amit Shah
2010-03-31 7:33 ` [Qemu-devel] [PATCH 01/17] virtio-serial: save/load: Ensure target has enough ports Amit Shah
2010-03-31 7:33 ` [Qemu-devel] [PATCH 02/17] virtio-serial: save/load: Ensure nr_ports on src and dest are same Amit Shah
2010-03-31 7:33 ` [Qemu-devel] [PATCH 03/17] virtio-serial: save/load: Ensure we have hot-plugged ports instantiated Amit Shah
2010-03-31 7:33 ` [Qemu-devel] [PATCH 04/17] virtio-serial: save/load: Send target host connection status if different Amit Shah
2010-03-31 7:33 ` [Qemu-devel] [PATCH 05/17] virtio-serial: Use control messages to notify guest of new ports Amit Shah
2010-03-31 7:33 ` [Qemu-devel] [PATCH 06/17] virtio-serial: whitespace: match surrounding code Amit Shah
2010-03-31 7:33 ` [Qemu-devel] [PATCH 07/17] virtio-serial: Remove redundant check for 0-sized write request Amit Shah
2010-03-31 7:33 ` [Qemu-devel] [PATCH 08/17] virtio-serial: Update copyright year to 2010 Amit Shah
2010-03-31 7:34 ` [Qemu-devel] [PATCH 09/17] virtio-serial: Propagate errors in initialising ports / devices in guest Amit Shah
2010-03-31 7:34 ` [Qemu-devel] [PATCH 10/17] virtio-serial: Send out guest data to ports only if port is opened Amit Shah
2010-03-31 7:34 ` [Qemu-devel] [PATCH 11/17] iov: Introduce a new file for helpers around iovs, add iov_from_buf() Amit Shah
2010-03-31 7:34 ` [Qemu-devel] [PATCH 12/17] iov: Add iov_to_buf and iov_size helpers Amit Shah
2010-03-31 7:34 ` [Qemu-devel] [PATCH 13/17] virtio-serial: Handle scatter-gather buffers for control messages Amit Shah
2010-03-31 7:34 ` [Qemu-devel] [PATCH 14/17] virtio-serial: Handle scatter/gather input from the guest Amit Shah
2010-03-31 7:34 ` [Qemu-devel] [PATCH 15/17] virtio-serial: Apps should consume all data that guest sends out / Fix virtio api abuse Amit Shah
2010-03-31 7:34 ` [Qemu-devel] [PATCH 16/17] virtio-serial: Discard data that guest sends us when ports aren't connected Amit Shah
2010-03-31 7:34 ` [Qemu-devel] [PATCH 17/17] virtio-serial: Implement flow control for individual ports Amit Shah
2010-03-31 11:07 ` [Qemu-devel] Re: [PATCH 16/17] virtio-serial: Discard data that guest sends us when ports aren't connected Juan Quintela
2010-03-31 13:53 ` [Qemu-devel] [PATCH 15/17] virtio-serial: Apps should consume all data that guest sends out / Fix virtio api abuse Gerd Hoffmann
2010-03-31 14:06 ` Amit Shah
2010-03-31 11:38 ` [Qemu-devel] Re: [PATCH 00/17] v4: virtio-serial fixes, new abi for port discovery Juan Quintela
2010-04-01 7:10 ` [Qemu-devel] " Gerd Hoffmann
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).