diff options
author | Sascha Silbe <silbe@linux.vnet.ibm.com> | 2016-09-27 15:43:36 +0200 |
---|---|---|
committer | Michael S. Tsirkin <mst@redhat.com> | 2016-10-10 01:16:57 +0300 |
commit | 09da01c3f205b008ce0c7a960092bcc03b383b50 (patch) | |
tree | 3a14b14ecfd3209e884e351e40658c183e17801e /hw/char | |
parent | 17871f71fd2ff5d76196051470e9604bfb6f0c09 (diff) |
virtio-serial: add plumbing for virtio console emergency write support
Add the infrastructure required for the virtio 1.0 "emergency write"
(VIRTIO_CONSOLE_F_EMERG_WRITE) feature. Because we don't touch the
size of the configuration area, guests will not be able to actually
make use of this without further patches.
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Sascha Silbe <silbe@linux.vnet.ibm.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'hw/char')
-rw-r--r-- | hw/char/virtio-serial-bus.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c index db57a38546..57419b2b6a 100644 --- a/hw/char/virtio-serial-bus.c +++ b/hw/char/virtio-serial-bus.c @@ -75,6 +75,19 @@ static VirtIOSerialPort *find_port_by_name(char *name) return NULL; } +static VirtIOSerialPort *find_first_connected_console(VirtIOSerial *vser) +{ + VirtIOSerialPort *port; + + QTAILQ_FOREACH(port, &vser->ports, next) { + VirtIOSerialPortClass const *vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port); + if (vsc->is_console && port->host_connected) { + return port; + } + } + return NULL; +} + static bool use_multiport(VirtIOSerial *vser) { VirtIODevice *vdev = VIRTIO_DEVICE(vser); @@ -547,6 +560,29 @@ static void get_config(VirtIODevice *vdev, uint8_t *config_data) vser->serial.max_virtserial_ports); } +/* Guest sent new config info */ +static void set_config(VirtIODevice *vdev, const uint8_t *config_data) +{ + VirtIOSerial *vser = VIRTIO_SERIAL(vdev); + struct virtio_console_config *config = + (struct virtio_console_config *)config_data; + uint8_t emerg_wr_lo = le32_to_cpu(config->emerg_wr); + VirtIOSerialPort *port = find_first_connected_console(vser); + VirtIOSerialPortClass *vsc; + + if (!config->emerg_wr) { + return; + } + /* Make sure we don't misdetect an emergency write when the guest + * does a short config write after an emergency write. */ + config->emerg_wr = 0; + if (!port) { + return; + } + vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port); + (void)vsc->have_data(port, &emerg_wr_lo, 1); +} + static void guest_reset(VirtIOSerial *vser) { VirtIOSerialPort *port; @@ -1098,6 +1134,7 @@ static void virtio_serial_class_init(ObjectClass *klass, void *data) vdc->unrealize = virtio_serial_device_unrealize; vdc->get_features = get_features; vdc->get_config = get_config; + vdc->set_config = set_config; vdc->set_status = set_status; vdc->reset = vser_reset; vdc->save = virtio_serial_save_device; |