* [PATCH v7 01/12] chardev: add cols, rows fields
2026-06-09 19:16 [PATCH v7 00/12] virtio-console: notify about the terminal size Filip Hejsek
@ 2026-06-09 19:16 ` Filip Hejsek
2026-06-09 19:16 ` [PATCH v7 02/12] chardev: add CHR_EVENT_RESIZE Filip Hejsek
` (12 subsequent siblings)
13 siblings, 0 replies; 35+ messages in thread
From: Filip Hejsek @ 2026-06-09 19:16 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Paolo Bonzini, Michael S. Tsirkin,
Laurent Vivier, Amit Shah, Markus Armbruster, Eric Blake,
Eduardo Habkost, Marcel Apfelbaum, Yanan Wang, Zhao Liu,
Daniel P. Berrangé, Maximilian Immanuel Brandtner,
Philippe Mathieu-Daudé, Szymon Lukasz
From: Szymon Lukasz <noh4hss@gmail.com>
These fields should be interpreted as the size of the terminal connected
to a given chardev.
Signed-off-by: Szymon Lukasz <noh4hss@gmail.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
[Filip: CharBackend -> CharFrontend]
Signed-off-by: Filip Hejsek <filip.hejsek@gmail.com>
---
chardev/char-fe.c | 13 +++++++++++++
include/chardev/char-fe.h | 10 ++++++++++
include/chardev/char.h | 1 +
3 files changed, 24 insertions(+)
diff --git a/chardev/char-fe.c b/chardev/char-fe.c
index a44f267373..c61c91f779 100644
--- a/chardev/char-fe.c
+++ b/chardev/char-fe.c
@@ -329,6 +329,19 @@ void qemu_chr_fe_set_echo(CharFrontend *c, bool echo)
}
}
+void qemu_chr_fe_get_winsize(CharFrontend *c, uint16_t *cols, uint16_t *rows)
+{
+ Chardev *chr = c->chr;
+
+ if (chr) {
+ *cols = chr->cols;
+ *rows = chr->rows;
+ } else {
+ *cols = 0;
+ *rows = 0;
+ }
+}
+
void qemu_chr_fe_set_open(CharFrontend *c, bool is_open)
{
Chardev *chr = c->chr;
diff --git a/include/chardev/char-fe.h b/include/chardev/char-fe.h
index 5f8a6df17d..53b8d2a1dc 100644
--- a/include/chardev/char-fe.h
+++ b/include/chardev/char-fe.h
@@ -157,6 +157,16 @@ int qemu_chr_fe_wait_connected(CharFrontend *c, Error **errp);
*/
void qemu_chr_fe_set_echo(CharFrontend *c, bool echo);
+/**
+ * qemu_chr_fe_get_winsize:
+ * @cols: the address for storing columns
+ * @rows: the address for storing rows
+ *
+ * Get the size of the terminal connected to the chardev backend.
+ * Returns *cols = *rows = 0, if no associated Chardev.
+ */
+void qemu_chr_fe_get_winsize(CharFrontend *c, uint16_t *cols, uint16_t *rows);
+
/**
* qemu_chr_fe_set_open:
* @c: a CharFrontend
diff --git a/include/chardev/char.h b/include/chardev/char.h
index 7377d8e60a..6394ec2ffe 100644
--- a/include/chardev/char.h
+++ b/include/chardev/char.h
@@ -66,6 +66,7 @@ struct Chardev {
bool logtimestamp;
bool log_line_start;
int be_open;
+ uint16_t cols, rows;
/* used to coordinate the chardev-change special-case: */
bool handover_yank_instance;
GSource *gsource;
--
2.54.0
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH v7 02/12] chardev: add CHR_EVENT_RESIZE
2026-06-09 19:16 [PATCH v7 00/12] virtio-console: notify about the terminal size Filip Hejsek
2026-06-09 19:16 ` [PATCH v7 01/12] chardev: add cols, rows fields Filip Hejsek
@ 2026-06-09 19:16 ` Filip Hejsek
2026-06-10 13:25 ` Daniel P. Berrangé
2026-06-09 19:16 ` [PATCH v7 03/12] chardev: add qemu_chr_resize() Filip Hejsek
` (11 subsequent siblings)
13 siblings, 1 reply; 35+ messages in thread
From: Filip Hejsek @ 2026-06-09 19:16 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Paolo Bonzini, Michael S. Tsirkin,
Laurent Vivier, Amit Shah, Markus Armbruster, Eric Blake,
Eduardo Habkost, Marcel Apfelbaum, Yanan Wang, Zhao Liu,
Daniel P. Berrangé, Maximilian Immanuel Brandtner,
Philippe Mathieu-Daudé, Szymon Lukasz
From: Szymon Lukasz <noh4hss@gmail.com>
Add a new chardev event, CHR_EVENT_RESIZE, which a backend should
trigger if it detects the size of the connected terminal changed.
Signed-off-by: Szymon Lukasz <noh4hss@gmail.com>
[Filip: add note that only the focused frontend gets the event]
Signed-off-by: Filip Hejsek <filip.hejsek@gmail.com>
---
backends/cryptodev-vhost-user.c | 1 +
chardev/char.c | 1 +
hw/block/vhost-user-blk.c | 1 +
hw/char/terminal3270.c | 1 +
hw/char/virtio-console.c | 1 +
hw/ipmi/ipmi_bmc_extern.c | 1 +
hw/scsi/vhost-user-scsi.c | 1 +
hw/usb/ccid-card-passthru.c | 1 +
hw/usb/dev-serial.c | 1 +
hw/usb/redirect.c | 1 +
hw/virtio/vhost-user-base.c | 1 +
hw/virtio/vhost-user-scmi.c | 1 +
include/chardev/char.h | 6 ++++++
monitor/hmp.c | 1 +
monitor/qmp.c | 1 +
net/passt.c | 1 +
net/vhost-user.c | 1 +
17 files changed, 22 insertions(+)
diff --git a/backends/cryptodev-vhost-user.c b/backends/cryptodev-vhost-user.c
index cc478d9902..36564d4307 100644
--- a/backends/cryptodev-vhost-user.c
+++ b/backends/cryptodev-vhost-user.c
@@ -173,6 +173,7 @@ static void cryptodev_vhost_user_event(void *opaque, QEMUChrEvent event)
case CHR_EVENT_BREAK:
case CHR_EVENT_MUX_IN:
case CHR_EVENT_MUX_OUT:
+ case CHR_EVENT_RESIZE:
/* Ignore */
break;
}
diff --git a/chardev/char.c b/chardev/char.c
index ca8b37ed8d..5e62f2949e 100644
--- a/chardev/char.c
+++ b/chardev/char.c
@@ -75,6 +75,7 @@ void qemu_chr_be_event(Chardev *s, QEMUChrEvent event)
case CHR_EVENT_BREAK:
case CHR_EVENT_MUX_IN:
case CHR_EVENT_MUX_OUT:
+ case CHR_EVENT_RESIZE:
/* Ignore */
break;
}
diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
index c151e83677..16c1a536f1 100644
--- a/hw/block/vhost-user-blk.c
+++ b/hw/block/vhost-user-blk.c
@@ -413,6 +413,7 @@ static void vhost_user_blk_event(void *opaque, QEMUChrEvent event)
case CHR_EVENT_BREAK:
case CHR_EVENT_MUX_IN:
case CHR_EVENT_MUX_OUT:
+ case CHR_EVENT_RESIZE:
/* Ignore */
break;
}
diff --git a/hw/char/terminal3270.c b/hw/char/terminal3270.c
index 989b6f6ee1..acd754bcfa 100644
--- a/hw/char/terminal3270.c
+++ b/hw/char/terminal3270.c
@@ -169,6 +169,7 @@ static void chr_event(void *opaque, QEMUChrEvent event)
case CHR_EVENT_BREAK:
case CHR_EVENT_MUX_IN:
case CHR_EVENT_MUX_OUT:
+ case CHR_EVENT_RESIZE:
/* Ignore */
break;
}
diff --git a/hw/char/virtio-console.c b/hw/char/virtio-console.c
index 4737b9a56e..36ad2ddc3f 100644
--- a/hw/char/virtio-console.c
+++ b/hw/char/virtio-console.c
@@ -165,6 +165,7 @@ static void chr_event(void *opaque, QEMUChrEvent event)
case CHR_EVENT_BREAK:
case CHR_EVENT_MUX_IN:
case CHR_EVENT_MUX_OUT:
+ case CHR_EVENT_RESIZE:
/* Ignore */
break;
}
diff --git a/hw/ipmi/ipmi_bmc_extern.c b/hw/ipmi/ipmi_bmc_extern.c
index fa08ed6c21..bd7c61b2d2 100644
--- a/hw/ipmi/ipmi_bmc_extern.c
+++ b/hw/ipmi/ipmi_bmc_extern.c
@@ -436,6 +436,7 @@ static void chr_event(void *opaque, QEMUChrEvent event)
case CHR_EVENT_BREAK:
case CHR_EVENT_MUX_IN:
case CHR_EVENT_MUX_OUT:
+ case CHR_EVENT_RESIZE:
/* Ignore */
break;
}
diff --git a/hw/scsi/vhost-user-scsi.c b/hw/scsi/vhost-user-scsi.c
index 3612897d4b..5601097bc9 100644
--- a/hw/scsi/vhost-user-scsi.c
+++ b/hw/scsi/vhost-user-scsi.c
@@ -226,6 +226,7 @@ static void vhost_user_scsi_event(void *opaque, QEMUChrEvent event)
case CHR_EVENT_BREAK:
case CHR_EVENT_MUX_IN:
case CHR_EVENT_MUX_OUT:
+ case CHR_EVENT_RESIZE:
/* Ignore */
break;
}
diff --git a/hw/usb/ccid-card-passthru.c b/hw/usb/ccid-card-passthru.c
index 5ab7855272..3f4052ec82 100644
--- a/hw/usb/ccid-card-passthru.c
+++ b/hw/usb/ccid-card-passthru.c
@@ -323,6 +323,7 @@ static void ccid_card_vscard_event(void *opaque, QEMUChrEvent event)
case CHR_EVENT_MUX_IN:
case CHR_EVENT_MUX_OUT:
case CHR_EVENT_CLOSED:
+ case CHR_EVENT_RESIZE:
/* Ignore */
break;
}
diff --git a/hw/usb/dev-serial.c b/hw/usb/dev-serial.c
index b238cb7937..98d2abbd56 100644
--- a/hw/usb/dev-serial.c
+++ b/hw/usb/dev-serial.c
@@ -576,6 +576,7 @@ static void usb_serial_event(void *opaque, QEMUChrEvent event)
break;
case CHR_EVENT_MUX_IN:
case CHR_EVENT_MUX_OUT:
+ case CHR_EVENT_RESIZE:
/* Ignore */
break;
}
diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index bde821e214..7a492c1e54 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -1387,6 +1387,7 @@ static void usbredir_chardev_event(void *opaque, QEMUChrEvent event)
case CHR_EVENT_BREAK:
case CHR_EVENT_MUX_IN:
case CHR_EVENT_MUX_OUT:
+ case CHR_EVENT_RESIZE:
/* Ignore */
break;
}
diff --git a/hw/virtio/vhost-user-base.c b/hw/virtio/vhost-user-base.c
index 01ab9ca56b..fd3a9d6265 100644
--- a/hw/virtio/vhost-user-base.c
+++ b/hw/virtio/vhost-user-base.c
@@ -267,6 +267,7 @@ static void vub_event(void *opaque, QEMUChrEvent event)
case CHR_EVENT_BREAK:
case CHR_EVENT_MUX_IN:
case CHR_EVENT_MUX_OUT:
+ case CHR_EVENT_RESIZE:
/* Ignore */
break;
}
diff --git a/hw/virtio/vhost-user-scmi.c b/hw/virtio/vhost-user-scmi.c
index f9264c4374..180787ec6d 100644
--- a/hw/virtio/vhost-user-scmi.c
+++ b/hw/virtio/vhost-user-scmi.c
@@ -214,6 +214,7 @@ static void vu_scmi_event(void *opaque, QEMUChrEvent event)
case CHR_EVENT_BREAK:
case CHR_EVENT_MUX_IN:
case CHR_EVENT_MUX_OUT:
+ case CHR_EVENT_RESIZE:
/* Ignore */
break;
}
diff --git a/include/chardev/char.h b/include/chardev/char.h
index 6394ec2ffe..ee9f24038b 100644
--- a/include/chardev/char.h
+++ b/include/chardev/char.h
@@ -22,6 +22,12 @@ typedef enum {
CHR_EVENT_OPENED, /* new connection established */
CHR_EVENT_MUX_IN, /* mux-focus was set to this terminal */
CHR_EVENT_MUX_OUT, /* mux-focus will move on */
+ CHR_EVENT_RESIZE, /*
+ * the size of the terminal connected to
+ * the chardev has changed. NOTE: this event is only
+ * sent to the focused frontend, so you should also
+ * update the size on receiving CHR_EVENT_MUX_IN.
+ */
CHR_EVENT_CLOSED /* connection closed. NOTE: currently this event
* is only bound to the read port of the chardev.
* Normally the read port and write port of a
diff --git a/monitor/hmp.c b/monitor/hmp.c
index cc4390486e..67d3fcba6d 100644
--- a/monitor/hmp.c
+++ b/monitor/hmp.c
@@ -1496,6 +1496,7 @@ static void monitor_event(void *opaque, QEMUChrEvent event)
break;
case CHR_EVENT_BREAK:
+ case CHR_EVENT_RESIZE:
/* Ignored */
break;
}
diff --git a/monitor/qmp.c b/monitor/qmp.c
index 687019811f..3d5ab8ff4f 100644
--- a/monitor/qmp.c
+++ b/monitor/qmp.c
@@ -486,6 +486,7 @@ static void monitor_qmp_event(void *opaque, QEMUChrEvent event)
case CHR_EVENT_BREAK:
case CHR_EVENT_MUX_IN:
case CHR_EVENT_MUX_OUT:
+ case CHR_EVENT_RESIZE:
/* Ignore */
break;
}
diff --git a/net/passt.c b/net/passt.c
index 45440c399b..e65198960e 100644
--- a/net/passt.c
+++ b/net/passt.c
@@ -428,6 +428,7 @@ static void passt_vhost_user_event(void *opaque, QEMUChrEvent event)
case CHR_EVENT_BREAK:
case CHR_EVENT_MUX_IN:
case CHR_EVENT_MUX_OUT:
+ case CHR_EVENT_RESIZE:
/* Ignore */
break;
}
diff --git a/net/vhost-user.c b/net/vhost-user.c
index 2d0fc49b4d..b849de92da 100644
--- a/net/vhost-user.c
+++ b/net/vhost-user.c
@@ -363,6 +363,7 @@ static void net_vhost_user_event(void *opaque, QEMUChrEvent event)
case CHR_EVENT_BREAK:
case CHR_EVENT_MUX_IN:
case CHR_EVENT_MUX_OUT:
+ case CHR_EVENT_RESIZE:
/* Ignore */
break;
}
--
2.54.0
^ permalink raw reply related [flat|nested] 35+ messages in thread* Re: [PATCH v7 02/12] chardev: add CHR_EVENT_RESIZE
2026-06-09 19:16 ` [PATCH v7 02/12] chardev: add CHR_EVENT_RESIZE Filip Hejsek
@ 2026-06-10 13:25 ` Daniel P. Berrangé
0 siblings, 0 replies; 35+ messages in thread
From: Daniel P. Berrangé @ 2026-06-10 13:25 UTC (permalink / raw)
To: Filip Hejsek
Cc: qemu-devel, Marc-André Lureau, Paolo Bonzini,
Michael S. Tsirkin, Laurent Vivier, Amit Shah, Markus Armbruster,
Eric Blake, Eduardo Habkost, Marcel Apfelbaum, Yanan Wang,
Zhao Liu, Maximilian Immanuel Brandtner,
Philippe Mathieu-Daudé, Szymon Lukasz
On Tue, Jun 09, 2026 at 09:16:12PM +0200, Filip Hejsek wrote:
> From: Szymon Lukasz <noh4hss@gmail.com>
>
> Add a new chardev event, CHR_EVENT_RESIZE, which a backend should
> trigger if it detects the size of the connected terminal changed.
>
> Signed-off-by: Szymon Lukasz <noh4hss@gmail.com>
> [Filip: add note that only the focused frontend gets the event]
> Signed-off-by: Filip Hejsek <filip.hejsek@gmail.com>
> ---
> backends/cryptodev-vhost-user.c | 1 +
> chardev/char.c | 1 +
> hw/block/vhost-user-blk.c | 1 +
> hw/char/terminal3270.c | 1 +
> hw/char/virtio-console.c | 1 +
> hw/ipmi/ipmi_bmc_extern.c | 1 +
> hw/scsi/vhost-user-scsi.c | 1 +
> hw/usb/ccid-card-passthru.c | 1 +
> hw/usb/dev-serial.c | 1 +
> hw/usb/redirect.c | 1 +
> hw/virtio/vhost-user-base.c | 1 +
> hw/virtio/vhost-user-scmi.c | 1 +
> include/chardev/char.h | 6 ++++++
> monitor/hmp.c | 1 +
> monitor/qmp.c | 1 +
> net/passt.c | 1 +
> net/vhost-user.c | 1 +
> 17 files changed, 22 insertions(+)
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH v7 03/12] chardev: add qemu_chr_resize()
2026-06-09 19:16 [PATCH v7 00/12] virtio-console: notify about the terminal size Filip Hejsek
2026-06-09 19:16 ` [PATCH v7 01/12] chardev: add cols, rows fields Filip Hejsek
2026-06-09 19:16 ` [PATCH v7 02/12] chardev: add CHR_EVENT_RESIZE Filip Hejsek
@ 2026-06-09 19:16 ` Filip Hejsek
2026-06-09 19:16 ` [PATCH v7 04/12] char-mux: add support for the terminal size Filip Hejsek
` (10 subsequent siblings)
13 siblings, 0 replies; 35+ messages in thread
From: Filip Hejsek @ 2026-06-09 19:16 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Paolo Bonzini, Michael S. Tsirkin,
Laurent Vivier, Amit Shah, Markus Armbruster, Eric Blake,
Eduardo Habkost, Marcel Apfelbaum, Yanan Wang, Zhao Liu,
Daniel P. Berrangé, Maximilian Immanuel Brandtner,
Philippe Mathieu-Daudé, Szymon Lukasz
From: Szymon Lukasz <noh4hss@gmail.com>
This function should be called whenever we learn about a new size of
the terminal connected to a chardev.
Signed-off-by: Szymon Lukasz <noh4hss@gmail.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Filip Hejsek <filip.hejsek@gmail.com>
---
chardev/char.c | 11 +++++++++++
include/chardev/char.h | 2 ++
2 files changed, 13 insertions(+)
diff --git a/chardev/char.c b/chardev/char.c
index 5e62f2949e..d4ef717c56 100644
--- a/chardev/char.c
+++ b/chardev/char.c
@@ -386,6 +386,17 @@ int qemu_chr_wait_connected(Chardev *chr, Error **errp)
return 0;
}
+void qemu_chr_resize(Chardev *chr, uint16_t cols, uint16_t rows)
+{
+ if (cols != chr->cols || rows != chr->rows) {
+ chr->cols = cols;
+ chr->rows = rows;
+ if (chr->be_open) {
+ qemu_chr_be_event(chr, CHR_EVENT_RESIZE);
+ }
+ }
+}
+
QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename,
bool permit_mux_mon)
{
diff --git a/include/chardev/char.h b/include/chardev/char.h
index ee9f24038b..2616c19cc0 100644
--- a/include/chardev/char.h
+++ b/include/chardev/char.h
@@ -235,6 +235,8 @@ int qemu_chr_write(Chardev *s, const uint8_t *buf, int len, bool write_all);
#define qemu_chr_write_all(s, buf, len) qemu_chr_write(s, buf, len, true)
int qemu_chr_wait_connected(Chardev *chr, Error **errp);
+void qemu_chr_resize(Chardev *chr, uint16_t cols, uint16_t rows);
+
#define TYPE_CHARDEV "chardev"
OBJECT_DECLARE_TYPE(Chardev, ChardevClass, CHARDEV)
--
2.54.0
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH v7 04/12] char-mux: add support for the terminal size
2026-06-09 19:16 [PATCH v7 00/12] virtio-console: notify about the terminal size Filip Hejsek
` (2 preceding siblings ...)
2026-06-09 19:16 ` [PATCH v7 03/12] chardev: add qemu_chr_resize() Filip Hejsek
@ 2026-06-09 19:16 ` Filip Hejsek
2026-06-09 19:16 ` [PATCH v7 05/12] main-loop: change the handling of SIGWINCH Filip Hejsek
` (9 subsequent siblings)
13 siblings, 0 replies; 35+ messages in thread
From: Filip Hejsek @ 2026-06-09 19:16 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Paolo Bonzini, Michael S. Tsirkin,
Laurent Vivier, Amit Shah, Markus Armbruster, Eric Blake,
Eduardo Habkost, Marcel Apfelbaum, Yanan Wang, Zhao Liu,
Daniel P. Berrangé, Maximilian Immanuel Brandtner,
Philippe Mathieu-Daudé, Szymon Lukasz
From: Szymon Lukasz <noh4hss@gmail.com>
The terminal size of a mux chardev should be the same as the real
chardev, so listen for CHR_EVENT_RESIZE to be up to date.
We forward CHR_EVENT_RESIZE only to the focused frontend. This means
frontends should update their view of the terminal size on
receiving CHR_EVENT_MUX_IN.
Signed-off-by: Szymon Lukasz <noh4hss@gmail.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Filip Hejsek <filip.hejsek@gmail.com>
---
chardev/char-mux.c | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/chardev/char-mux.c b/chardev/char-mux.c
index 881443d869..5a90f0221b 100644
--- a/chardev/char-mux.c
+++ b/chardev/char-mux.c
@@ -264,9 +264,24 @@ void mux_chr_send_all_event(Chardev *chr, QEMUChrEvent event)
}
}
+static void mux_update_winsize(Chardev *chr)
+{
+ MuxChardev *d = MUX_CHARDEV(chr);
+ uint16_t cols, rows;
+
+ qemu_chr_fe_get_winsize(&d->chr, &cols, &rows);
+ qemu_chr_resize(chr, cols, rows);
+}
+
static void mux_chr_event(void *opaque, QEMUChrEvent event)
{
- mux_chr_send_all_event(CHARDEV(opaque), event);
+ Chardev *chr = CHARDEV(opaque);
+
+ if (event == CHR_EVENT_RESIZE) {
+ mux_update_winsize(chr);
+ } else {
+ mux_chr_send_all_event(chr, event);
+ }
}
static GSource *mux_chr_add_watch(Chardev *s, GIOCondition cond)
@@ -378,6 +393,8 @@ static bool mux_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
return false;
}
+ mux_update_winsize(chr);
+
/*
* Only move to opened state if we've realized
* the initial set of muxes:
--
2.54.0
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH v7 05/12] main-loop: change the handling of SIGWINCH
2026-06-09 19:16 [PATCH v7 00/12] virtio-console: notify about the terminal size Filip Hejsek
` (3 preceding siblings ...)
2026-06-09 19:16 ` [PATCH v7 04/12] char-mux: add support for the terminal size Filip Hejsek
@ 2026-06-09 19:16 ` Filip Hejsek
2026-06-09 19:16 ` [PATCH v7 06/12] char-stdio: add support for the terminal size Filip Hejsek
` (8 subsequent siblings)
13 siblings, 0 replies; 35+ messages in thread
From: Filip Hejsek @ 2026-06-09 19:16 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Paolo Bonzini, Michael S. Tsirkin,
Laurent Vivier, Amit Shah, Markus Armbruster, Eric Blake,
Eduardo Habkost, Marcel Apfelbaum, Yanan Wang, Zhao Liu,
Daniel P. Berrangé, Maximilian Immanuel Brandtner,
Philippe Mathieu-Daudé, Szymon Lukasz
From: Szymon Lukasz <noh4hss@gmail.com>
Block SIGWINCH, so it is delivered only via signalfd.
Install a handler that uses NotifierList to tell
interested parties about SIGWINCH delivery.
Signed-off-by: Szymon Lukasz <noh4hss@gmail.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Filip Hejsek <filip.hejsek@gmail.com>
---
include/qemu/main-loop.h | 4 ++++
ui/curses.c | 11 ++++++-----
util/main-loop.c | 21 +++++++++++++++++++++
3 files changed, 31 insertions(+), 5 deletions(-)
diff --git a/include/qemu/main-loop.h b/include/qemu/main-loop.h
index 8c1241a2c1..ff41346b0b 100644
--- a/include/qemu/main-loop.h
+++ b/include/qemu/main-loop.h
@@ -449,4 +449,8 @@ typedef struct MainLoopPoll {
void main_loop_poll_add_notifier(Notifier *notify);
void main_loop_poll_remove_notifier(Notifier *notify);
+#ifndef _WIN32
+void sigwinch_add_notifier(Notifier *n);
+#endif
+
#endif
diff --git a/ui/curses.c b/ui/curses.c
index 24d3713e57..04feaeb390 100644
--- a/ui/curses.c
+++ b/ui/curses.c
@@ -33,6 +33,7 @@
#include <iconv.h>
#include "qapi/error.h"
+#include "qemu/main-loop.h"
#include "qemu/module.h"
#include "ui/console.h"
#include "ui/input.h"
@@ -149,7 +150,7 @@ static void curses_resize(DisplayChangeListener *dcl,
}
#if !defined(_WIN32) && defined(SIGWINCH) && defined(KEY_RESIZE)
-static volatile sig_atomic_t got_sigwinch;
+static bool got_sigwinch;
static void curses_winch_check(void)
{
struct winsize {
@@ -172,17 +173,17 @@ static void curses_winch_check(void)
invalidate = 1;
}
-static void curses_winch_handler(int signum)
+static void curses_winch_handler(Notifier *n, void *data)
{
got_sigwinch = true;
}
static void curses_winch_init(void)
{
- struct sigaction old, winch = {
- .sa_handler = curses_winch_handler,
+ static Notifier n = {
+ .notify = curses_winch_handler
};
- sigaction(SIGWINCH, &winch, &old);
+ sigwinch_add_notifier(&n);
}
#else
static void curses_winch_check(void) {}
diff --git a/util/main-loop.c b/util/main-loop.c
index ad8645c30a..136886e4ee 100644
--- a/util/main-loop.c
+++ b/util/main-loop.c
@@ -100,6 +100,7 @@ static int qemu_signal_init(Error **errp)
sigaddset(&set, SIGIO);
sigaddset(&set, SIGALRM);
sigaddset(&set, SIGBUS);
+ sigaddset(&set, SIGWINCH);
/* SIGINT cannot be handled via signalfd, so that ^C can be used
* to interrupt QEMU when it is being run under gdb. SIGHUP and
* SIGTERM are also handled asynchronously, even though it is not
@@ -124,6 +125,26 @@ static int qemu_signal_init(Error **errp)
return 0;
}
+static NotifierList sigwinch_notifiers =
+ NOTIFIER_LIST_INITIALIZER(sigwinch_notifiers);
+
+static void sigwinch_handler(int signum)
+{
+ notifier_list_notify(&sigwinch_notifiers, NULL);
+}
+
+void sigwinch_add_notifier(Notifier *n)
+{
+ if (notifier_list_empty(&sigwinch_notifiers)) {
+ struct sigaction action = {
+ .sa_handler = sigwinch_handler,
+ };
+ sigaction(SIGWINCH, &action, NULL);
+ }
+
+ notifier_list_add(&sigwinch_notifiers, n);
+}
+
#else /* _WIN32 */
static int qemu_signal_init(Error **errp)
--
2.54.0
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH v7 06/12] char-stdio: add support for the terminal size
2026-06-09 19:16 [PATCH v7 00/12] virtio-console: notify about the terminal size Filip Hejsek
` (4 preceding siblings ...)
2026-06-09 19:16 ` [PATCH v7 05/12] main-loop: change the handling of SIGWINCH Filip Hejsek
@ 2026-06-09 19:16 ` Filip Hejsek
2026-06-09 19:16 ` [PATCH v7 07/12] char-win-stdio: add support for " Filip Hejsek
` (7 subsequent siblings)
13 siblings, 0 replies; 35+ messages in thread
From: Filip Hejsek @ 2026-06-09 19:16 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Paolo Bonzini, Michael S. Tsirkin,
Laurent Vivier, Amit Shah, Markus Armbruster, Eric Blake,
Eduardo Habkost, Marcel Apfelbaum, Yanan Wang, Zhao Liu,
Daniel P. Berrangé, Maximilian Immanuel Brandtner,
Philippe Mathieu-Daudé, Szymon Lukasz
From: Szymon Lukasz <noh4hss@gmail.com>
Update the terminal size upon SIGWINCH delivery.
Signed-off-by: Szymon Lukasz <noh4hss@gmail.com>
[Filip: use DECLARE_INSTANCE_CHECKER, qemu_chr_resize_stdio -> stdio_chr_resize]
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Filip Hejsek <filip.hejsek@gmail.com>
---
chardev/char-stdio.c | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/chardev/char-stdio.c b/chardev/char-stdio.c
index fe1cbb2d88..4fc8db212c 100644
--- a/chardev/char-stdio.c
+++ b/chardev/char-stdio.c
@@ -34,7 +34,9 @@
#include "chardev/char-win-stdio.h"
#else
#include <termios.h>
+#include <sys/ioctl.h>
#include "chardev/char-fd.h"
+#include "qemu/main-loop.h"
#endif
#ifndef _WIN32
@@ -46,6 +48,14 @@ static bool stdio_in_use;
static bool stdio_allow_signal;
static bool stdio_echo_state;
+typedef struct {
+ FDChardev parent;
+ Notifier resize_notifier;
+} StdioChardev;
+
+DECLARE_INSTANCE_CHECKER(StdioChardev, STDIO_CHARDEV,
+ TYPE_CHARDEV_STDIO)
+
static void term_exit(void)
{
if (stdio_in_use) {
@@ -85,8 +95,23 @@ static void term_stdio_handler(int sig)
stdio_chr_set_echo(NULL, stdio_echo_state);
}
+static void stdio_chr_resize(Chardev *chr)
+{
+ struct winsize ws;
+ if (ioctl(1, TIOCGWINSZ, &ws) != -1) {
+ qemu_chr_resize(chr, ws.ws_col, ws.ws_row);
+ }
+}
+
+static void term_resize_notify(Notifier *n, void *data)
+{
+ StdioChardev *s = container_of(n, StdioChardev, resize_notifier);
+ stdio_chr_resize(CHARDEV(s));
+}
+
static bool stdio_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
{
+ StdioChardev *s = STDIO_CHARDEV(chr);
ChardevStdio *opts = backend->u.stdio.data;
struct sigaction act;
@@ -121,6 +146,10 @@ static bool stdio_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
stdio_allow_signal = !opts->has_signal || opts->signal;
stdio_chr_set_echo(chr, false);
+ s->resize_notifier.notify = term_resize_notify;
+ sigwinch_add_notifier(&s->resize_notifier);
+ stdio_chr_resize(chr);
+
qemu_chr_be_event(chr, CHR_EVENT_OPENED);
return true;
}
@@ -162,6 +191,7 @@ static const TypeInfo char_stdio_type_info = {
.parent = TYPE_CHARDEV_WIN_STDIO,
#else
.parent = TYPE_CHARDEV_FD,
+ .instance_size = sizeof(StdioChardev),
#endif
.instance_finalize = char_stdio_finalize,
.class_init = char_stdio_class_init,
--
2.54.0
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH v7 07/12] char-win-stdio: add support for terminal size
2026-06-09 19:16 [PATCH v7 00/12] virtio-console: notify about the terminal size Filip Hejsek
` (5 preceding siblings ...)
2026-06-09 19:16 ` [PATCH v7 06/12] char-stdio: add support for the terminal size Filip Hejsek
@ 2026-06-09 19:16 ` Filip Hejsek
2026-06-09 19:16 ` [PATCH v7 08/12] ui/console-vc: forward text console size to vc chardev Filip Hejsek
` (6 subsequent siblings)
13 siblings, 0 replies; 35+ messages in thread
From: Filip Hejsek @ 2026-06-09 19:16 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Paolo Bonzini, Michael S. Tsirkin,
Laurent Vivier, Amit Shah, Markus Armbruster, Eric Blake,
Eduardo Habkost, Marcel Apfelbaum, Yanan Wang, Zhao Liu,
Daniel P. Berrangé, Maximilian Immanuel Brandtner,
Philippe Mathieu-Daudé
Use GetConsoleScreenBufferInfo to obtain terminal size
and set ENABLE_WINDOW_INPUT to receive resize notifications.
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Filip Hejsek <filip.hejsek@gmail.com>
---
chardev/char-win-stdio.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/chardev/char-win-stdio.c b/chardev/char-win-stdio.c
index bb9c195a8b..188d26502d 100644
--- a/chardev/char-win-stdio.c
+++ b/chardev/char-win-stdio.c
@@ -44,6 +44,20 @@ typedef struct WinStdioChardev WinStdioChardev;
DECLARE_INSTANCE_CHECKER(WinStdioChardev, WIN_STDIO_CHARDEV,
TYPE_CHARDEV_WIN_STDIO)
+static void win_stdio_chr_resize(Chardev *chr)
+{
+ HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
+ CONSOLE_SCREEN_BUFFER_INFO ScreenBufferInfo;
+
+ if (GetConsoleScreenBufferInfo(hStdOut, &ScreenBufferInfo)) {
+ uint16_t cols = ScreenBufferInfo.srWindow.Right + 1
+ - ScreenBufferInfo.srWindow.Left;
+ uint16_t rows = ScreenBufferInfo.srWindow.Bottom + 1
+ - ScreenBufferInfo.srWindow.Top;
+ qemu_chr_resize(chr, cols, rows);
+ }
+}
+
static void win_stdio_wait_func(void *opaque)
{
Chardev *chr = CHARDEV(opaque);
@@ -75,6 +89,9 @@ static void win_stdio_wait_func(void *opaque)
}
}
}
+ if (buf[i].EventType == WINDOW_BUFFER_SIZE_EVENT) {
+ win_stdio_chr_resize(chr);
+ }
}
}
@@ -201,6 +218,8 @@ static bool win_stdio_chr_open(Chardev *chr,
} else {
dwMode &= ~ENABLE_PROCESSED_INPUT;
}
+ dwMode |= ENABLE_WINDOW_INPUT;
+ win_stdio_chr_resize(chr);
}
SetConsoleMode(stdio->hStdIn, dwMode);
--
2.54.0
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH v7 08/12] ui/console-vc: forward text console size to vc chardev
2026-06-09 19:16 [PATCH v7 00/12] virtio-console: notify about the terminal size Filip Hejsek
` (6 preceding siblings ...)
2026-06-09 19:16 ` [PATCH v7 07/12] char-win-stdio: add support for " Filip Hejsek
@ 2026-06-09 19:16 ` Filip Hejsek
2026-06-09 19:16 ` [PATCH v7 09/12] ui/gtk: forward gtk " Filip Hejsek
` (5 subsequent siblings)
13 siblings, 0 replies; 35+ messages in thread
From: Filip Hejsek @ 2026-06-09 19:16 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Paolo Bonzini, Michael S. Tsirkin,
Laurent Vivier, Amit Shah, Markus Armbruster, Eric Blake,
Eduardo Habkost, Marcel Apfelbaum, Yanan Wang, Zhao Liu,
Daniel P. Berrangé, Maximilian Immanuel Brandtner,
Philippe Mathieu-Daudé
Update the vc chardev size when initializing the console and after
changing the surface image.
NOTE: There seems to be a bug in the code where the dpy_text_resize
callback is not called when the size changes due to changing the
surface image. (Though it doesn't cause any problem in practice
because the callback is only used by ui/ncurses for fixed
consoles, whose size never changes.)
Signed-off-by: Filip Hejsek <filip.hejsek@gmail.com>
---
ui/console-vc.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/ui/console-vc.c b/ui/console-vc.c
index 828e78c41e..d28dc4cdb7 100644
--- a/ui/console-vc.c
+++ b/ui/console-vc.c
@@ -115,12 +115,19 @@ static int vc_chr_write(Chardev *chr, const uint8_t *buf, int len)
return vt100_input(&s->vt, buf, len);
}
+static void text_console_chr_resize(QemuTextConsole *s)
+{
+ qemu_chr_resize(s->chr, s->vt.width, s->vt.height);
+}
+
static void text_console_invalidate(void *opaque)
{
QemuTextConsole *s = QEMU_TEXT_CONSOLE(opaque);
if (!QEMU_IS_FIXED_TEXT_CONSOLE(s)) {
vt100_set_image(&s->vt, QEMU_CONSOLE(s)->surface->image);
+ text_console_chr_resize(s);
+ /* XXX Shouldn't qemu_text_console_update_size() also be called here? */
}
vt100_refresh(&s->vt);
}
@@ -254,6 +261,7 @@ static bool vc_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
s->vt.t_attrib = TEXT_ATTRIBUTES_DEFAULT;
}
+ text_console_chr_resize(s);
qemu_chr_be_event(chr, CHR_EVENT_OPENED);
return true;
}
--
2.54.0
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH v7 09/12] ui/gtk: forward gtk console size to vc chardev
2026-06-09 19:16 [PATCH v7 00/12] virtio-console: notify about the terminal size Filip Hejsek
` (7 preceding siblings ...)
2026-06-09 19:16 ` [PATCH v7 08/12] ui/console-vc: forward text console size to vc chardev Filip Hejsek
@ 2026-06-09 19:16 ` Filip Hejsek
2026-06-09 19:16 ` [PATCH v7 10/12] qmp: add chardev-window-size-changed command Filip Hejsek
` (4 subsequent siblings)
13 siblings, 0 replies; 35+ messages in thread
From: Filip Hejsek @ 2026-06-09 19:16 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Paolo Bonzini, Michael S. Tsirkin,
Laurent Vivier, Amit Shah, Markus Armbruster, Eric Blake,
Eduardo Habkost, Marcel Apfelbaum, Yanan Wang, Zhao Liu,
Daniel P. Berrangé, Maximilian Immanuel Brandtner,
Philippe Mathieu-Daudé
Query the terminal size from the vte library when creating the console
and every time it might change. Vte doesn't send any signal specifically
for terminal size changes, so instead we register callbacks for
size-allocate and char-size-changed.
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Filip Hejsek <filip.hejsek@gmail.com>
---
ui/gtk.c | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/ui/gtk.c b/ui/gtk.c
index 4f706c6bbb..2863082a24 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -2040,6 +2040,28 @@ static gboolean gd_vc_in(VteTerminal *terminal, gchar *text, guint size,
return TRUE;
}
+static void gd_vc_vte_update_size(VirtualConsole *vc)
+{
+ uint16_t cols, rows;
+ cols = vte_terminal_get_column_count(VTE_TERMINAL(vc->vte.terminal));
+ rows = vte_terminal_get_row_count(VTE_TERMINAL(vc->vte.terminal));
+ qemu_chr_resize(vc->vte.chr, cols, rows);
+}
+
+static void gd_vc_size_allocate(VteTerminal *terminal,
+ GtkAllocation *allocation, gpointer user_data)
+{
+ VirtualConsole *vc = user_data;
+ gd_vc_vte_update_size(vc);
+}
+
+static void gd_vc_char_size_changed(VteTerminal *terminal, guint width,
+ guint height, gpointer user_data)
+{
+ VirtualConsole *vc = user_data;
+ gd_vc_vte_update_size(vc);
+}
+
static GSList *gd_vc_vte_init(GtkDisplayState *s, VirtualConsole *vc,
Chardev *chr, int idx,
GSList *group, GtkWidget *view_menu)
@@ -2105,6 +2127,12 @@ static GSList *gd_vc_vte_init(GtkDisplayState *s, VirtualConsole *vc,
qemu_chr_be_event(vc->vte.chr, CHR_EVENT_OPENED);
+ g_signal_connect(vc->vte.terminal, "size-allocate",
+ G_CALLBACK(gd_vc_size_allocate), vc);
+ g_signal_connect(vc->vte.terminal, "char-size-changed",
+ G_CALLBACK(gd_vc_char_size_changed), vc);
+ gd_vc_vte_update_size(vc);
+
return group;
}
--
2.54.0
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH v7 10/12] qmp: add chardev-window-size-changed command
2026-06-09 19:16 [PATCH v7 00/12] virtio-console: notify about the terminal size Filip Hejsek
` (8 preceding siblings ...)
2026-06-09 19:16 ` [PATCH v7 09/12] ui/gtk: forward gtk " Filip Hejsek
@ 2026-06-09 19:16 ` Filip Hejsek
2026-06-09 19:16 ` [PATCH v7 11/12] virtio-serial-bus: add terminal resize messages Filip Hejsek
` (3 subsequent siblings)
13 siblings, 0 replies; 35+ messages in thread
From: Filip Hejsek @ 2026-06-09 19:16 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Paolo Bonzini, Michael S. Tsirkin,
Laurent Vivier, Amit Shah, Markus Armbruster, Eric Blake,
Eduardo Habkost, Marcel Apfelbaum, Yanan Wang, Zhao Liu,
Daniel P. Berrangé, Maximilian Immanuel Brandtner,
Philippe Mathieu-Daudé, Szymon Lukasz
From: Szymon Lukasz <noh4hss@gmail.com>
The managment software can use this command to notify QEMU about the
size of the terminal connected to a chardev, QEMU can then forward this
information to the guest if the chardev is connected to a virtio console
device.
Signed-off-by: Szymon Lukasz <noh4hss@gmail.com>
Suggested-by: Daniel P. Berrangé <berrange@redhat.com>
[Filip: rename command, change documentation]
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Acked-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Filip Hejsek <filip.hejsek@gmail.com>
---
chardev/char.c | 14 ++++++++++++++
qapi/char.json | 31 +++++++++++++++++++++++++++++++
2 files changed, 45 insertions(+)
diff --git a/chardev/char.c b/chardev/char.c
index d4ef717c56..96e67de815 100644
--- a/chardev/char.c
+++ b/chardev/char.c
@@ -1339,6 +1339,20 @@ bool qmp_add_client_char(int fd, bool has_skipauth, bool skipauth,
return true;
}
+void qmp_chardev_window_size_changed(const char *id, uint16_t cols,
+ uint16_t rows, Error **errp)
+{
+ Chardev *chr;
+
+ chr = qemu_chr_find(id);
+ if (chr == NULL) {
+ error_setg(errp, "Chardev '%s' not found", id);
+ return;
+ }
+
+ qemu_chr_resize(chr, cols, rows);
+}
+
/*
* Add a timeout callback for the chardev (in milliseconds), return
* the GSource object created. Please use this to add timeout hook for
diff --git a/qapi/char.json b/qapi/char.json
index aa5ee9ffcd..d26af6bcc3 100644
--- a/qapi/char.json
+++ b/qapi/char.json
@@ -891,6 +891,37 @@
{ 'command': 'chardev-send-break',
'data': { 'id': 'str' } }
+##
+# @chardev-window-size-changed:
+#
+# Notifies a chardev about the current size of the terminal connected
+# to this chardev. The information will be forwarded to the guest if
+# the chardev is connected to a virtio console device.
+#
+# The initial size is 0x0, which should be interpreted as an unknown
+# size.
+#
+# Some backends detect the terminal size automatically, in which case
+# the size may unpredictably revert to the detected one at any time.
+#
+# @id: the chardev's ID
+#
+# @cols: the number of columns
+#
+# @rows: the number of rows
+#
+# Since: 11.1
+#
+# .. qmp-example::
+#
+# -> { "execute": "chardev-window-size-changed", "arguments": { "id": "foo", "cols": 80, "rows": 24 } }
+# <- { "return": {} }
+##
+{ 'command': 'chardev-window-size-changed',
+ 'data': { 'id': 'str',
+ 'cols': 'uint16',
+ 'rows': 'uint16' } }
+
##
# @VSERPORT_CHANGE:
#
--
2.54.0
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH v7 11/12] virtio-serial-bus: add terminal resize messages
2026-06-09 19:16 [PATCH v7 00/12] virtio-console: notify about the terminal size Filip Hejsek
` (9 preceding siblings ...)
2026-06-09 19:16 ` [PATCH v7 10/12] qmp: add chardev-window-size-changed command Filip Hejsek
@ 2026-06-09 19:16 ` Filip Hejsek
2026-06-09 21:48 ` marcandre.lureau
2026-06-10 13:31 ` Daniel P. Berrangé
2026-06-09 19:16 ` [PATCH v7 12/12] virtio-console: notify the guest about terminal resizes Filip Hejsek
` (2 subsequent siblings)
13 siblings, 2 replies; 35+ messages in thread
From: Filip Hejsek @ 2026-06-09 19:16 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Paolo Bonzini, Michael S. Tsirkin,
Laurent Vivier, Amit Shah, Markus Armbruster, Eric Blake,
Eduardo Habkost, Marcel Apfelbaum, Yanan Wang, Zhao Liu,
Daniel P. Berrangé, Maximilian Immanuel Brandtner,
Philippe Mathieu-Daudé, Szymon Lukasz
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 <noh4hss@gmail.com>,
but partially rewritten to fix various corner cases.
Signed-off-by: Szymon Lukasz <noh4hss@gmail.com>
Signed-off-by: Filip Hejsek <filip.hejsek@gmail.com>
---
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 a3fcc77287..e387c8853f 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 cd234dc6db..a31e80cfde 100644
--- a/hw/char/virtio-serial-bus.c
+++ b/hw/char/virtio-serial-bus.c
@@ -260,6 +260,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)) {
+ struct {
+ struct virtio_console_control control;
+ struct virtio_console_resize resize;
+ } buffer;
+
+ virtio_stl_p(vdev, &buffer.control.id, port->id);
+ virtio_stw_p(vdev, &buffer.control.event, VIRTIO_CONSOLE_RESIZE);
+ virtio_stw_p(vdev, &buffer.resize.cols, port->cols);
+ virtio_stw_p(vdev, &buffer.resize.rows, port->rows);
+
+ send_control_msg(vser, &buffer, sizeof(buffer));
+ }
+}
+
+void virtio_serial_resize_console(VirtIOSerialPort *port,
+ uint16_t cols, uint16_t rows)
+{
+ VirtIOSerial *vser = port->vser;
+ VirtIODevice *vdev = VIRTIO_DEVICE(vser);
+
+ if (port->cols == cols && port->rows == rows) {
+ return;
+ }
+
+ port->cols = cols;
+ port->rows = rows;
+
+ if (port->id == 0 && !use_multiport(vser) &&
+ virtio_vdev_has_feature(vdev, VIRTIO_CONSOLE_F_SIZE)) {
+ virtio_notify_config(vdev);
+ }
+
+ /*
+ * We will send these messages even before we told the guest that
+ * it is a console port (by sending VIRTIO_CONSOLE_CONSOLE_PORT
+ * message), but that should be fine as the guest will likely
+ * ignore them.
+ */
+ send_console_resize(port);
+}
+
/* Functions for use inside qemu to open and read from/write to ports */
int virtio_serial_open(VirtIOSerialPort *port)
{
@@ -408,6 +470,7 @@ static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len)
*/
if (vsc->is_console) {
send_control_event(vser, port->id, VIRTIO_CONSOLE_CONSOLE_PORT, 1);
+ send_console_resize(port);
}
if (port->name) {
@@ -557,6 +620,7 @@ static uint64_t get_features(VirtIODevice *vdev, uint64_t features,
vser = VIRTIO_SERIAL(vdev);
+ features |= vser->host_features;
features |= BIT_ULL(VIRTIO_CONSOLE_F_EMERG_WRITE);
if (vser->bus.max_nr_ports > 1) {
virtio_add_feature(&features, VIRTIO_CONSOLE_F_MULTIPORT);
@@ -568,11 +632,18 @@ static uint64_t get_features(VirtIODevice *vdev, uint64_t features,
static void get_config(VirtIODevice *vdev, uint8_t *config_data)
{
VirtIOSerial *vser = VIRTIO_SERIAL(vdev);
+ VirtIOSerialPort *port;
struct virtio_console_config *config =
(struct virtio_console_config *)config_data;
- config->cols = 0;
- config->rows = 0;
+ port = find_port_by_id(vser, 0);
+ if (port) {
+ config->cols = virtio_tswap16(vdev, port->cols);
+ config->rows = virtio_tswap16(vdev, port->rows);
+ } else {
+ config->cols = 0;
+ config->rows = 0;
+ }
config->max_nr_ports = virtio_tswap32(vdev,
vser->serial.max_virtserial_ports);
}
@@ -735,6 +806,10 @@ static void virtio_serial_post_load_timer_cb(void *opaque)
port->host_connected);
}
vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port);
+ /*
+ * TODO: let the guest know about new console size if it has changed
+ * (this will require sending old size in the migration stream)
+ */
if (vsc->set_guest_connected) {
vsc->set_guest_connected(port, port->guest_connected);
}
@@ -1151,6 +1226,8 @@ static const VMStateDescription vmstate_virtio_console = {
static const Property virtio_serial_properties[] = {
DEFINE_PROP_UINT32("max_ports", VirtIOSerial, serial.max_virtserial_ports,
31),
+ DEFINE_PROP_BIT64("console-size", VirtIOSerial, host_features,
+ VIRTIO_CONSOLE_F_SIZE, false),
};
static void virtio_serial_class_init(ObjectClass *klass, const void *data)
diff --git a/include/hw/virtio/virtio-serial.h b/include/hw/virtio/virtio-serial.h
index da0c91e1a4..bda6d5312a 100644
--- a/include/hw/virtio/virtio-serial.h
+++ b/include/hw/virtio/virtio-serial.h
@@ -145,6 +145,9 @@ struct VirtIOSerialPort {
bool host_connected;
/* Do apps not want to receive data? */
bool throttled;
+
+ /* Terminal size reported to the guest. Only used for consoles. */
+ uint16_t cols, rows;
};
/* The virtio-serial bus on top of which the ports will ride as devices */
@@ -186,6 +189,8 @@ struct VirtIOSerial {
struct VirtIOSerialPostLoad *post_load;
virtio_serial_conf serial;
+
+ uint64_t host_features;
};
/* Interface to the virtio-serial bus */
@@ -220,5 +225,7 @@ size_t virtio_serial_guest_ready(VirtIOSerialPort *port);
*/
void virtio_serial_throttle_port(VirtIOSerialPort *port, bool throttle);
+void virtio_serial_resize_console(VirtIOSerialPort *port,
+ uint16_t cols, uint16_t rows);
#endif
--
2.54.0
^ permalink raw reply related [flat|nested] 35+ messages in thread* Re: [PATCH v7 11/12] virtio-serial-bus: add terminal resize messages
2026-06-09 19:16 ` [PATCH v7 11/12] virtio-serial-bus: add terminal resize messages Filip Hejsek
@ 2026-06-09 21:48 ` marcandre.lureau
2026-06-10 13:31 ` Daniel P. Berrangé
1 sibling, 0 replies; 35+ messages in thread
From: marcandre.lureau @ 2026-06-09 21:48 UTC (permalink / raw)
To: Filip Hejsek
Cc: qemu-devel, Marc-André Lureau, Paolo Bonzini,
Michael S. Tsirkin, Laurent Vivier, Amit Shah, Markus Armbruster,
Eric Blake, Eduardo Habkost, Marcel Apfelbaum, Yanan Wang,
Zhao Liu, Daniel P. Berrangé, Maximilian Immanuel Brandtner,
Philippe Mathieu-Daudé, Szymon Lukasz
On Tue, 09 Jun 2026 21:16:21 +0200, Filip Hejsek <filip.hejsek@gmail.com> wrote:
> diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
> index cd234dc6db1..a31e80cfdee 100644
> --- a/hw/char/virtio-serial-bus.c
> +++ b/hw/char/virtio-serial-bus.c
> @@ -260,6 +260,68 @@ static size_t send_control_event(VirtIOSerial *vser, uint32_t port_id,
> [ ... skip 22 lines ... ]
> +
> + if (use_multiport(vser)) {
> + struct {
> + struct virtio_console_control control;
> + struct virtio_console_resize resize;
> + } buffer;
Initialize the buffer to = {},..
> +
> + virtio_stl_p(vdev, &buffer.control.id, port->id);
> + virtio_stw_p(vdev, &buffer.control.event, VIRTIO_CONSOLE_RESIZE);
> + virtio_stw_p(vdev, &buffer.resize.cols, port->cols);
> + virtio_stw_p(vdev, &buffer.resize.rows, port->rows);
..otherwise whatever is on the stack at control.value is sent to the guest.
--
Marc-André Lureau <marcandre.lureau@redhat.com>
^ permalink raw reply [flat|nested] 35+ messages in thread* Re: [PATCH v7 11/12] virtio-serial-bus: add terminal resize messages
2026-06-09 19:16 ` [PATCH v7 11/12] virtio-serial-bus: add terminal resize messages Filip Hejsek
2026-06-09 21:48 ` marcandre.lureau
@ 2026-06-10 13:31 ` Daniel P. Berrangé
1 sibling, 0 replies; 35+ messages in thread
From: Daniel P. Berrangé @ 2026-06-10 13:31 UTC (permalink / raw)
To: Filip Hejsek
Cc: qemu-devel, Marc-André Lureau, Paolo Bonzini,
Michael S. Tsirkin, Laurent Vivier, Amit Shah, Markus Armbruster,
Eric Blake, Eduardo Habkost, Marcel Apfelbaum, Yanan Wang,
Zhao Liu, Maximilian Immanuel Brandtner,
Philippe Mathieu-Daudé, Szymon Lukasz
On Tue, Jun 09, 2026 at 09:16:21PM +0200, Filip Hejsek wrote:
> 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 <noh4hss@gmail.com>,
> but partially rewritten to fix various corner cases.
>
> Signed-off-by: Szymon Lukasz <noh4hss@gmail.com>
> Signed-off-by: Filip Hejsek <filip.hejsek@gmail.com>
> ---
> 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(-)
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH v7 12/12] virtio-console: notify the guest about terminal resizes
2026-06-09 19:16 [PATCH v7 00/12] virtio-console: notify about the terminal size Filip Hejsek
` (10 preceding siblings ...)
2026-06-09 19:16 ` [PATCH v7 11/12] virtio-serial-bus: add terminal resize messages Filip Hejsek
@ 2026-06-09 19:16 ` Filip Hejsek
2026-09-21 12:16 ` [PATCH] s390x/sclpconsole: implement resizing for vt220 consoles Maximilian Immanuel Brandtner
2026-09-28 9:30 ` [PATCH v7 00/12] virtio-console: notify about the terminal size Maximilian Immanuel Brandtner
13 siblings, 0 replies; 35+ messages in thread
From: Filip Hejsek @ 2026-06-09 19:16 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Paolo Bonzini, Michael S. Tsirkin,
Laurent Vivier, Amit Shah, Markus Armbruster, Eric Blake,
Eduardo Habkost, Marcel Apfelbaum, Yanan Wang, Zhao Liu,
Daniel P. Berrangé, Maximilian Immanuel Brandtner,
Philippe Mathieu-Daudé, Szymon Lukasz
From: Szymon Lukasz <noh4hss@gmail.com>
If a virtio serial port is a console port, forward terminal resize
messages from the chardev backend to the guest.
Signed-off-by: Szymon Lukasz <noh4hss@gmail.com>
[Filip: rename things, remove logic that is now handled in virtio-serial-bus.c]
Signed-off-by: Filip Hejsek <filip.hejsek@gmail.com>
---
hw/char/virtio-console.c | 34 +++++++++++++++++++++++++++++++---
1 file changed, 31 insertions(+), 3 deletions(-)
diff --git a/hw/char/virtio-console.c b/hw/char/virtio-console.c
index 36ad2ddc3f..db9d8ca797 100644
--- a/hw/char/virtio-console.c
+++ b/hw/char/virtio-console.c
@@ -107,6 +107,15 @@ static ssize_t flush_buf(VirtIOSerialPort *port,
return ret;
}
+static void virtconsole_update_size(VirtIOSerialPort *port)
+{
+ uint16_t cols, rows;
+ VirtConsole *vcon = VIRTIO_CONSOLE(port);
+
+ qemu_chr_fe_get_winsize(&vcon->chr, &cols, &rows);
+ virtio_serial_resize_console(port, cols, rows);
+}
+
/* Callback function that's called when the guest opens/closes the port */
static void set_guest_connected(VirtIOSerialPort *port, int guest_connected)
{
@@ -171,6 +180,23 @@ static void chr_event(void *opaque, QEMUChrEvent event)
}
}
+static void chr_event_console(void *opaque, QEMUChrEvent event)
+{
+ VirtConsole *vcon = opaque;
+ VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(vcon);
+
+ trace_virtio_console_chr_event(port->id, event);
+ switch (event) {
+ case CHR_EVENT_OPENED:
+ case CHR_EVENT_MUX_IN:
+ case CHR_EVENT_RESIZE:
+ virtconsole_update_size(port);
+ break;
+ default:
+ break;
+ }
+}
+
static int chr_be_change(void *opaque)
{
VirtConsole *vcon = opaque;
@@ -179,7 +205,9 @@ static int chr_be_change(void *opaque)
if (k->is_console) {
qemu_chr_fe_set_handlers(&vcon->chr, chr_can_read, chr_read,
- NULL, chr_be_change, vcon, NULL, true);
+ chr_event_console, chr_be_change,
+ vcon, NULL, true);
+ virtconsole_update_size(port);
} else {
qemu_chr_fe_set_handlers(&vcon->chr, chr_can_read, chr_read,
chr_event, chr_be_change, vcon, NULL, false);
@@ -207,7 +235,7 @@ static void virtconsole_enable_backend(VirtIOSerialPort *port, bool enable)
VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_GET_CLASS(port);
qemu_chr_fe_set_handlers(&vcon->chr, chr_can_read, chr_read,
- k->is_console ? NULL : chr_event,
+ k->is_console ? chr_event_console : chr_event,
chr_be_change, vcon, NULL, false);
} else {
qemu_chr_fe_set_handlers(&vcon->chr, NULL, NULL, NULL,
@@ -239,7 +267,7 @@ static void virtconsole_realize(DeviceState *dev, Error **errp)
*/
if (k->is_console) {
qemu_chr_fe_set_handlers(&vcon->chr, chr_can_read, chr_read,
- NULL, chr_be_change,
+ chr_event_console, chr_be_change,
vcon, NULL, true);
virtio_serial_open(port);
} else {
--
2.54.0
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH] s390x/sclpconsole: implement resizing for vt220 consoles
2026-06-09 19:16 [PATCH v7 00/12] virtio-console: notify about the terminal size Filip Hejsek
` (11 preceding siblings ...)
2026-06-09 19:16 ` [PATCH v7 12/12] virtio-console: notify the guest about terminal resizes Filip Hejsek
@ 2026-09-21 12:16 ` Maximilian Immanuel Brandtner
2026-09-21 12:19 ` Maximilian Immanuel Brandtner
` (3 more replies)
2026-09-28 9:30 ` [PATCH v7 00/12] virtio-console: notify about the terminal size Maximilian Immanuel Brandtner
13 siblings, 4 replies; 35+ messages in thread
From: Maximilian Immanuel Brandtner @ 2026-09-21 12:16 UTC (permalink / raw)
To: filip.hejsek
Cc: amit, armbru, berrange, eblake, eduardo, lvivier,
marcandre.lureau, marcel.apfelbaum, mst, noh4hss, pbonzini,
philmd, qemu-devel, wangyanan55, zhao1.liu, pasic, borntraeger,
jjherne, qemu-s390x, mjrosato, brueckner, farman, cohuck,
maximilian.immanuel.brandtner
Adds a tty code to indicate a resize frame. The body contains two big
endian 16-bit integers rows and columns.
Signed-off-by: Maximilian Immanuel Brandtner <maxbr@linux.ibm.com>
---
Requires the following pre-req:
[PATCH v7 00/12] virtio-console: notify about the terminal size
(https://lore.kernel.org/qemu-devel/20260609-console-resize-v7-0-0c550fdcec15@gmail.com/)
Testing:
- Tested on QEMU: commit 38879a667f with the following patches applied:
[PATCH v7 00/12] virtio-console: notify about the terminal size
- Tested on linux-next (commit c1f49dea2b8f) with the following patches
applied:
[PATCH 0/2] s390/sclp: Resize for sclp-vt220 console
---
hw/char/sclpconsole.c | 52 ++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 51 insertions(+), 1 deletion(-)
diff --git a/hw/char/sclpconsole.c b/hw/char/sclpconsole.c
index 179d12745c..acf1fea6b5 100644
--- a/hw/char/sclpconsole.c
+++ b/hw/char/sclpconsole.c
@@ -42,6 +42,7 @@ struct SCLPConsole {
uint32_t iov_data_len; /* length of byte stream in buffer */
uint32_t iov_sclp_rest; /* length of byte stream not read via SCLP */
bool notify; /* qemu_notify_event() req'd if true */
+ bool resize;
};
typedef struct SCLPConsole SCLPConsole;
@@ -81,6 +82,28 @@ static void chr_read(void *opaque, const uint8_t *buf, int size)
sclp_service_interrupt(0);
}
+static void chr_event(void *opaque, QEMUChrEvent event)
+{
+ SCLPConsole *scon = opaque;
+
+ assert(scon);
+
+ switch(event) {
+ case CHR_EVENT_RESIZE:
+ case CHR_EVENT_MUX_IN:
+ scon->resize = true;
+ scon->event.event_pending = true;
+ sclp_service_interrupt(0);
+ break;
+ case CHR_EVENT_BREAK:
+ case CHR_EVENT_OPENED:
+ case CHR_EVENT_MUX_OUT:
+ case CHR_EVENT_CLOSED:
+ /* ignore */
+ break;
+ }
+}
+
/* functions to be called by event facility */
static bool can_handle_event(uint8_t type)
@@ -105,6 +128,28 @@ static void get_console_data(SCLPEvent *event, uint8_t *buf, size_t *size,
int avail)
{
SCLPConsole *cons = SCLP_CONSOLE(event);
+ uint16_t be_rows, be_cols, rows, cols;
+
+ if (cons->resize) {
+ if (avail < 5) {
+ *size = 0;
+ return;
+ }
+
+ qemu_chr_fe_get_winsize(&cons->chr, &cols, &rows);
+ be_rows = cpu_to_be16(rows);
+ be_cols = cpu_to_be16(cols);
+
+ /* first byte hex 0x08 indicates a new terminal size follows */
+ *buf++ = 0x08;
+ memcpy(buf, &be_rows, sizeof(be_rows));
+ memcpy(buf + 2, &be_cols, sizeof(be_cols));
+ *size = 5;
+
+ cons->resize = false;
+
+ return;
+ }
/* first byte is hex 0 saying an ascii string follows */
*buf++ = '\0';
@@ -233,7 +278,12 @@ static int console_init(SCLPEvent *event)
}
console_available = true;
qemu_chr_fe_set_handlers(&scon->chr, chr_can_read,
- chr_read, NULL, NULL, scon, NULL, true);
+ chr_read, chr_event, NULL, scon, NULL, true);
+
+ /* set the initial terminal size */
+ scon->resize = true;
+ scon->event.event_pending = true;
+ sclp_service_interrupt(0);
return 0;
}
--
2.54.0
^ permalink raw reply related [flat|nested] 35+ messages in thread* Re: [PATCH] s390x/sclpconsole: implement resizing for vt220 consoles
2026-09-21 12:16 ` [PATCH] s390x/sclpconsole: implement resizing for vt220 consoles Maximilian Immanuel Brandtner
@ 2026-09-21 12:19 ` Maximilian Immanuel Brandtner
2026-09-25 2:42 ` Matthew Rosato
` (2 subsequent siblings)
3 siblings, 0 replies; 35+ messages in thread
From: Maximilian Immanuel Brandtner @ 2026-09-21 12:19 UTC (permalink / raw)
To: filip.hejsek
Cc: amit, armbru, berrange, eblake, eduardo, lvivier,
marcandre.lureau, marcel.apfelbaum, mst, noh4hss, pbonzini,
philmd, qemu-devel, wangyanan55, zhao1.liu, pasic, borntraeger,
jjherne, qemu-s390x, mjrosato, brueckner, farman, cohuck,
maximilian.immanuel.brandtner
For the Linux Kernel patch-set see: [PATCH 0/2] s390/sclp: Resize for
sclp-vt220 console
(https://lore.kernel.org/all/20260921121619.1354611-1-
maxbr@linux.ibm.com/T/#t)
^ permalink raw reply [flat|nested] 35+ messages in thread* Re: [PATCH] s390x/sclpconsole: implement resizing for vt220 consoles
2026-09-21 12:16 ` [PATCH] s390x/sclpconsole: implement resizing for vt220 consoles Maximilian Immanuel Brandtner
2026-09-21 12:19 ` Maximilian Immanuel Brandtner
@ 2026-09-25 2:42 ` Matthew Rosato
2026-09-28 8:21 ` Maximilian Immanuel Brandtner
2026-09-28 9:08 ` [PATCH v2] " Maximilian Immanuel Brandtner
2026-09-29 15:20 ` [PATCH v3 0/2] " Maximilian Immanuel Brandtner
3 siblings, 1 reply; 35+ messages in thread
From: Matthew Rosato @ 2026-09-25 2:42 UTC (permalink / raw)
To: Maximilian Immanuel Brandtner, filip.hejsek
Cc: amit, armbru, berrange, eblake, eduardo, lvivier,
marcandre.lureau, marcel.apfelbaum, mst, noh4hss, pbonzini,
philmd, qemu-devel, wangyanan55, zhao1.liu, pasic, borntraeger,
jjherne, qemu-s390x, brueckner, farman, cohuck,
maximilian.immanuel.brandtner
On 9/21/26 8:16 AM, Maximilian Immanuel Brandtner wrote:
> Adds a tty code to indicate a resize frame. The body contains two big
> endian 16-bit integers rows and columns.
>
> Signed-off-by: Maximilian Immanuel Brandtner <maxbr@linux.ibm.com>
> ---
> Requires the following pre-req:
> [PATCH v7 00/12] virtio-console: notify about the terminal size
> (https://lore.kernel.org/qemu-devel/20260609-console-resize-v7-0-0c550fdcec15@gmail.com/)
>
> Testing:
> - Tested on QEMU: commit 38879a667f with the following patches applied:
> [PATCH v7 00/12] virtio-console: notify about the terminal size
> - Tested on linux-next (commit c1f49dea2b8f) with the following patches
> applied:
> [PATCH 0/2] s390/sclp: Resize for sclp-vt220 console
> ---
> hw/char/sclpconsole.c | 52 ++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 51 insertions(+), 1 deletion(-)
>
> diff --git a/hw/char/sclpconsole.c b/hw/char/sclpconsole.c
> index 179d12745c..acf1fea6b5 100644
> --- a/hw/char/sclpconsole.c
> +++ b/hw/char/sclpconsole.c
> @@ -42,6 +42,7 @@ struct SCLPConsole {
> uint32_t iov_data_len; /* length of byte stream in buffer */
> uint32_t iov_sclp_rest; /* length of byte stream not read via SCLP */
> bool notify; /* qemu_notify_event() req'd if true */
> + bool resize;
Does this need to be in vmstate_sclpconsole / included in migration so
we don't miss pending resize events during a migration?
Also, should the resize value be explicitly set to false during
console_reset()?
[...]
> @@ -105,6 +128,28 @@ static void get_console_data(SCLPEvent *event, uint8_t *buf, size_t *size,
> int avail)
> {
> SCLPConsole *cons = SCLP_CONSOLE(event);
> + uint16_t be_rows, be_cols, rows, cols;
> +
> + if (cons->resize) {
> + if (avail < 5) {
I dislike the use of a magic number here, when it's tied directly to the
combined sizes of a few structures. Can you derive the size instead e.g.
sizeof(*buf) + sizeof(be_rows) + sizeof(be_cols);
> + *size = 0;
> + return;
> + }
> +
> + qemu_chr_fe_get_winsize(&cons->chr, &cols, &rows);
> + be_rows = cpu_to_be16(rows);
> + be_cols = cpu_to_be16(cols);
> +
> + /* first byte hex 0x08 indicates a new terminal size follows */
> + *buf++ = 0x08;
> + memcpy(buf, &be_rows, sizeof(be_rows));
> + memcpy(buf + 2, &be_cols, sizeof(be_cols));
> + *size = 5;
Ditto
^ permalink raw reply [flat|nested] 35+ messages in thread* Re: [PATCH] s390x/sclpconsole: implement resizing for vt220 consoles
2026-09-25 2:42 ` Matthew Rosato
@ 2026-09-28 8:21 ` Maximilian Immanuel Brandtner
0 siblings, 0 replies; 35+ messages in thread
From: Maximilian Immanuel Brandtner @ 2026-09-28 8:21 UTC (permalink / raw)
To: Matthew Rosato, filip.hejsek
Cc: amit, armbru, berrange, eblake, eduardo, lvivier,
marcandre.lureau, marcel.apfelbaum, mst, noh4hss, pbonzini,
philmd, qemu-devel, wangyanan55, zhao1.liu, pasic, borntraeger,
jjherne, qemu-s390x, brueckner, farman, cohuck,
maximilian.immanuel.brandtner
On Thu, 2026-09-24 at 22:42 -0400, Matthew Rosato wrote:
> On 9/21/26 8:16 AM, Maximilian Immanuel Brandtner wrote:
> > Adds a tty code to indicate a resize frame. The body contains two
> > big
> > endian 16-bit integers rows and columns.
> >
> > Signed-off-by: Maximilian Immanuel Brandtner <maxbr@linux.ibm.com>
> > ---
> > Requires the following pre-req:
> > [PATCH v7 00/12] virtio-console: notify about the terminal size
> >
> > (https://lore.kernel.org/qemu-devel/20260609-console-resize-v7-0-0c
> > 550fdcec15@gmail.com/)
> >
> > Testing:
> > - Tested on QEMU: commit 38879a667f with the following patches
> > applied:
> > [PATCH v7 00/12] virtio-console: notify about the terminal size
> > - Tested on linux-next (commit c1f49dea2b8f) with the following
> > patches
> > applied:
> > [PATCH 0/2] s390/sclp: Resize for sclp-vt220 console
> > ---
> > hw/char/sclpconsole.c | 52
> > ++++++++++++++++++++++++++++++++++++++++++-
> > 1 file changed, 51 insertions(+), 1 deletion(-)
> >
> > diff --git a/hw/char/sclpconsole.c b/hw/char/sclpconsole.c
> > index 179d12745c..acf1fea6b5 100644
> > --- a/hw/char/sclpconsole.c
> > +++ b/hw/char/sclpconsole.c
> > @@ -42,6 +42,7 @@ struct SCLPConsole {
> > uint32_t iov_data_len; /* length of byte stream in
> > buffer */
> > uint32_t iov_sclp_rest; /* length of byte stream not read via
> > SCLP */
> > bool notify; /* qemu_notify_event() req'd if
> > true */
> > + bool resize;
>
> Does this need to be in vmstate_sclpconsole / included in migration
> so
> we don't miss pending resize events during a migration?
No, console_init() already sets scon->resize = true. So after migration
a resize event is always pending.
>
> Also, should the resize value be explicitly set to false during
> console_reset()?
Not to false. This would eliminate the initial resize event, because
console_reset() runs after console_init(). We need an initial resize
event, because the chardev (eg chardev-stdio) might send its
initializing resize event before sclpconsole has been initialized.
That said, I think it's better for me to move the initial resize code
from console_init to console_reset.
> [...]
>
> > @@ -105,6 +128,28 @@ static void get_console_data(SCLPEvent *event,
> > uint8_t *buf, size_t *size,
> > int avail)
> > {
> > SCLPConsole *cons = SCLP_CONSOLE(event);
> > + uint16_t be_rows, be_cols, rows, cols;
> > +
> > + if (cons->resize) {
> > + if (avail < 5) {
>
> I dislike the use of a magic number here, when it's tied directly to
> the
> combined sizes of a few structures. Can you derive the size instead
> e.g.
> sizeof(*buf) + sizeof(be_rows) + sizeof(be_cols);
Sure, though sizeof(*buf) seems misleading, as we're really dealing
with a 1-byte header value which just so happens to be the same type as
the raw buffer. Looking at the code again though, I think it's best to
use a packed struct instead.
>
> > + *size = 0;
> > + return;
> > + }
> > +
> > + qemu_chr_fe_get_winsize(&cons->chr, &cols, &rows);
> > + be_rows = cpu_to_be16(rows);
> > + be_cols = cpu_to_be16(cols);
> > +
> > + /* first byte hex 0x08 indicates a new terminal size
> > follows */
> > + *buf++ = 0x08;
> > + memcpy(buf, &be_rows, sizeof(be_rows));
> > + memcpy(buf + 2, &be_cols, sizeof(be_cols));
> > + *size = 5;
>
> Ditto
>
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH v2] s390x/sclpconsole: implement resizing for vt220 consoles
2026-09-21 12:16 ` [PATCH] s390x/sclpconsole: implement resizing for vt220 consoles Maximilian Immanuel Brandtner
2026-09-21 12:19 ` Maximilian Immanuel Brandtner
2026-09-25 2:42 ` Matthew Rosato
@ 2026-09-28 9:08 ` Maximilian Immanuel Brandtner
2026-09-28 13:32 ` Jason J. Herne
2026-09-29 15:20 ` [PATCH v3 0/2] " Maximilian Immanuel Brandtner
3 siblings, 1 reply; 35+ messages in thread
From: Maximilian Immanuel Brandtner @ 2026-09-28 9:08 UTC (permalink / raw)
To: filip.hejsek
Cc: amit, armbru, berrange, eblake, eduardo, lvivier,
marcandre.lureau, marcel.apfelbaum, mst, noh4hss, pbonzini,
philmd, qemu-devel, wangyanan55, zhao1.liu, pasic, borntraeger,
jjherne, qemu-s390x, mjrosato, brueckner, farman, cohuck,
maximilian.immanuel.brandtner
Add a tty code to indicate a resize frame. The body contains two big
endian 16-bit integers rows and columns.
After reset, the guest must be informed of the terminal size again. A
chardev that doesn't report its size yields 0x0, which shouldn't replace
the guest's default.
Signed-off-by: Maximilian Immanuel Brandtner <maxbr@linux.ibm.com>
---
Changelog:
v2:
- Use packed struct and named event type codes for resize frames
- Trigger initial resize event in console_reset() instead of
console_init(), skip when chardev reports no size
- Reset event_pending after resize event
Requires the following pre-req:
[PATCH v7 00/12] virtio-console: notify about the terminal size
(https://lore.kernel.org/qemu-devel/20260609-console-resize-v7-0-0c550fdcec15@gmail.com/)
Testing:
- Tested on QEMU: commit 38879a667f with the following patches applied:
[PATCH v7 00/12] virtio-console: notify about the terminal size
- Tested on linux-next (commit c1f49dea2b8f) with the following patches
applied:
[PATCH 0/2] s390/sclp: Resize for sclp-vt220 console
---
hw/char/sclpconsole.c | 92 +++++++++++++++++++++++++++++++++++++------
1 file changed, 80 insertions(+), 12 deletions(-)
diff --git a/hw/char/sclpconsole.c b/hw/char/sclpconsole.c
index 179d12745c..12033e1e46 100644
--- a/hw/char/sclpconsole.c
+++ b/hw/char/sclpconsole.c
@@ -33,6 +33,9 @@ typedef struct ASCIIConsoleData {
/* max size for ASCII data in 4K SCCB page */
#define SIZE_BUFFER_VT220 4080
+#define SCLP_CONSOLE_EVENT_TYPE_DATA 0x00
+#define SCLP_CONSOLE_EVENT_TYPE_RESIZE 0x08
+
struct SCLPConsole {
SCLPEvent event;
CharFrontend chr;
@@ -42,6 +45,8 @@ struct SCLPConsole {
uint32_t iov_data_len; /* length of byte stream in buffer */
uint32_t iov_sclp_rest; /* length of byte stream not read via SCLP */
bool notify; /* qemu_notify_event() req'd if true */
+ bool resize;
+ bool resize_init;
};
typedef struct SCLPConsole SCLPConsole;
@@ -49,6 +54,12 @@ typedef struct SCLPConsole SCLPConsole;
DECLARE_INSTANCE_CHECKER(SCLPConsole, SCLP_CONSOLE,
TYPE_SCLP_CONSOLE)
+typedef struct SCLPConsoleResizeData {
+ uint8_t type;
+ uint16_t rows;
+ uint16_t cols;
+} QEMU_PACKED SCLPConsoleResizeData;
+
/* character layer call-back functions */
/* Return number of bytes that fit into iov buffer */
@@ -81,6 +92,29 @@ static void chr_read(void *opaque, const uint8_t *buf, int size)
sclp_service_interrupt(0);
}
+static void chr_event(void *opaque, QEMUChrEvent event)
+{
+ SCLPConsole *scon = opaque;
+
+ assert(scon);
+
+ switch (event) {
+ case CHR_EVENT_RESIZE:
+ case CHR_EVENT_MUX_IN:
+ scon->resize = true;
+ scon->resize_init = false;
+ scon->event.event_pending = true;
+ sclp_service_interrupt(0);
+ break;
+ case CHR_EVENT_BREAK:
+ case CHR_EVENT_OPENED:
+ case CHR_EVENT_MUX_OUT:
+ case CHR_EVENT_CLOSED:
+ /* ignore */
+ break;
+ }
+}
+
/* functions to be called by event facility */
static bool can_handle_event(uint8_t type)
@@ -104,10 +138,37 @@ static sccb_mask_t receive_mask(void)
static void get_console_data(SCLPEvent *event, uint8_t *buf, size_t *size,
int avail)
{
+ SCLPConsoleResizeData resize_data;
SCLPConsole *cons = SCLP_CONSOLE(event);
+ uint16_t rows, cols;
+
+ if (cons->resize) {
+ if (avail < sizeof(resize_data)) {
+ *size = 0;
+ return;
+ }
- /* first byte is hex 0 saying an ascii string follows */
- *buf++ = '\0';
+ qemu_chr_fe_get_winsize(&cons->chr, &cols, &rows);
+
+ if (cons->resize_init && cols == 0 && rows == 0) {
+ *size = 0;
+ } else {
+ resize_data.type = SCLP_CONSOLE_EVENT_TYPE_RESIZE;
+ resize_data.rows = cpu_to_be16(rows);
+ resize_data.cols = cpu_to_be16(cols);
+
+ memcpy(buf, &resize_data, sizeof(resize_data));
+ *size = sizeof(resize_data);
+ }
+
+ cons->resize = false;
+ cons->resize_init = false;
+ event->event_pending = cons->iov_sclp_rest != 0;
+
+ return;
+ }
+
+ *buf++ = SCLP_CONSOLE_EVENT_TYPE_DATA;
avail--;
/* if all data fit into provided SCLP buffer */
if (avail >= cons->iov_sclp_rest) {
@@ -150,6 +211,9 @@ static int read_event_data(SCLPEvent *event, EventBufferHeader *evt_buf_hdr,
to = (uint8_t *)&acd->data;
avail = *slen - sizeof(ASCIIConsoleData);
get_console_data(event, to, &src_len, avail);
+ if (src_len == 0) {
+ return 0;
+ }
acd->ebh.length = cpu_to_be16(sizeof(ASCIIConsoleData) + src_len);
acd->ebh.type = SCLP_EVENT_ASCII_CONSOLE_DATA;
@@ -233,22 +297,26 @@ static int console_init(SCLPEvent *event)
}
console_available = true;
qemu_chr_fe_set_handlers(&scon->chr, chr_can_read,
- chr_read, NULL, NULL, scon, NULL, true);
+ chr_read, chr_event, NULL, scon, NULL, true);
return 0;
}
static void console_reset(DeviceState *dev)
{
- SCLPEvent *event = SCLP_EVENT(dev);
- SCLPConsole *scon = SCLP_CONSOLE(event);
-
- event->event_pending = false;
- scon->iov_sclp = 0;
- scon->iov_bs = 0;
- scon->iov_data_len = 0;
- scon->iov_sclp_rest = 0;
- scon->notify = false;
+ SCLPEvent *event = SCLP_EVENT(dev);
+ SCLPConsole *scon = SCLP_CONSOLE(event);
+
+ scon->iov_sclp = 0;
+ scon->iov_bs = 0;
+ scon->iov_data_len = 0;
+ scon->iov_sclp_rest = 0;
+ scon->notify = false;
+
+ /* the guest defaults its terminal size on reset, announce the real one */
+ scon->resize = true;
+ scon->resize_init = true;
+ event->event_pending = true;
}
static const Property console_properties[] = {
--
2.54.0
^ permalink raw reply related [flat|nested] 35+ messages in thread* Re: [PATCH v2] s390x/sclpconsole: implement resizing for vt220 consoles
2026-09-28 9:08 ` [PATCH v2] " Maximilian Immanuel Brandtner
@ 2026-09-28 13:32 ` Jason J. Herne
2026-09-28 19:28 ` Maximilian Immanuel Brandtner
0 siblings, 1 reply; 35+ messages in thread
From: Jason J. Herne @ 2026-09-28 13:32 UTC (permalink / raw)
To: Maximilian Immanuel Brandtner, filip.hejsek
Cc: amit, armbru, berrange, eblake, eduardo, lvivier,
marcandre.lureau, marcel.apfelbaum, mst, noh4hss, pbonzini,
philmd, qemu-devel, wangyanan55, zhao1.liu, pasic, borntraeger,
qemu-s390x, mjrosato, brueckner, farman, cohuck,
maximilian.immanuel.brandtner
On 9/28/26 5:08 AM, Maximilian Immanuel Brandtner wrote:
> Add a tty code to indicate a resize frame. The body contains two big
> endian 16-bit integers rows and columns.
>
> After reset, the guest must be informed of the terminal size again. A
> chardev that doesn't report its size yields 0x0, which shouldn't replace
> the guest's default.
>
> Signed-off-by: Maximilian Immanuel Brandtner <maxbr@linux.ibm.com>
> ---
> Changelog:
> v2:
> - Use packed struct and named event type codes for resize frames
> - Trigger initial resize event in console_reset() instead of
> console_init(), skip when chardev reports no size
> - Reset event_pending after resize event
>
> Requires the following pre-req:
> [PATCH v7 00/12] virtio-console: notify about the terminal size
> (https://lore.kernel.org/qemu-devel/20260609-console-resize-v7-0-0c550fdcec15@gmail.com/)
>
> Testing:
> - Tested on QEMU: commit 38879a667f with the following patches applied:
> [PATCH v7 00/12] virtio-console: notify about the terminal size
> - Tested on linux-next (commit c1f49dea2b8f) with the following patches
> applied:
> [PATCH 0/2] s390/sclp: Resize for sclp-vt220 console
> ---
> hw/char/sclpconsole.c | 92 +++++++++++++++++++++++++++++++++++++------
> 1 file changed, 80 insertions(+), 12 deletions(-)
>
> diff --git a/hw/char/sclpconsole.c b/hw/char/sclpconsole.c
> index 179d12745c..12033e1e46 100644
> --- a/hw/char/sclpconsole.c
> +++ b/hw/char/sclpconsole.c
> @@ -33,6 +33,9 @@ typedef struct ASCIIConsoleData {
> /* max size for ASCII data in 4K SCCB page */
> #define SIZE_BUFFER_VT220 4080
>
> +#define SCLP_CONSOLE_EVENT_TYPE_DATA 0x00
> +#define SCLP_CONSOLE_EVENT_TYPE_RESIZE 0x08
> +
> struct SCLPConsole {
> SCLPEvent event;
> CharFrontend chr;
> @@ -42,6 +45,8 @@ struct SCLPConsole {
> uint32_t iov_data_len; /* length of byte stream in buffer */
> uint32_t iov_sclp_rest; /* length of byte stream not read via SCLP */
> bool notify; /* qemu_notify_event() req'd if true */
> + bool resize;
> + bool resize_init;
> };
> typedef struct SCLPConsole SCLPConsole;
>
> @@ -49,6 +54,12 @@ typedef struct SCLPConsole SCLPConsole;
> DECLARE_INSTANCE_CHECKER(SCLPConsole, SCLP_CONSOLE,
> TYPE_SCLP_CONSOLE)
>
> +typedef struct SCLPConsoleResizeData {
> + uint8_t type;
> + uint16_t rows;
> + uint16_t cols;
> +} QEMU_PACKED SCLPConsoleResizeData;
> +
> /* character layer call-back functions */
>
> /* Return number of bytes that fit into iov buffer */
> @@ -81,6 +92,29 @@ static void chr_read(void *opaque, const uint8_t *buf, int size)
> sclp_service_interrupt(0);
> }
>
> +static void chr_event(void *opaque, QEMUChrEvent event)
> +{
> + SCLPConsole *scon = opaque;
> +
> + assert(scon);
> +
> + switch (event) {
> + case CHR_EVENT_RESIZE:
> + case CHR_EVENT_MUX_IN:
> + scon->resize = true;
> + scon->resize_init = false;
> + scon->event.event_pending = true;
> + sclp_service_interrupt(0);
> + break;
> + case CHR_EVENT_BREAK:
> + case CHR_EVENT_OPENED:
> + case CHR_EVENT_MUX_OUT:
> + case CHR_EVENT_CLOSED:
> + /* ignore */
> + break;
> + }
> +}
> +
> /* functions to be called by event facility */
>
> static bool can_handle_event(uint8_t type)
> @@ -104,10 +138,37 @@ static sccb_mask_t receive_mask(void)
> static void get_console_data(SCLPEvent *event, uint8_t *buf, size_t *size,
> int avail)
> {
> + SCLPConsoleResizeData resize_data;
> SCLPConsole *cons = SCLP_CONSOLE(event);
> + uint16_t rows, cols;
> +
> + if (cons->resize) {
> + if (avail < sizeof(resize_data)) {
> + *size = 0;
> + return;
> + }
>
> - /* first byte is hex 0 saying an ascii string follows */
> - *buf++ = '\0';
> + qemu_chr_fe_get_winsize(&cons->chr, &cols, &rows);
> +
> + if (cons->resize_init && cols == 0 && rows == 0) {
> + *size = 0;
> + } else {
> + resize_data.type = SCLP_CONSOLE_EVENT_TYPE_RESIZE;
> + resize_data.rows = cpu_to_be16(rows);
> + resize_data.cols = cpu_to_be16(cols);
> +
> + memcpy(buf, &resize_data, sizeof(resize_data));
> + *size = sizeof(resize_data);
> + }
> +
> + cons->resize = false;
> + cons->resize_init = false;
> + event->event_pending = cons->iov_sclp_rest != 0;
> +
> + return;
> + }
> +
> + *buf++ = SCLP_CONSOLE_EVENT_TYPE_DATA;
> avail--;
> /* if all data fit into provided SCLP buffer */
> if (avail >= cons->iov_sclp_rest) {
> @@ -150,6 +211,9 @@ static int read_event_data(SCLPEvent *event, EventBufferHeader *evt_buf_hdr,
> to = (uint8_t *)&acd->data;
> avail = *slen - sizeof(ASCIIConsoleData);
> get_console_data(event, to, &src_len, avail);
> + if (src_len == 0) {
> + return 0;
> + }
> acd->ebh.length = cpu_to_be16(sizeof(ASCIIConsoleData) + src_len);
> acd->ebh.type = SCLP_EVENT_ASCII_CONSOLE_DATA;
> @@ -233,22 +297,26 @@ static int console_init(SCLPEvent *event)
> }
> console_available = true;
> qemu_chr_fe_set_handlers(&scon->chr, chr_can_read,
> - chr_read, NULL, NULL, scon, NULL, true);
> + chr_read, chr_event, NULL, scon, NULL, true);
>
> return 0;
> }
>
> static void console_reset(DeviceState *dev)
> {
> - SCLPEvent *event = SCLP_EVENT(dev);
> - SCLPConsole *scon = SCLP_CONSOLE(event);
> -
> - event->event_pending = false;
> - scon->iov_sclp = 0;
> - scon->iov_bs = 0;
> - scon->iov_data_len = 0;
> - scon->iov_sclp_rest = 0;
> - scon->notify = false;
> + SCLPEvent *event = SCLP_EVENT(dev);
> + SCLPConsole *scon = SCLP_CONSOLE(event);
> +
> + scon->iov_sclp = 0;
> + scon->iov_bs = 0;
> + scon->iov_data_len = 0;
> + scon->iov_sclp_rest = 0;
> + scon->notify = false;
> +
> + /* the guest defaults its terminal size on reset, announce the real one */
> + scon->resize = true;
> + scon->resize_init = true;
> + event->event_pending = true;
> }
This is a style fix, included in a functional patch. I suppose it is
probably borderline, but it might be best to put this in its own patch.
Other than that:
Reviewed-by: Jason J. Herne <jjherne@linux.ibm.com>
^ permalink raw reply [flat|nested] 35+ messages in thread* Re: [PATCH v2] s390x/sclpconsole: implement resizing for vt220 consoles
2026-09-28 13:32 ` Jason J. Herne
@ 2026-09-28 19:28 ` Maximilian Immanuel Brandtner
2026-09-28 20:33 ` Matthew Rosato
0 siblings, 1 reply; 35+ messages in thread
From: Maximilian Immanuel Brandtner @ 2026-09-28 19:28 UTC (permalink / raw)
To: Jason J. Herne, filip.hejsek
Cc: amit, armbru, berrange, eblake, eduardo, lvivier,
marcandre.lureau, marcel.apfelbaum, mst, noh4hss, pbonzini,
philmd, qemu-devel, wangyanan55, zhao1.liu, pasic, borntraeger,
qemu-s390x, mjrosato, brueckner, farman, cohuck,
maximilian.immanuel.brandtner
On Mon, 2026-09-28 at 09:32 -0400, Jason J. Herne wrote:
>
>
> On 9/28/26 5:08 AM, Maximilian Immanuel Brandtner wrote:
> > Add a tty code to indicate a resize frame. The body contains two
> > big
> > endian 16-bit integers rows and columns.
> >
> > After reset, the guest must be informed of the terminal size again.
> > A
> > chardev that doesn't report its size yields 0x0, which shouldn't
> > replace
> > the guest's default.
> >
> > Signed-off-by: Maximilian Immanuel Brandtner <maxbr@linux.ibm.com>
> > ---
> > Changelog:
> > v2:
> > - Use packed struct and named event type codes for resize frames
> > - Trigger initial resize event in console_reset() instead of
> > console_init(), skip when chardev reports no size
> > - Reset event_pending after resize event
> >
> > Requires the following pre-req:
> > [PATCH v7 00/12] virtio-console: notify about the terminal
> > size
> >
> > (https://lore.kernel.org/qemu-devel/20260609-console-resize-v7-0-0c
> > 550fdcec15@gmail.com/)
> >
> > Testing:
> > - Tested on QEMU: commit 38879a667f with the following patches
> > applied:
> > [PATCH v7 00/12] virtio-console: notify about the terminal
> > size
> > - Tested on linux-next (commit c1f49dea2b8f) with the following
> > patches
> > applied:
> > [PATCH 0/2] s390/sclp: Resize for sclp-vt220 console
> > ---
> > hw/char/sclpconsole.c | 92 +++++++++++++++++++++++++++++++++++++-
> > -----
> > 1 file changed, 80 insertions(+), 12 deletions(-)
> >
> > diff --git a/hw/char/sclpconsole.c b/hw/char/sclpconsole.c
> > index 179d12745c..12033e1e46 100644
> > --- a/hw/char/sclpconsole.c
> > +++ b/hw/char/sclpconsole.c
> > @@ -33,6 +33,9 @@ typedef struct ASCIIConsoleData {
> > /* max size for ASCII data in 4K SCCB page */
> > #define SIZE_BUFFER_VT220 4080
> >
> > +#define SCLP_CONSOLE_EVENT_TYPE_DATA 0x00
> > +#define SCLP_CONSOLE_EVENT_TYPE_RESIZE 0x08
> > +
> > struct SCLPConsole {
> > SCLPEvent event;
> > CharFrontend chr;
> > @@ -42,6 +45,8 @@ struct SCLPConsole {
> > uint32_t iov_data_len; /* length of byte stream in
> > buffer */
> > uint32_t iov_sclp_rest; /* length of byte stream not read via
> > SCLP */
> > bool notify; /* qemu_notify_event() req'd if
> > true */
> > + bool resize;
> > + bool resize_init;
> > };
> > typedef struct SCLPConsole SCLPConsole;
> >
> > @@ -49,6 +54,12 @@ typedef struct SCLPConsole SCLPConsole;
> > DECLARE_INSTANCE_CHECKER(SCLPConsole, SCLP_CONSOLE,
> > TYPE_SCLP_CONSOLE)
> >
> > +typedef struct SCLPConsoleResizeData {
> > + uint8_t type;
> > + uint16_t rows;
> > + uint16_t cols;
> > +} QEMU_PACKED SCLPConsoleResizeData;
> > +
> > /* character layer call-back functions */
> >
> > /* Return number of bytes that fit into iov buffer */
> > @@ -81,6 +92,29 @@ static void chr_read(void *opaque, const uint8_t
> > *buf, int size)
> > sclp_service_interrupt(0);
> > }
> >
> > +static void chr_event(void *opaque, QEMUChrEvent event)
> > +{
> > + SCLPConsole *scon = opaque;
> > +
> > + assert(scon);
> > +
> > + switch (event) {
> > + case CHR_EVENT_RESIZE:
> > + case CHR_EVENT_MUX_IN:
> > + scon->resize = true;
> > + scon->resize_init = false;
> > + scon->event.event_pending = true;
> > + sclp_service_interrupt(0);
> > + break;
> > + case CHR_EVENT_BREAK:
> > + case CHR_EVENT_OPENED:
> > + case CHR_EVENT_MUX_OUT:
> > + case CHR_EVENT_CLOSED:
> > + /* ignore */
> > + break;
> > + }
> > +}
> > +
> > /* functions to be called by event facility */
> >
> > static bool can_handle_event(uint8_t type)
> > @@ -104,10 +138,37 @@ static sccb_mask_t receive_mask(void)
> > static void get_console_data(SCLPEvent *event, uint8_t *buf,
> > size_t *size,
> > int avail)
> > {
> > + SCLPConsoleResizeData resize_data;
> > SCLPConsole *cons = SCLP_CONSOLE(event);
> > + uint16_t rows, cols;
> > +
> > + if (cons->resize) {
> > + if (avail < sizeof(resize_data)) {
> > + *size = 0;
> > + return;
> > + }
> >
> > - /* first byte is hex 0 saying an ascii string follows */
> > - *buf++ = '\0';
> > + qemu_chr_fe_get_winsize(&cons->chr, &cols, &rows);
> > +
> > + if (cons->resize_init && cols == 0 && rows == 0) {
> > + *size = 0;
> > + } else {
> > + resize_data.type = SCLP_CONSOLE_EVENT_TYPE_RESIZE;
> > + resize_data.rows = cpu_to_be16(rows);
> > + resize_data.cols = cpu_to_be16(cols);
> > +
> > + memcpy(buf, &resize_data, sizeof(resize_data));
> > + *size = sizeof(resize_data);
> > + }
> > +
> > + cons->resize = false;
> > + cons->resize_init = false;
> > + event->event_pending = cons->iov_sclp_rest != 0;
> > +
> > + return;
> > + }
> > +
> > + *buf++ = SCLP_CONSOLE_EVENT_TYPE_DATA;
> > avail--;
> > /* if all data fit into provided SCLP buffer */
> > if (avail >= cons->iov_sclp_rest) {
> > @@ -150,6 +211,9 @@ static int read_event_data(SCLPEvent *event,
> > EventBufferHeader *evt_buf_hdr,
> > to = (uint8_t *)&acd->data;
> > avail = *slen - sizeof(ASCIIConsoleData);
> > get_console_data(event, to, &src_len, avail);
> > + if (src_len == 0) {
> > + return 0;
> > + }
> > acd->ebh.length = cpu_to_be16(sizeof(ASCIIConsoleData) +
> > src_len);
> > acd->ebh.type = SCLP_EVENT_ASCII_CONSOLE_DATA;
> > @@ -233,22 +297,26 @@ static int console_init(SCLPEvent *event)
> > }
> > console_available = true;
> > qemu_chr_fe_set_handlers(&scon->chr, chr_can_read,
> > - chr_read, NULL, NULL, scon, NULL,
> > true);
> > + chr_read, chr_event, NULL, scon,
> > NULL, true);
> >
> > return 0;
> > }
> >
> > static void console_reset(DeviceState *dev)
> > {
> > - SCLPEvent *event = SCLP_EVENT(dev);
> > - SCLPConsole *scon = SCLP_CONSOLE(event);
> > -
> > - event->event_pending = false;
> > - scon->iov_sclp = 0;
> > - scon->iov_bs = 0;
> > - scon->iov_data_len = 0;
> > - scon->iov_sclp_rest = 0;
> > - scon->notify = false;
> > + SCLPEvent *event = SCLP_EVENT(dev);
> > + SCLPConsole *scon = SCLP_CONSOLE(event);
> > +
> > + scon->iov_sclp = 0;
> > + scon->iov_bs = 0;
> > + scon->iov_data_len = 0;
> > + scon->iov_sclp_rest = 0;
> > + scon->notify = false;
> > +
> > + /* the guest defaults its terminal size on reset, announce the
> > real one */
> > + scon->resize = true;
> > + scon->resize_init = true;
> > + event->event_pending = true;
> > }
>
> This is a style fix, included in a functional patch. I suppose it is
> probably borderline, but it might be best to put this in its own
> patch.
I thought about that, but concluded that a 6-line indentation commit
would be too small to warrant its own patch. If you'd prefer it to be
split I could also send it as a seperate patch.
>
> Other than that:
> Reviewed-by: Jason J. Herne <jjherne@linux.ibm.com>
Thanks
^ permalink raw reply [flat|nested] 35+ messages in thread* Re: [PATCH v2] s390x/sclpconsole: implement resizing for vt220 consoles
2026-09-28 19:28 ` Maximilian Immanuel Brandtner
@ 2026-09-28 20:33 ` Matthew Rosato
0 siblings, 0 replies; 35+ messages in thread
From: Matthew Rosato @ 2026-09-28 20:33 UTC (permalink / raw)
To: Maximilian Immanuel Brandtner, Jason J. Herne, filip.hejsek
Cc: amit, armbru, berrange, eblake, eduardo, lvivier,
marcandre.lureau, marcel.apfelbaum, mst, noh4hss, pbonzini,
philmd, qemu-devel, wangyanan55, zhao1.liu, pasic, borntraeger,
qemu-s390x, brueckner, farman, cohuck,
maximilian.immanuel.brandtner
On 9/28/26 3:28 PM, Maximilian Immanuel Brandtner wrote:
> On Mon, 2026-09-28 at 09:32 -0400, Jason J. Herne wrote:
>>
>>
>> On 9/28/26 5:08 AM, Maximilian Immanuel Brandtner wrote:
>>> Add a tty code to indicate a resize frame. The body contains two
>>> big
>>> endian 16-bit integers rows and columns.
>>>
>>> After reset, the guest must be informed of the terminal size again.
>>> A
>>> chardev that doesn't report its size yields 0x0, which shouldn't
>>> replace
>>> the guest's default.
>>>
>>> Signed-off-by: Maximilian Immanuel Brandtner <maxbr@linux.ibm.com>
>>> ---
>>> Changelog:
>>> v2:
>>> - Use packed struct and named event type codes for resize frames
>>> - Trigger initial resize event in console_reset() instead of
>>> console_init(), skip when chardev reports no size
>>> - Reset event_pending after resize event
>>>
>>> Requires the following pre-req:
>>> [PATCH v7 00/12] virtio-console: notify about the terminal
>>> size
>>>
>>> (https://lore.kernel.org/qemu-devel/20260609-console-resize-v7-0-0c
>>> 550fdcec15@gmail.com/)
>>>
>>> Testing:
>>> - Tested on QEMU: commit 38879a667f with the following patches
>>> applied:
>>> [PATCH v7 00/12] virtio-console: notify about the terminal
>>> size
>>> - Tested on linux-next (commit c1f49dea2b8f) with the following
>>> patches
>>> applied:
>>> [PATCH 0/2] s390/sclp: Resize for sclp-vt220 console
>>> ---
>>> hw/char/sclpconsole.c | 92 +++++++++++++++++++++++++++++++++++++-
>>> -----
>>> 1 file changed, 80 insertions(+), 12 deletions(-)
>>>
>>> diff --git a/hw/char/sclpconsole.c b/hw/char/sclpconsole.c
>>> index 179d12745c..12033e1e46 100644
>>> --- a/hw/char/sclpconsole.c
>>> +++ b/hw/char/sclpconsole.c
>>> @@ -33,6 +33,9 @@ typedef struct ASCIIConsoleData {
>>> /* max size for ASCII data in 4K SCCB page */
>>> #define SIZE_BUFFER_VT220 4080
>>>
>>> +#define SCLP_CONSOLE_EVENT_TYPE_DATA 0x00
>>> +#define SCLP_CONSOLE_EVENT_TYPE_RESIZE 0x08
>>> +
>>> struct SCLPConsole {
>>> SCLPEvent event;
>>> CharFrontend chr;
>>> @@ -42,6 +45,8 @@ struct SCLPConsole {
>>> uint32_t iov_data_len; /* length of byte stream in
>>> buffer */
>>> uint32_t iov_sclp_rest; /* length of byte stream not read via
>>> SCLP */
>>> bool notify; /* qemu_notify_event() req'd if
>>> true */
>>> + bool resize;
>>> + bool resize_init;
>>> };
>>> typedef struct SCLPConsole SCLPConsole;
>>>
>>> @@ -49,6 +54,12 @@ typedef struct SCLPConsole SCLPConsole;
>>> DECLARE_INSTANCE_CHECKER(SCLPConsole, SCLP_CONSOLE,
>>> TYPE_SCLP_CONSOLE)
>>>
>>> +typedef struct SCLPConsoleResizeData {
>>> + uint8_t type;
>>> + uint16_t rows;
>>> + uint16_t cols;
>>> +} QEMU_PACKED SCLPConsoleResizeData;
>>> +
>>> /* character layer call-back functions */
>>>
>>> /* Return number of bytes that fit into iov buffer */
>>> @@ -81,6 +92,29 @@ static void chr_read(void *opaque, const uint8_t
>>> *buf, int size)
>>> sclp_service_interrupt(0);
>>> }
>>>
>>> +static void chr_event(void *opaque, QEMUChrEvent event)
>>> +{
>>> + SCLPConsole *scon = opaque;
>>> +
>>> + assert(scon);
>>> +
>>> + switch (event) {
>>> + case CHR_EVENT_RESIZE:
>>> + case CHR_EVENT_MUX_IN:
>>> + scon->resize = true;
>>> + scon->resize_init = false;
>>> + scon->event.event_pending = true;
>>> + sclp_service_interrupt(0);
>>> + break;
>>> + case CHR_EVENT_BREAK:
>>> + case CHR_EVENT_OPENED:
>>> + case CHR_EVENT_MUX_OUT:
>>> + case CHR_EVENT_CLOSED:
>>> + /* ignore */
>>> + break;
>>> + }
>>> +}
>>> +
>>> /* functions to be called by event facility */
>>>
>>> static bool can_handle_event(uint8_t type)
>>> @@ -104,10 +138,37 @@ static sccb_mask_t receive_mask(void)
>>> static void get_console_data(SCLPEvent *event, uint8_t *buf,
>>> size_t *size,
>>> int avail)
>>> {
>>> + SCLPConsoleResizeData resize_data;
>>> SCLPConsole *cons = SCLP_CONSOLE(event);
>>> + uint16_t rows, cols;
>>> +
>>> + if (cons->resize) {
>>> + if (avail < sizeof(resize_data)) {
>>> + *size = 0;
>>> + return;
>>> + }
>>>
>>> - /* first byte is hex 0 saying an ascii string follows */
>>> - *buf++ = '\0';
>>> + qemu_chr_fe_get_winsize(&cons->chr, &cols, &rows);
>>> +
>>> + if (cons->resize_init && cols == 0 && rows == 0) {
>>> + *size = 0;
>>> + } else {
>>> + resize_data.type = SCLP_CONSOLE_EVENT_TYPE_RESIZE;
>>> + resize_data.rows = cpu_to_be16(rows);
>>> + resize_data.cols = cpu_to_be16(cols);
>>> +
>>> + memcpy(buf, &resize_data, sizeof(resize_data));
>>> + *size = sizeof(resize_data);
>>> + }
>>> +
>>> + cons->resize = false;
>>> + cons->resize_init = false;
>>> + event->event_pending = cons->iov_sclp_rest != 0;
>>> +
>>> + return;
>>> + }
>>> +
>>> + *buf++ = SCLP_CONSOLE_EVENT_TYPE_DATA;
>>> avail--;
>>> /* if all data fit into provided SCLP buffer */
>>> if (avail >= cons->iov_sclp_rest) {
>>> @@ -150,6 +211,9 @@ static int read_event_data(SCLPEvent *event,
>>> EventBufferHeader *evt_buf_hdr,
>>> to = (uint8_t *)&acd->data;
>>> avail = *slen - sizeof(ASCIIConsoleData);
>>> get_console_data(event, to, &src_len, avail);
>>> + if (src_len == 0) {
>>> + return 0;
>>> + }
>>> acd->ebh.length = cpu_to_be16(sizeof(ASCIIConsoleData) +
>>> src_len);
>>> acd->ebh.type = SCLP_EVENT_ASCII_CONSOLE_DATA;
>>> @@ -233,22 +297,26 @@ static int console_init(SCLPEvent *event)
>>> }
>>> console_available = true;
>>> qemu_chr_fe_set_handlers(&scon->chr, chr_can_read,
>>> - chr_read, NULL, NULL, scon, NULL,
>>> true);
>>> + chr_read, chr_event, NULL, scon,
>>> NULL, true);
>>>
>>> return 0;
>>> }
>>>
>>> static void console_reset(DeviceState *dev)
>>> {
>>> - SCLPEvent *event = SCLP_EVENT(dev);
>>> - SCLPConsole *scon = SCLP_CONSOLE(event);
>>> -
>>> - event->event_pending = false;
>>> - scon->iov_sclp = 0;
>>> - scon->iov_bs = 0;
>>> - scon->iov_data_len = 0;
>>> - scon->iov_sclp_rest = 0;
>>> - scon->notify = false;
>>> + SCLPEvent *event = SCLP_EVENT(dev);
>>> + SCLPConsole *scon = SCLP_CONSOLE(event);
>>> +
>>> + scon->iov_sclp = 0;
>>> + scon->iov_bs = 0;
>>> + scon->iov_data_len = 0;
>>> + scon->iov_sclp_rest = 0;
>>> + scon->notify = false;
>>> +
>>> + /* the guest defaults its terminal size on reset, announce the
>>> real one */
>>> + scon->resize = true;
>>> + scon->resize_init = true;
>>> + event->event_pending = true;
>>> }
>>
>> This is a style fix, included in a functional patch. I suppose it is
>> probably borderline, but it might be best to put this in its own
>> patch.
>
> I thought about that, but concluded that a 6-line indentation commit
> would be too small to warrant its own patch. If you'd prefer it to be
> split I could also send it as a seperate patch.
I would prefer it in its own patch if possible as a preparatory commit
prior to this one. It keeps git blame easier to read if we have issues
later and are trying to sort out where the functional changes occurred
vs what was just whitespace cleanup.
With the whitespace changes broken out:
Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com>
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH v3 0/2] s390x/sclpconsole: implement resizing for vt220 consoles
2026-09-21 12:16 ` [PATCH] s390x/sclpconsole: implement resizing for vt220 consoles Maximilian Immanuel Brandtner
` (2 preceding siblings ...)
2026-09-28 9:08 ` [PATCH v2] " Maximilian Immanuel Brandtner
@ 2026-09-29 15:20 ` Maximilian Immanuel Brandtner
2026-09-29 15:20 ` [PATCH v3 1/2] s390x/sclpconsole: fix indentation for console_reset Maximilian Immanuel Brandtner
2026-09-29 15:20 ` [PATCH v3 2/2] s390x/sclpconsole: implement resizing for vt220 consoles Maximilian Immanuel Brandtner
3 siblings, 2 replies; 35+ messages in thread
From: Maximilian Immanuel Brandtner @ 2026-09-29 15:20 UTC (permalink / raw)
To: filip.hejsek
Cc: amit, armbru, berrange, eblake, eduardo, lvivier,
marcandre.lureau, marcel.apfelbaum, mst, noh4hss, pbonzini,
philmd, qemu-devel, wangyanan55, zhao1.liu, pasic, borntraeger,
jjherne, qemu-s390x, mjrosato, brueckner, farman, cohuck,
maximilian.immanuel.brandtner
This patch-set implements resize event handling for the vt220 console.
Add a tty code to indicate a resize frame. The body contains two big
endian 16-bit integers rows and columns.
---
Changelog:
v3:
- split console_reset indentation fix into its own patch
v2:
- Use packed struct and named event type codes for resize frames
- Trigger initial resize event in console_reset() instead of
console_init(), skip when chardev reports no size
- Reset event_pending after resize event
Requires the following pre-req:
[PATCH v7 00/12] virtio-console: notify about the terminal size
(https://lore.kernel.org/qemu-devel/20260609-console-resize-v7-0-0c550fdcec15@gmail.com/)
Testing:
- Tested on QEMU: commit 38879a667f with the following patches applied:
[PATCH v7 00/12] virtio-console: notify about the terminal size
- Tested on linux-next (commit c1f49dea2b8f) with the following patches
applied:
[PATCH 0/2] s390/sclp: Resize for sclp-vt220 console
Maximilian Immanuel Brandtner (2):
s390x/sclpconsole: fix indentation for console_reset
s390x/sclpconsole: implement resizing for vt220 consoles
hw/char/sclpconsole.c | 92 +++++++++++++++++++++++++++++++++++++------
1 file changed, 80 insertions(+), 12 deletions(-)
--
2.54.0
^ permalink raw reply [flat|nested] 35+ messages in thread* [PATCH v3 1/2] s390x/sclpconsole: fix indentation for console_reset
2026-09-29 15:20 ` [PATCH v3 0/2] " Maximilian Immanuel Brandtner
@ 2026-09-29 15:20 ` Maximilian Immanuel Brandtner
2026-09-29 15:46 ` Matthew Rosato
2026-09-29 15:20 ` [PATCH v3 2/2] s390x/sclpconsole: implement resizing for vt220 consoles Maximilian Immanuel Brandtner
1 sibling, 1 reply; 35+ messages in thread
From: Maximilian Immanuel Brandtner @ 2026-09-29 15:20 UTC (permalink / raw)
To: filip.hejsek
Cc: amit, armbru, berrange, eblake, eduardo, lvivier,
marcandre.lureau, marcel.apfelbaum, mst, noh4hss, pbonzini,
philmd, qemu-devel, wangyanan55, zhao1.liu, pasic, borntraeger,
jjherne, qemu-s390x, mjrosato, brueckner, farman, cohuck,
maximilian.immanuel.brandtner
Adjust indentation to match the rest of the file. No functional change
intended.
Signed-off-by: Maximilian Immanuel Brandtner <maxbr@linux.ibm.com>
---
hw/char/sclpconsole.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/hw/char/sclpconsole.c b/hw/char/sclpconsole.c
index 179d12745c..1ad39084d3 100644
--- a/hw/char/sclpconsole.c
+++ b/hw/char/sclpconsole.c
@@ -240,15 +240,15 @@ static int console_init(SCLPEvent *event)
static void console_reset(DeviceState *dev)
{
- SCLPEvent *event = SCLP_EVENT(dev);
- SCLPConsole *scon = SCLP_CONSOLE(event);
-
- event->event_pending = false;
- scon->iov_sclp = 0;
- scon->iov_bs = 0;
- scon->iov_data_len = 0;
- scon->iov_sclp_rest = 0;
- scon->notify = false;
+ SCLPEvent *event = SCLP_EVENT(dev);
+ SCLPConsole *scon = SCLP_CONSOLE(event);
+
+ event->event_pending = false;
+ scon->iov_sclp = 0;
+ scon->iov_bs = 0;
+ scon->iov_data_len = 0;
+ scon->iov_sclp_rest = 0;
+ scon->notify = false;
}
static const Property console_properties[] = {
--
2.54.0
^ permalink raw reply related [flat|nested] 35+ messages in thread* Re: [PATCH v3 1/2] s390x/sclpconsole: fix indentation for console_reset
2026-09-29 15:20 ` [PATCH v3 1/2] s390x/sclpconsole: fix indentation for console_reset Maximilian Immanuel Brandtner
@ 2026-09-29 15:46 ` Matthew Rosato
2026-09-29 16:03 ` Eric Farman
0 siblings, 1 reply; 35+ messages in thread
From: Matthew Rosato @ 2026-09-29 15:46 UTC (permalink / raw)
To: Maximilian Immanuel Brandtner, filip.hejsek, farman
Cc: amit, armbru, berrange, eblake, eduardo, lvivier,
marcandre.lureau, marcel.apfelbaum, mst, noh4hss, pbonzini,
philmd, qemu-devel, wangyanan55, zhao1.liu, pasic, borntraeger,
jjherne, qemu-s390x, brueckner, cohuck,
maximilian.immanuel.brandtner
On 9/29/26 11:20 AM, Maximilian Immanuel Brandtner wrote:
> Adjust indentation to match the rest of the file. No functional change
> intended.
>
> Signed-off-by: Maximilian Immanuel Brandtner <maxbr@linux.ibm.com>
Thanks.
Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com>
@Eric this whitespace fixup applies cleanly to master and could get
applied separately if you care to -- or it can remain bundled with the
resize patch (patch 2 of this series) until we sort out the fate of the
pre-req virtio-console series.
Thanks,
Matt
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH v3 1/2] s390x/sclpconsole: fix indentation for console_reset
2026-09-29 15:46 ` Matthew Rosato
@ 2026-09-29 16:03 ` Eric Farman
0 siblings, 0 replies; 35+ messages in thread
From: Eric Farman @ 2026-09-29 16:03 UTC (permalink / raw)
To: Matthew Rosato, Maximilian Immanuel Brandtner, filip.hejsek
Cc: amit, armbru, berrange, eblake, eduardo, lvivier,
marcandre.lureau, marcel.apfelbaum, mst, noh4hss, pbonzini,
philmd, qemu-devel, wangyanan55, zhao1.liu, pasic, borntraeger,
jjherne, qemu-s390x, brueckner, cohuck,
maximilian.immanuel.brandtner
On 9/29/26 11:46 AM, Matthew Rosato wrote:
> On 9/29/26 11:20 AM, Maximilian Immanuel Brandtner wrote:
>> Adjust indentation to match the rest of the file. No functional change
>> intended.
>>
>> Signed-off-by: Maximilian Immanuel Brandtner <maxbr@linux.ibm.com>
>
> Thanks.
>
> Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com>
>
> @Eric this whitespace fixup applies cleanly to master and could get
> applied separately if you care to -- or it can remain bundled with the
> resize patch (patch 2 of this series) until we sort out the fate of the
> pre-req virtio-console series.
Thanks Matt (and Max!).
I'll pick this up for the next PR, so we're not dragging it along.
Then it's just the pre-req and functional piece in the future.
>
> Thanks,
> Matt
>
>
>
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH v3 2/2] s390x/sclpconsole: implement resizing for vt220 consoles
2026-09-29 15:20 ` [PATCH v3 0/2] " Maximilian Immanuel Brandtner
2026-09-29 15:20 ` [PATCH v3 1/2] s390x/sclpconsole: fix indentation for console_reset Maximilian Immanuel Brandtner
@ 2026-09-29 15:20 ` Maximilian Immanuel Brandtner
1 sibling, 0 replies; 35+ messages in thread
From: Maximilian Immanuel Brandtner @ 2026-09-29 15:20 UTC (permalink / raw)
To: filip.hejsek
Cc: amit, armbru, berrange, eblake, eduardo, lvivier,
marcandre.lureau, marcel.apfelbaum, mst, noh4hss, pbonzini,
philmd, qemu-devel, wangyanan55, zhao1.liu, pasic, borntraeger,
jjherne, qemu-s390x, mjrosato, brueckner, farman, cohuck,
maximilian.immanuel.brandtner
Add a tty code to indicate a resize frame. The body contains two big
endian 16-bit integers rows and columns.
After reset, the guest must be informed of the terminal size again. A
chardev that doesn't report its size yields 0x0, which shouldn't replace
the guest's default.
Signed-off-by: Maximilian Immanuel Brandtner <maxbr@linux.ibm.com>
Reviewed-by: Jason J. Herne <jjherne@linux.ibm.com>
Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com>
---
Changelog:
v3:
- split console_reset indentation fix into its own patch
v2:
- Use packed struct and named event type codes for resize frames
- Trigger initial resize event in console_reset() instead of
console_init(), skip when chardev reports no size
- Reset event_pending after resize event
Requires the following pre-req:
[PATCH v7 00/12] virtio-console: notify about the terminal size
(https://lore.kernel.org/qemu-devel/20260609-console-resize-v7-0-0c550fdcec15@gmail.com/)
Testing:
- Tested on QEMU: commit 38879a667f with the following patches applied:
[PATCH v7 00/12] virtio-console: notify about the terminal size
- Tested on linux-next (commit c1f49dea2b8f) with the following patches
applied:
[PATCH 0/2] s390/sclp: Resize for sclp-vt220 console
---
hw/char/sclpconsole.c | 76 ++++++++++++++++++++++++++++++++++++++++---
1 file changed, 72 insertions(+), 4 deletions(-)
diff --git a/hw/char/sclpconsole.c b/hw/char/sclpconsole.c
index 1ad39084d3..12033e1e46 100644
--- a/hw/char/sclpconsole.c
+++ b/hw/char/sclpconsole.c
@@ -33,6 +33,9 @@ typedef struct ASCIIConsoleData {
/* max size for ASCII data in 4K SCCB page */
#define SIZE_BUFFER_VT220 4080
+#define SCLP_CONSOLE_EVENT_TYPE_DATA 0x00
+#define SCLP_CONSOLE_EVENT_TYPE_RESIZE 0x08
+
struct SCLPConsole {
SCLPEvent event;
CharFrontend chr;
@@ -42,6 +45,8 @@ struct SCLPConsole {
uint32_t iov_data_len; /* length of byte stream in buffer */
uint32_t iov_sclp_rest; /* length of byte stream not read via SCLP */
bool notify; /* qemu_notify_event() req'd if true */
+ bool resize;
+ bool resize_init;
};
typedef struct SCLPConsole SCLPConsole;
@@ -49,6 +54,12 @@ typedef struct SCLPConsole SCLPConsole;
DECLARE_INSTANCE_CHECKER(SCLPConsole, SCLP_CONSOLE,
TYPE_SCLP_CONSOLE)
+typedef struct SCLPConsoleResizeData {
+ uint8_t type;
+ uint16_t rows;
+ uint16_t cols;
+} QEMU_PACKED SCLPConsoleResizeData;
+
/* character layer call-back functions */
/* Return number of bytes that fit into iov buffer */
@@ -81,6 +92,29 @@ static void chr_read(void *opaque, const uint8_t *buf, int size)
sclp_service_interrupt(0);
}
+static void chr_event(void *opaque, QEMUChrEvent event)
+{
+ SCLPConsole *scon = opaque;
+
+ assert(scon);
+
+ switch (event) {
+ case CHR_EVENT_RESIZE:
+ case CHR_EVENT_MUX_IN:
+ scon->resize = true;
+ scon->resize_init = false;
+ scon->event.event_pending = true;
+ sclp_service_interrupt(0);
+ break;
+ case CHR_EVENT_BREAK:
+ case CHR_EVENT_OPENED:
+ case CHR_EVENT_MUX_OUT:
+ case CHR_EVENT_CLOSED:
+ /* ignore */
+ break;
+ }
+}
+
/* functions to be called by event facility */
static bool can_handle_event(uint8_t type)
@@ -104,10 +138,37 @@ static sccb_mask_t receive_mask(void)
static void get_console_data(SCLPEvent *event, uint8_t *buf, size_t *size,
int avail)
{
+ SCLPConsoleResizeData resize_data;
SCLPConsole *cons = SCLP_CONSOLE(event);
+ uint16_t rows, cols;
- /* first byte is hex 0 saying an ascii string follows */
- *buf++ = '\0';
+ if (cons->resize) {
+ if (avail < sizeof(resize_data)) {
+ *size = 0;
+ return;
+ }
+
+ qemu_chr_fe_get_winsize(&cons->chr, &cols, &rows);
+
+ if (cons->resize_init && cols == 0 && rows == 0) {
+ *size = 0;
+ } else {
+ resize_data.type = SCLP_CONSOLE_EVENT_TYPE_RESIZE;
+ resize_data.rows = cpu_to_be16(rows);
+ resize_data.cols = cpu_to_be16(cols);
+
+ memcpy(buf, &resize_data, sizeof(resize_data));
+ *size = sizeof(resize_data);
+ }
+
+ cons->resize = false;
+ cons->resize_init = false;
+ event->event_pending = cons->iov_sclp_rest != 0;
+
+ return;
+ }
+
+ *buf++ = SCLP_CONSOLE_EVENT_TYPE_DATA;
avail--;
/* if all data fit into provided SCLP buffer */
if (avail >= cons->iov_sclp_rest) {
@@ -150,6 +211,9 @@ static int read_event_data(SCLPEvent *event, EventBufferHeader *evt_buf_hdr,
to = (uint8_t *)&acd->data;
avail = *slen - sizeof(ASCIIConsoleData);
get_console_data(event, to, &src_len, avail);
+ if (src_len == 0) {
+ return 0;
+ }
acd->ebh.length = cpu_to_be16(sizeof(ASCIIConsoleData) + src_len);
acd->ebh.type = SCLP_EVENT_ASCII_CONSOLE_DATA;
@@ -233,7 +297,7 @@ static int console_init(SCLPEvent *event)
}
console_available = true;
qemu_chr_fe_set_handlers(&scon->chr, chr_can_read,
- chr_read, NULL, NULL, scon, NULL, true);
+ chr_read, chr_event, NULL, scon, NULL, true);
return 0;
}
@@ -243,12 +307,16 @@ static void console_reset(DeviceState *dev)
SCLPEvent *event = SCLP_EVENT(dev);
SCLPConsole *scon = SCLP_CONSOLE(event);
- event->event_pending = false;
scon->iov_sclp = 0;
scon->iov_bs = 0;
scon->iov_data_len = 0;
scon->iov_sclp_rest = 0;
scon->notify = false;
+
+ /* the guest defaults its terminal size on reset, announce the real one */
+ scon->resize = true;
+ scon->resize_init = true;
+ event->event_pending = true;
}
static const Property console_properties[] = {
--
2.54.0
^ permalink raw reply related [flat|nested] 35+ messages in thread
* Re: [PATCH v7 00/12] virtio-console: notify about the terminal size
2026-06-09 19:16 [PATCH v7 00/12] virtio-console: notify about the terminal size Filip Hejsek
` (12 preceding siblings ...)
2026-09-21 12:16 ` [PATCH] s390x/sclpconsole: implement resizing for vt220 consoles Maximilian Immanuel Brandtner
@ 2026-09-28 9:30 ` Maximilian Immanuel Brandtner
2026-09-28 9:50 ` Michael S. Tsirkin
13 siblings, 1 reply; 35+ messages in thread
From: Maximilian Immanuel Brandtner @ 2026-09-28 9:30 UTC (permalink / raw)
To: Filip Hejsek, qemu-devel
Cc: Marc-André Lureau, Paolo Bonzini, Michael S. Tsirkin,
Laurent Vivier, Amit Shah, Markus Armbruster, Eric Blake,
Eduardo Habkost, Marcel Apfelbaum, Yanan Wang, Zhao Liu,
Daniel P. Berrangé, Philippe Mathieu-Daudé,
Szymon Lukasz
I would really appreciate it, if this patch-set could be merged. I know
that things can get really busy, but it seems to me that there aren't
any blockers that should prevent this patch-set from being merged
(apart from some minor refactors), even as is. It would be a real shame
if all this work were put into this feature, just for it to rot on the
mailing-list.
Kind regards,
Max Brandtner
^ permalink raw reply [flat|nested] 35+ messages in thread* Re: [PATCH v7 00/12] virtio-console: notify about the terminal size
2026-09-28 9:30 ` [PATCH v7 00/12] virtio-console: notify about the terminal size Maximilian Immanuel Brandtner
@ 2026-09-28 9:50 ` Michael S. Tsirkin
2026-09-28 21:21 ` Matthew Rosato
0 siblings, 1 reply; 35+ messages in thread
From: Michael S. Tsirkin @ 2026-09-28 9:50 UTC (permalink / raw)
To: Maximilian Immanuel Brandtner
Cc: Filip Hejsek, qemu-devel, Marc-André Lureau, Paolo Bonzini,
Laurent Vivier, Amit Shah, Markus Armbruster, Eric Blake,
Eduardo Habkost, Marcel Apfelbaum, Yanan Wang, Zhao Liu,
Daniel P. Berrangé, Philippe Mathieu-Daudé,
Szymon Lukasz
On Mon, Sep 28, 2026 at 11:30:03AM +0200, Maximilian Immanuel Brandtner wrote:
> I would really appreciate it, if this patch-set could be merged. I know
> that things can get really busy, but it seems to me that there aren't
> any blockers that should prevent this patch-set from being merged
> (apart from some minor refactors), even as is.
Why not address the minor comments you got?
> It would be a real shame
> if all this work were put into this feature, just for it to rot on the
> mailing-list.
>
> Kind regards,
> Max Brandtner
Reviewer's time is not less valuable.
--
MST
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH v7 00/12] virtio-console: notify about the terminal size
2026-09-28 9:50 ` Michael S. Tsirkin
@ 2026-09-28 21:21 ` Matthew Rosato
2026-09-29 8:33 ` Daniel P. Berrangé
2026-09-29 9:55 ` Michael S. Tsirkin
0 siblings, 2 replies; 35+ messages in thread
From: Matthew Rosato @ 2026-09-28 21:21 UTC (permalink / raw)
To: Michael S. Tsirkin, Maximilian Immanuel Brandtner, Filip Hejsek,
Eric Farman, Cornelia Huck
Cc: qemu-devel, Marc-André Lureau, Paolo Bonzini, Laurent Vivier,
Amit Shah, Markus Armbruster, Eric Blake, Eduardo Habkost,
Marcel Apfelbaum, Yanan Wang, Zhao Liu, Daniel P. Berrangé,
Philippe Mathieu-Daudé, Szymon Lukasz
On 9/28/26 5:50 AM, Michael S. Tsirkin wrote:
> On Mon, Sep 28, 2026 at 11:30:03AM +0200, Maximilian Immanuel Brandtner wrote:
>> I would really appreciate it, if this patch-set could be merged. I know
>> that things can get really busy, but it seems to me that there aren't
>> any blockers that should prevent this patch-set from being merged
>> (apart from some minor refactors), even as is.
>
> Why not address the minor comments you got?
>
Just to clarify, Max did not write the subject series; he is expressing
interest in it because he wrote a patch that builds upon it for s390x
[1].
Now, I'm not asking anyone to take code that isn't ready; but I would
like to understand if this series is abandoned or if the developer is
planning to send a v8 so we (s390x maintainers) know what to do about
Max's patch.
@Filip, do you plan to respin and address the comments you received?
There isn't much, but it looks like there was at least one real bug
identified.
Thanks,
Matt
[1] https://lore.kernel.org/qemu-devel/20260928090846.2315532-1-maxbr@linux.ibm.com/
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH v7 00/12] virtio-console: notify about the terminal size
2026-09-28 21:21 ` Matthew Rosato
@ 2026-09-29 8:33 ` Daniel P. Berrangé
2026-09-29 17:55 ` Filip Hejsek
2026-09-29 9:55 ` Michael S. Tsirkin
1 sibling, 1 reply; 35+ messages in thread
From: Daniel P. Berrangé @ 2026-09-29 8:33 UTC (permalink / raw)
To: Matthew Rosato
Cc: Michael S. Tsirkin, Maximilian Immanuel Brandtner, Filip Hejsek,
Eric Farman, Cornelia Huck, qemu-devel, Marc-André Lureau,
Paolo Bonzini, Laurent Vivier, Amit Shah, Markus Armbruster,
Eric Blake, Eduardo Habkost, Marcel Apfelbaum, Yanan Wang,
Zhao Liu, Philippe Mathieu-Daudé, Szymon Lukasz
On Mon, Sep 28, 2026 at 05:21:25PM -0400, Matthew Rosato wrote:
> On 9/28/26 5:50 AM, Michael S. Tsirkin wrote:
> > On Mon, Sep 28, 2026 at 11:30:03AM +0200, Maximilian Immanuel Brandtner wrote:
> >> I would really appreciate it, if this patch-set could be merged. I know
> >> that things can get really busy, but it seems to me that there aren't
> >> any blockers that should prevent this patch-set from being merged
> >> (apart from some minor refactors), even as is.
> >
> > Why not address the minor comments you got?
> >
>
> Just to clarify, Max did not write the subject series; he is expressing
> interest in it because he wrote a patch that builds upon it for s390x
> [1].
>
> Now, I'm not asking anyone to take code that isn't ready; but I would
> like to understand if this series is abandoned or if the developer is
> planning to send a v8 so we (s390x maintainers) know what to do about
> Max's patch.
>
> @Filip, do you plan to respin and address the comments you received?
> There isn't much, but it looks like there was at least one real bug
> identified.
The series also has conflicts with Git master, so cannot be applied
as is.
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH v7 00/12] virtio-console: notify about the terminal size
2026-09-29 8:33 ` Daniel P. Berrangé
@ 2026-09-29 17:55 ` Filip Hejsek
0 siblings, 0 replies; 35+ messages in thread
From: Filip Hejsek @ 2026-09-29 17:55 UTC (permalink / raw)
To: Daniel P. Berrangé, Matthew Rosato
Cc: Michael S. Tsirkin, Maximilian Immanuel Brandtner, Eric Farman,
Cornelia Huck, qemu-devel, Marc-André Lureau, Paolo Bonzini,
Laurent Vivier, Amit Shah, Markus Armbruster, Eric Blake,
Eduardo Habkost, Marcel Apfelbaum, Yanan Wang, Zhao Liu,
Philippe Mathieu-Daudé, Szymon Lukasz
On Tue, 2026-09-29 at 09:33 +0100, Daniel P. Berrangé wrote:
> On Mon, Sep 28, 2026 at 05:21:25PM -0400, Matthew Rosato wrote:
> > On 9/28/26 5:50 AM, Michael S. Tsirkin wrote:
> > > On Mon, Sep 28, 2026 at 11:30:03AM +0200, Maximilian Immanuel Brandtner wrote:
> > > > I would really appreciate it, if this patch-set could be merged. I know
> > > > that things can get really busy, but it seems to me that there aren't
> > > > any blockers that should prevent this patch-set from being merged
> > > > (apart from some minor refactors), even as is.
> > >
> > > Why not address the minor comments you got?
> > >
> >
> > Just to clarify, Max did not write the subject series; he is expressing
> > interest in it because he wrote a patch that builds upon it for s390x
> > [1].
> >
> > Now, I'm not asking anyone to take code that isn't ready; but I would
> > like to understand if this series is abandoned or if the developer is
> > planning to send a v8 so we (s390x maintainers) know what to do about
> > Max's patch.
> >
> > @Filip, do you plan to respin and address the comments you received?
> > There isn't much, but it looks like there was at least one real bug
> > identified.
>
> The series also has conflicts with Git master, so cannot be applied
> as is.
>
> With regards,
> Daniel
Hi all,
I've sent a v8 [1], which is a rebase on master plus the uninitialized
buffer fix suggested by Marc-André Lureau.
Sorry for the delay, and thanks for the nudge, which got me to come
back to it. I do this in my free time, so progress comes in bursts, but
feel free to nag me if I don't respond for a while again.
I originally planned to include a fix for the migration issue in v8
too, but I don't have time right now for implementing the necessary
migration stream changes. I think you can merge it without the fix, as
it's only a minor issue, but I hope it can be fixed in a follow-up. If
someone wants to pick that up, help is welcome. I have a rough WIP
refactor of virtio-serial serialization to use VMState at [2], which
might be useful as a starting point if that is the chosen approach.
Matthew, Max: I hope this unblocks the s390x patch.
[1]: https://lore.kernel.org/qemu-devel/20260929-console-resize-v8-0-2ff9183f8750@gmail.com
[2]: https://gitlab.com/filip-hejsek/qemu/-/commits/b4/virtio-serial-vmstate
Best regards,
Filip
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH v7 00/12] virtio-console: notify about the terminal size
2026-09-28 21:21 ` Matthew Rosato
2026-09-29 8:33 ` Daniel P. Berrangé
@ 2026-09-29 9:55 ` Michael S. Tsirkin
1 sibling, 0 replies; 35+ messages in thread
From: Michael S. Tsirkin @ 2026-09-29 9:55 UTC (permalink / raw)
To: Matthew Rosato
Cc: Maximilian Immanuel Brandtner, Filip Hejsek, Eric Farman,
Cornelia Huck, qemu-devel, Marc-André Lureau, Paolo Bonzini,
Laurent Vivier, Amit Shah, Markus Armbruster, Eric Blake,
Eduardo Habkost, Marcel Apfelbaum, Yanan Wang, Zhao Liu,
Daniel P. Berrangé, Philippe Mathieu-Daudé,
Szymon Lukasz
On Mon, Sep 28, 2026 at 05:21:25PM -0400, Matthew Rosato wrote:
> On 9/28/26 5:50 AM, Michael S. Tsirkin wrote:
> > On Mon, Sep 28, 2026 at 11:30:03AM +0200, Maximilian Immanuel Brandtner wrote:
> >> I would really appreciate it, if this patch-set could be merged. I know
> >> that things can get really busy, but it seems to me that there aren't
> >> any blockers that should prevent this patch-set from being merged
> >> (apart from some minor refactors), even as is.
> >
> > Why not address the minor comments you got?
> >
>
> Just to clarify, Max did not write the subject series; he is expressing
> interest in it because he wrote a patch that builds upon it for s390x
> [1].
>
> Now, I'm not asking anyone to take code that isn't ready; but I would
> like to understand if this series is abandoned or if the developer is
> planning to send a v8 so we (s390x maintainers) know what to do about
> Max's patch.
>
> @Filip, do you plan to respin and address the comments you received?
> There isn't much, but it looks like there was at least one real bug
> identified.
>
> Thanks,
> Matt
>
> [1] https://lore.kernel.org/qemu-devel/20260928090846.2315532-1-maxbr@linux.ibm.com/
This is what I am saying. It's been since June. Whoever wants this,
should clean it up and repost.
--
MST
^ permalink raw reply [flat|nested] 35+ messages in thread