> Implement the part of the virtio spec that allows to notify the virtio > driver about terminal resizes. Gate the new resize support behind the > console-size property, which defaults to off. To implement the property, > restore VirtIOSerial::host_features (previously removed by commit > d0660e5b7fc7e97926232d13d2500a16df32b310). > > The virtio spec contains two methods to inform the guest about console > size: > > For legacy drivers, we have only one port and we put the terminal size > in the config space and inject the config changed interrupt. > > For multiport devices, we use the control virtqueue to send a > packet containing the terminal size. Unfortunately, old versions > of the Linux kernel used an incorrect order for the fields (rows > then cols instead of cols then rows), until it was fixed by commit > 5326ab737a47278dbd16ed3ee7380b26c7056ddd. As a result, when running an > old guest kernel, the number of rows and columns will be swapped. > > Based on a patch originally written by Szymon Lukasz <[email protected]>, > but partially rewritten to fix various corner cases. > > Signed-off-by: Szymon Lukasz <[email protected]> > Signed-off-by: Filip Hejsek <[email protected]> > Message-ID: <[email protected]> > --- > hw/char/trace-events | 1 + > hw/char/virtio-serial-bus.c | 81 > ++++++++++++++++++++++++++++++++++++++- > include/hw/virtio/virtio-serial.h | 7 ++++ > 3 files changed, 87 insertions(+), 2 deletions(-) > > diff --git a/hw/char/trace-events b/hw/char/trace-events > index a3fcc772877a..e387c8853fcf 100644 > --- a/hw/char/trace-events > +++ b/hw/char/trace-events > @@ -11,6 +11,7 @@ serial_update_parameters(uint64_t baudrate, char parity, > int data_bits, int stop > > # virtio-serial-bus.c > virtio_serial_send_control_event(unsigned int port, uint16_t event, uint16_t > value) "port %u, event %u, value %u" > +virtio_serial_send_console_resize(unsigned int port, uint16_t cols, uint16_t > rows) "port %u, cols %u, rows %u" > virtio_serial_throttle_port(unsigned int port, bool throttle) "port %u, > throttle %d" > virtio_serial_handle_control_message(uint16_t event, uint16_t value) "event > %u, value %u" > virtio_serial_handle_control_message_port(unsigned int port) "port %u" > diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c > index c36e18a4cfb5..882765ac88ab 100644 > --- a/hw/char/virtio-serial-bus.c > +++ b/hw/char/virtio-serial-bus.c > @@ -261,6 +261,68 @@ static size_t send_control_event(VirtIOSerial *vser, > uint32_t port_id, > return send_control_msg(vser, &cpkt, sizeof(cpkt)); > } > > +/* > + * This struct should be added to the Linux kernel uapi headers > + * and later imported to standard-headers/linux/virtio_console.h > + */ > +struct virtio_console_resize { > + __virtio16 cols; > + __virtio16 rows; > +}; > + > +static void send_console_resize(VirtIOSerialPort *port) > +{ > + VirtIOSerial *vser = port->vser; > + VirtIODevice *vdev = VIRTIO_DEVICE(vser); > + > + if (!virtio_has_feature(vser->host_features, VIRTIO_CONSOLE_F_SIZE)) { > + return; > + } > + > + trace_virtio_serial_send_console_resize(port->id, port->cols, > port->rows); > + > + if (use_multiport(vser)) {
it should probably gate on negotiated virtio_vdev_has_feature(vdev, VIRTIO_CONSOLE_F_SIZE) as well -- Marc-André Lureau <[email protected]>
