From nobody Mon Feb 9 12:09:58 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1768794138; cv=none; d=zohomail.com; s=zohoarc; b=jaV70fICddUJWjRb0xi5MI8afKsCGFxpJKRmnsCTW3WIcMdS3LJQBTRLUvsy5Rzh+AQRvdyyTZZwrcZ/jszv+A0u/z6z5DL05/T1XNfqyQttohW+wBJKMzp9AFPC18cEKx/YhznGVFanNtcnA1quwKlvbU0t7lV8bwPxIPlACkc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1768794138; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=tn+OZOSXDbknR2OaFoKADd3P/YORnV8fEUKXR99UvC0=; b=Pgz5hDAcMbug6yw487jxQnK0ruc183tlEcwDxeFbH6mUrGz2cUm4CDyGqpB/jT6r+954M9QbdoBBfu8y/AhGaABv4tN5Mul68R6ToHKxFwbvcK/cS/lG8c0Sgl9oLikqph5fex5rOZul30V0Cx0woKI2URthMBs2aWcnt91DzHU= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1768794138143426.52317631412507; Sun, 18 Jan 2026 19:42:18 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vhfwv-00074m-C4; Sun, 18 Jan 2026 22:29:07 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vhfwi-00073p-61 for qemu-devel@nongnu.org; Sun, 18 Jan 2026 22:28:53 -0500 Received: from mail-ed1-x536.google.com ([2a00:1450:4864:20::536]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1vhfwd-0004Bd-WB for qemu-devel@nongnu.org; Sun, 18 Jan 2026 22:28:51 -0500 Received: by mail-ed1-x536.google.com with SMTP id 4fb4d7f45d1cf-6505cac9879so6334046a12.1 for ; Sun, 18 Jan 2026 19:28:47 -0800 (PST) Received: from localhost (mem-185.47.220.165.jmnet.cz. [185.47.220.165]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-b87d1e6dd64sm236516866b.32.2026.01.18.19.28.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 18 Jan 2026 19:28:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1768793326; x=1769398126; darn=nongnu.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=tn+OZOSXDbknR2OaFoKADd3P/YORnV8fEUKXR99UvC0=; b=PTmxipqdimREFbsNVzpAus7UxpaBrdS63t4mkOFQOomOxh6F2F+dJFZf7uxByfZu0s 7l/t2CXnX4K0N9wuBtFqovMPw/FakuUwcVnc0XnYFyhZCiqKGAb/CtTL9SdKpkg7QRY7 C9ajMUulon6/eamRXS5nTJLumldm7xOnjTYhF94pBVjSBA87VSf9Qtfosndw1RKtxB72 NWTmd1YTzNemNOKTCaEh3urRxp+5E5brpWLMTiiegXvJ9zYEOK6CRaIFMV1/7gC0f5cF +KSmBE5hJpnnUg2ysMiqTiR2+F7G8ZOaj3gAd8KHeb6Yd1SI0oTswWGi3ALSU1aA7wAM QclA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768793326; x=1769398126; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=tn+OZOSXDbknR2OaFoKADd3P/YORnV8fEUKXR99UvC0=; b=Hfupgkxl4pzmX4JxgjhRVuumTmlfW32Vr5FkRs1SJWYV+UfEmJYq5jmNa1UoGgpwMy 7DpjdAnNRT5xwd4YPRIiVGHasGMjfHLiesPgLR50PVFY6ZjZF8xEw6bYaXUqjwRhekxi 1f0oXShXNo4c8kJxVp/pG1CzTuxvJ9xwsevCw7rRGPnuWd/ykjUVV+2EAdZdfXxs6mny jB/Ht7Vv6dsxjFTZDnAyYsB12s1hzaywcHT0QRnVPBwonWK37Os2Zi6RiTbQr4lLcsGP CjNwJ1qU+vKgNotVT2uNravl59KCriQujbjDbXEmK3liarsZ6Ghi/Ly8kkb0NUsiDfcH NIJA== X-Gm-Message-State: AOJu0YzADDlptx/E6JhobZpbdBFqxM1jTKnXV04CDPCr5wpWg7+TWnwB rQfesAIhFHpSgTkYfXm+fJSlaZAovZOhg2ga4Xv5CQQyRl/lVvkxWyBK X-Gm-Gg: AY/fxX5F12YE3HC89UQj26zoRtiMWkfNySATX/+Y+8a0zfKJcqkE6Fe2sjBjNZ/nc+B gZmlyIXfrAqvlp2dt+qEDweAvOnyn0OLtid84ppYDQW6mCjnquLcKMPstt5aZ7K22rnbOl6ZrFq +OtSsMvYczOQnvK4jS68vQBmCKsgc/U5G7C8TbBH5m+9A1UBDavCShZ4aP6PPVBeAFKeeyMei4m 0Vb6DAsWepPL2P0DjIYG8FSyfJgYpmhLa3GWmYx08Mzh7/LuzOrBhsjIFc8zS7YH2pOzoUpz5Uf sMXjSKsLODsp3iEPd7ojcSe0RAV9w1gQsp6pa5Sy2oJe2cT6x9qj+Ds13Q6McUgnHi8tPIwFirM VYYPiQzzGOOTAA44YRq1RVJ/aMfRC77Drtz//82nFFeWpgJ68rxCOwrUJyAYN8aGHZql5GrNogy Ybybg6kTdh4i5v/VCXxjJhl2/qvAfUqZ57oJZiGeiB X-Received: by 2002:a17:907:1ca5:b0:b80:3fff:32ea with SMTP id a640c23a62f3a-b8792fede57mr931808966b.57.1768793325817; Sun, 18 Jan 2026 19:28:45 -0800 (PST) From: Filip Hejsek Date: Mon, 19 Jan 2026 04:27:51 +0100 Subject: [PATCH v6 08/12] virtio-serial-bus: add terminal resize messages MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260119-console-resize-v6-8-33a7b0330a7a@gmail.com> References: <20260119-console-resize-v6-0-33a7b0330a7a@gmail.com> In-Reply-To: <20260119-console-resize-v6-0-33a7b0330a7a@gmail.com> To: qemu-devel@nongnu.org Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Paolo Bonzini , "Michael S. Tsirkin" , Laurent Vivier , Amit Shah , Markus Armbruster , Eric Blake , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , Yanan Wang , Zhao Liu , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , Maximilian Immanuel Brandtner , Szymon Lukasz X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1768793314; l=7237; i=filip.hejsek@gmail.com; s=20250912; h=from:subject:message-id; bh=iA4bzXkkPsS0eGd8S0fKQQSaARDJLTGpF3c43PCxCTg=; b=wsO/GtjNynmS9ZF6de16+ezf6aZHn7ouWvpYw6UmCffe7e3rCaVYCBjFKnWXavrdm02s7/jQk N390GJZZuiFDaVMtCg0zMGiTQ4WjpSDmN2oTnXWKbIbzhLYhF83MoKR X-Developer-Key: i=filip.hejsek@gmail.com; a=ed25519; pk=nakB8gEK3oi+Q/5dBTMCy/LgZL47NP60z1jeDR6O/WU= Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2a00:1450:4864:20::536; envelope-from=filip.hejsek@gmail.com; helo=mail-ed1-x536.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1768794140339158500 Implement the part of the virtio spec that allows to notify the virtio driver about terminal resizes. The virtio spec contains two methods to achieve that: 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. Note that 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 5326ab737a47278dbd16ed3ee7380b26c7= 056ddd. As a result, when using a Linux kernel older than 6.15, the number of rows and columns will be swapped. Based on a patch originally written by Szymon Lukasz , but partially rewritten to fix various corner cases. Signed-off-by: Szymon Lukasz Signed-off-by: Filip Hejsek --- hw/char/trace-events | 1 + hw/char/virtio-serial-bus.c | 76 +++++++++++++++++++++++++++++++++++= ++-- hw/core/machine.c | 4 ++- include/hw/virtio/virtio-serial.h | 5 +++ 4 files changed, 83 insertions(+), 3 deletions(-) diff --git a/hw/char/trace-events b/hw/char/trace-events index 9e74be2c14..2416d4d04e 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 =20 # 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, th= rottle %d" virtio_serial_handle_control_message(uint16_t event, uint16_t value) "even= t %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 5ec5f5313b..6348eef3a2 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, u= int32_t port_id, return send_control_msg(vser, &cpkt, sizeof(cpkt)); } =20 +/* + * 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 =3D port->vser; + VirtIODevice *vdev =3D 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->ro= ws); + + 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 =3D port->vser; + VirtIODevice *vdev =3D VIRTIO_DEVICE(vser); + + if (port->cols =3D=3D cols && port->rows =3D=3D rows) { + return; + } + + port->cols =3D cols; + port->rows =3D rows; + + if (port->id =3D=3D 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); } =20 if (port->name) { @@ -568,11 +631,18 @@ static uint64_t get_features(VirtIODevice *vdev, uint= 64_t features, static void get_config(VirtIODevice *vdev, uint8_t *config_data) { VirtIOSerial *vser =3D VIRTIO_SERIAL(vdev); + VirtIOSerialPort *port; struct virtio_console_config *config =3D (struct virtio_console_config *)config_data; =20 - config->cols =3D 0; - config->rows =3D 0; + port =3D find_port_by_id(vser, 0); + if (port) { + config->cols =3D virtio_tswap16(vdev, port->cols); + config->rows =3D virtio_tswap16(vdev, port->rows); + } else { + config->cols =3D 0; + config->rows =3D 0; + } config->max_nr_ports =3D virtio_tswap32(vdev, vser->serial.max_virtserial_port= s); } @@ -1158,6 +1228,8 @@ static const Property virtio_serial_properties[] =3D { 31), DEFINE_PROP_BIT64("emergency-write", VirtIOSerial, host_features, VIRTIO_CONSOLE_F_EMERG_WRITE, true), + DEFINE_PROP_BIT64("console-size", VirtIOSerial, host_features, + VIRTIO_CONSOLE_F_SIZE, true), }; =20 static void virtio_serial_class_init(ObjectClass *klass, const void *data) diff --git a/hw/core/machine.c b/hw/core/machine.c index 6411e68856..50554b8900 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -38,7 +38,9 @@ #include "hw/acpi/generic_event_device.h" #include "qemu/audio.h" =20 -GlobalProperty hw_compat_10_2[] =3D {}; +GlobalProperty hw_compat_10_2[] =3D { + { "virtio-serial-device", "console-size", "off" }, +}; const size_t hw_compat_10_2_len =3D G_N_ELEMENTS(hw_compat_10_2); =20 GlobalProperty hw_compat_10_1[] =3D { diff --git a/include/hw/virtio/virtio-serial.h b/include/hw/virtio/virtio-s= erial.h index 60641860bf..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; }; =20 /* The virtio-serial bus on top of which the ports will ride as devices */ @@ -222,5 +225,7 @@ size_t virtio_serial_guest_ready(VirtIOSerialPort *port= ); */ void virtio_serial_throttle_port(VirtIOSerialPort *port, bool throttle); =20 +void virtio_serial_resize_console(VirtIOSerialPort *port, + uint16_t cols, uint16_t rows); =20 #endif --=20 2.52.0