{"id":2224771,"url":"http://patchwork.ozlabs.org/api/1.1/patches/2224771/?format=json","web_url":"http://patchwork.ozlabs.org/project/qemu-devel/patch/20260418115230.17809-1-viking4@gmail.com/","project":{"id":14,"url":"http://patchwork.ozlabs.org/api/1.1/projects/14/?format=json","name":"QEMU Development","link_name":"qemu-devel","list_id":"qemu-devel.nongnu.org","list_email":"qemu-devel@nongnu.org","web_url":"","scm_url":"","webscm_url":""},"msgid":"<20260418115230.17809-1-viking4@gmail.com>","date":"2026-04-18T11:52:30","name":"chardev/msmouse: save and restore device state for migration and savevm","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"d4e46700c1d849747dcb109674e632b323492f81","submitter":{"id":92831,"url":"http://patchwork.ozlabs.org/api/1.1/people/92831/?format=json","name":"Trieu Huynh","email":"vikingtc4@gmail.com"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/qemu-devel/patch/20260418115230.17809-1-viking4@gmail.com/mbox/","series":[{"id":500438,"url":"http://patchwork.ozlabs.org/api/1.1/series/500438/?format=json","web_url":"http://patchwork.ozlabs.org/project/qemu-devel/list/?series=500438","date":"2026-04-18T11:52:30","name":"chardev/msmouse: save and restore device state for migration and savevm","version":1,"mbox":"http://patchwork.ozlabs.org/series/500438/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2224771/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2224771/checks/","tags":{},"headers":{"Return-Path":"<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>","X-Original-To":"incoming@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256\n header.s=20251104 header.b=n7izcMiS;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org\n (client-ip=209.51.188.17; helo=lists1p.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=patchwork.ozlabs.org)"],"Received":["from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17])\n\t(using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fyVWp51Htz1yCv\n\tfor <incoming@patchwork.ozlabs.org>; Sat, 18 Apr 2026 21:53:41 +1000 (AEST)","from localhost ([::1] helo=lists1p.gnu.org)\n\tby lists1p.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces@nongnu.org>)\n\tid 1wE4EF-0000Ef-Md; Sat, 18 Apr 2026 07:52:51 -0400","from eggs.gnu.org ([2001:470:142:3::10])\n by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <vikingtc4@gmail.com>)\n id 1wE4EA-0000EU-5P\n for qemu-devel@nongnu.org; Sat, 18 Apr 2026 07:52:46 -0400","from mail-pg1-x534.google.com ([2607:f8b0:4864:20::534])\n by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)\n (Exim 4.90_1) (envelope-from <vikingtc4@gmail.com>)\n id 1wE4E7-0004jR-SY\n for qemu-devel@nongnu.org; Sat, 18 Apr 2026 07:52:45 -0400","by mail-pg1-x534.google.com with SMTP id\n 41be03b00d2f7-c741692db4cso448141a12.1\n for <qemu-devel@nongnu.org>; Sat, 18 Apr 2026 04:52:39 -0700 (PDT)","from localhost.localdomain ([123.19.199.205])\n by smtp.gmail.com with ESMTPSA id\n 41be03b00d2f7-c797704b575sm3755530a12.29.2026.04.18.04.52.36\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Sat, 18 Apr 2026 04:52:37 -0700 (PDT)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=gmail.com; s=20251104; t=1776513158; x=1777117958; darn=nongnu.org;\n h=content-transfer-encoding:mime-version:message-id:date:subject:cc\n :to:from:from:to:cc:subject:date:message-id:reply-to;\n bh=aViH8Sa+dRrCP6ce2A729e6K8FtQacwZ96aCuGlKC5c=;\n b=n7izcMiSIA/8kBXxagtjh6SdGKvxNiKlBCTHD2yOScxq9R2LM6ZuOKwZi2Duv1kW1c\n iaxTAtBq8CJW83npRCaT+dbehB7kScNfKUC5MGnJSnlrn0d4zqDJrMr+nv/HCHU7zK4u\n o3Qi1awQpT0lKK7/jcDfpoknJ2hAZiI2MhtrgKneta5+1sfSdJ1uDh3kSXyO0qZlgruH\n ybKVEs9q9fzHFP8tMYo1QJJsVpmntOy9Dt13rVnOniC1hIu0Gzb3yKDOQzdxeg+ilu2p\n 8kO8zg9Yywdq54Pvuyorf790mMNHSp1QGlsHYy+MP9RqZ5we5lHHBMAKOzi98I1oXVa9\n LViA==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1776513158; x=1777117958;\n h=content-transfer-encoding:mime-version:message-id:date:subject:cc\n :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date\n :message-id:reply-to;\n bh=aViH8Sa+dRrCP6ce2A729e6K8FtQacwZ96aCuGlKC5c=;\n b=mncBoLxv3UsZB9tB1+auueaa0DdfVhsuih2T+yoqbQrTkgUNlXftTRH5xvn2gpAnly\n xYhZvt8S7Iis1sthF0Ryfgxn6QHrFa4+IeJFGMZE/K8mYBGGICxifUBMKhtUP9IYBVeE\n z3yq5XnNZKzNZRYgmCRl+V8zdndhmhU0Y9M9UQi5yq9Ih/6pVaXLBzBi4IREBKCDRnxk\n zyt/DwgB13qgBkAbhahJFyn6oepMYaM0dgv9w4vF6iXRN6lLW9g9O1Xj321C4u8B5fYh\n TJnXYOs7sTau3p52JvFXHuanybvAWHzDJURZLodYVAGI88WRodkdch/vlkCie85SbpSk\n XM+w==","X-Gm-Message-State":"AOJu0YzVlrADB9UqBHWXiJlG8EW2IOKFs/Ct+NUk6rAo5hVkJDd4CB53\n HfhQg3I3dJriBOojl8ddQVbA/q0okZATCtMXLWHc+R305qzV0Ev0nezl0fdE5uli","X-Gm-Gg":"AeBDietNICju4cCjj1NT2mfsau5Q0lUs7pvwWHVEPybMMj+W9SKZzDFOVTVvDfyfqCU\n Nhg216Hd9PsnuDN6OQsRAKy5NQaRfOiVQSiaQVAtj41hdZT+ucQVYs+q5Lo8S5UDAREfh/WjlNs\n BwaggFghxtBcrt1/4NbAcl0Mc4XX9yNBYLt5gibIVKtJd6IWVjJsM1LVnjQajQFKAZBGYF610ib\n dGnFyhrFaAXjLLumYGZuK6ZPoPj3fKolK+GPERGg9BwIyW/pWmhl1lXEGeSQrnzqnJhuwIU+PPU\n 8IJvuQELpLy91A7WKjKoMWskgXfhKvBaitu2w52PpI4y8rAjCH0HpsHmx5DTHARBRu5zNn2vn6N\n WqSYZwpITstKGON5svAdX9wFYtJgqWs6lM5RPcp9B9VRggKDUPIcvFn3+IOmHr0vcZRhmQhM0Yg\n +as063kS0CRfIuzzq62JBmCMQT9VArQ34sI/W6r9e6t/7ci/wwu7VtYv2PstEH1u4OxxNf","X-Received":"by 2002:a05:6a20:3946:b0:39c:212c:9088 with SMTP id\n adf61e73a8af0-3a08ca6e212mr6253151637.20.1776513158018;\n Sat, 18 Apr 2026 04:52:38 -0700 (PDT)","From":"Trieu Huynh <vikingtc4@gmail.com>","X-Google-Original-From":"Trieu Huynh <viking4@gmail.com>","To":"qemu-devel@nongnu.org","Cc":"Trieu Huynh <vikingtc4@gmail.com>,\n =?utf-8?q?Marc-Andr=C3=A9_Lureau?= <marcandre.lureau@redhat.com>,\n Paolo Bonzini <pbonzini@redhat.com>","Subject":"[PATCH] chardev/msmouse: save and restore device state for migration\n and savevm","Date":"Sat, 18 Apr 2026 18:52:30 +0700","Message-ID":"<20260418115230.17809-1-viking4@gmail.com>","X-Mailer":"git-send-email 2.43.0","MIME-Version":"1.0","Content-Transfer-Encoding":"8bit","Received-SPF":"pass client-ip=2607:f8b0:4864:20::534;\n envelope-from=vikingtc4@gmail.com; helo=mail-pg1-x534.google.com","X-Spam_score_int":"-17","X-Spam_score":"-1.8","X-Spam_bar":"-","X-Spam_report":"(-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1,\n DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1,\n FREEMAIL_ENVFROM_END_DIGIT=0.25, FREEMAIL_FROM=0.001,\n RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001,\n 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 <qemu-devel.nongnu.org>","List-Unsubscribe":"<https://lists.nongnu.org/mailman/options/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>","List-Archive":"<https://lists.nongnu.org/archive/html/qemu-devel>","List-Post":"<mailto:qemu-devel@nongnu.org>","List-Help":"<mailto:qemu-devel-request@nongnu.org?subject=help>","List-Subscribe":"<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=subscribe>","Errors-To":"qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org","Sender":"qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org"},"content":"From: Trieu Huynh <vikingtc4@gmail.com>\n\nMouseChardev holds state that must survive migration and savevm/loadvm:\n\n  tiocm   - serial line control (RTS/DTR).  When zero the mouse is\n            considered powered-off and all input events are silently\n            dropped.  Losing this field after migration leaves the\n            mouse in a dead state: the guest driver must toggle\n            RTS/DTR again to re-detect the mouse, which most drivers\n            (Linux sermouse, DOS ctmouse) only do at initialisation.\n\n  axis[]  - accumulated X/Y movement not yet encoded into a packet.\n\n  btns[]  - current button state.\n\n  btnc[]  - per-button change flags used for middle-button tracking.\n\n  outbuf  - Fifo8 of encoded mouse bytes waiting to be delivered to\n            the serial port receive FIFO.\n\nAdd a VMStateDescription covering all five fields, registering it in\nmsmouse_chr_open and unregistering it in char_msmouse_finalize.  This\nfollows the same pattern used by ui/vdagent.c\n\nResolves: https://gitlab.com/qemu-project/qemu/-/issues/1234\n\nSigned-off-by: Trieu Huynh <vikingtc4@gmail.com>\n---\nSteps to reproduce:\n\n* 1. Starting source QEMU under GDB\ngdb -q ./qemu-system-x86_64\n\n* Inside GDB:\n\n(gdb) set args -chardev msmouse,id=mouse0 \\\n  -device isa-serial,chardev=mouse0 \\\n  - <other_options>\n\n(gdb) break msmouse_input_sync\n(gdb) run\n\n* 2. Starting destination QEMU under GDB\ngdb -q ./qemu-system-x86_64\n\n* Inside GDB:\n\n(gdb) set args -chardev msmouse,id=mouse0 \\\n  -S -incoming tcp:0:4444\n  -device isa-serial,chardev=mouse0 \\\n  - <other_options>\n\n(gdb) break msmouse_chr_ioctl\n(gdb) run\n<waiting for migration>\n\n* 3. Send mouse events to source\n{\"execute\":\"qmp_capabilities\"}\n\n* Power on the mouse:\n{\"execute\":\"human-monitor-command\",\"arguments\":{\"command-line\":\"o 0x2fc 0x03\"}}\n\n* Inject a movement event with buttons:\n{\"execute\":\"input-send-event\",\"arguments\":{\"events\":[{\"type\":\"rel\",\"data\":{\"axis\":\"x\",\"value\":30}},{\"type\":\"rel\",\"data\":{\"axis\":\"y\",\"value\":-10}},{\"type\":\"btn\",\"data\":{\"button\":\"left\",\"down\":true}},{\"type\":\"btn\",\"data\":{\"button\":\"middle\",\"down\":true}}]}}\n\nThread 1 \"qemu-system-x86\" hit Breakpoint 1, msmouse_input_sync (dev=0x555557648a00)\n    at ../chardev/msmouse.c:171\n171\t    MouseChardev *mouse = MOUSE_CHARDEV(dev);\n(gdb) next\n172\t    Chardev *chr = CHARDEV(dev);\n(gdb) next\n175\t    if (!MSMOUSE_PWR(mouse->tiocm)) {\n(gdb) print mouse->tiocm\n$17 = 6\n(gdb) print mouse->axis[1]\n$18 = -10\n(gdb) print mouse->axis[0]\n$19 = 30\n(gdb) print mouse->btns[0]\n$20 = true\n(gdb)  print mouse->btns[2]\n$21 = false\n(gdb) print mouse->btnc[0]\n$22 = true\n(gdb)  print mouse->btnc[2]\n$23 = false\n(gdb) print mouse->outbuf \n$24 = {data = 0x5555578bbdf0 \"M3\\b\\001$1-5\\020\\020\\020\\021<<-/53%<<1%-5\", capacity = 64, \n  head = 1, num = 55}\n(gdb) continue\n\n* 4. Start migration until completed\n\n{\"execute\":\"migrate\",\"arguments\":{\"uri\":\"tcp:127.0.0.1:4444\"}}\n\n* 5. Verify mouse data on dest\n\n* As-is:\nThread 1 \"qemu-system-x86\" hit Breakpoint 1, msmouse_chr_ioctl (chr=0x555557648ad0, \n    cmd=1, arg=0x7ffff415ba80) at ../chardev/msmouse.c:182\n182\t{\n(gdb) next\n183\t    MouseChardev *mouse = MOUSE_CHARDEV(chr);\n(gdb) next\n184\t    int c, i, j;\n(gdb) print ((MouseChardev *)chr)->tiocm\n$1 = 0\n(gdb) print ((MouseChardev *)chr)->axis[0]\n$2 = 0\n(gdb) print ((MouseChardev *)chr)->axis[1]\n$3 = 0\n(gdb) print ((MouseChardev *)chr)->btns[0]\n$4 = false\n(gdb) print ((MouseChardev *)chr)->btns[2]\n$5 = false\n(gdb) print ((MouseChardev *)chr)->btnc[0]\n$6 = false\n(gdb) print ((MouseChardev *)chr)->btnc[2]\n$7 = false\n(gdb) print ((MouseChardev *)chr)->outbuf\n$8 = {data = 0x5555578bbf60 \"\\273xUU\\005\", capacity = 64, head = 0, num = 0}\n(gdb) \n\n* To-be:\nThread 1 \"qemu-system-x86\" hit Breakpoint 1, msmouse_chr_ioctl (chr=0x555557648ad0, \n    cmd=1, arg=0x7ffff415ba80) at ../chardev/msmouse.c:197\n197    {\n(gdb) next\n198        MouseChardev *mouse = MOUSE_CHARDEV(chr);\n(gdb) next\n199        int c, i, j;\n(gdb) print ((MouseChardev *)chr)->tiocm\n$1 = 6\n(gdb) print ((MouseChardev *)chr)->axis[0]\n$2 = 0\n(gdb) print ((MouseChardev *)chr)->axis[1]\n$3 = 0\n(gdb) print ((MouseChardev *)chr)->btns[0]\n$4 = true\n(gdb) print ((MouseChardev *)chr)->btns[2]\n$5 = false\n(gdb) print ((MouseChardev *)chr)->btnc[0]\n$6 = true\n(gdb) print ((MouseChardev *)chr)->btnc[2]\n$7 = false\n(gdb) print ((MouseChardev *)chr)->outbuf\n$8 = {data = 0x5555578bbf60 \"M3\\b\\001$1-5\\020\\020\\020\\021<<-/53%<<1%-5\", capacity = 64, \n  head = 1, num = 59}\n\n chardev/msmouse.c | 17 +++++++++++++++++\n 1 file changed, 17 insertions(+)","diff":"diff --git a/chardev/msmouse.c b/chardev/msmouse.c\nindex 365f04546e..e991135be9 100644\n--- a/chardev/msmouse.c\n+++ b/chardev/msmouse.c\n@@ -30,6 +30,7 @@\n #include \"ui/console.h\"\n #include \"ui/input.h\"\n #include \"qom/object.h\"\n+#include \"migration/vmstate.h\"\n \n #define MSMOUSE_LO6(n)  ((n) & 0x3f)\n #define MSMOUSE_HI2(n)  (((n) & 0xc0) >> 6)\n@@ -70,6 +71,20 @@ typedef struct MouseChardev MouseChardev;\n DECLARE_INSTANCE_CHECKER(MouseChardev, MOUSE_CHARDEV,\n                          TYPE_CHARDEV_MSMOUSE)\n \n+static const VMStateDescription vmstate_msmouse = {\n+    .name = \"msmouse\",\n+    .version_id = 1,\n+    .minimum_version_id = 1,\n+    .fields = (const VMStateField[]) {\n+        VMSTATE_INT32(tiocm, MouseChardev),\n+        VMSTATE_INT32_ARRAY(axis, MouseChardev, INPUT_AXIS__MAX),\n+        VMSTATE_BOOL_ARRAY(btns, MouseChardev, INPUT_BUTTON__MAX),\n+        VMSTATE_BOOL_ARRAY(btnc, MouseChardev, INPUT_BUTTON__MAX),\n+        VMSTATE_FIFO8(outbuf, MouseChardev),\n+        VMSTATE_END_OF_LIST()\n+    },\n+};\n+\n static void msmouse_chr_accept_input(Chardev *chr)\n {\n     MouseChardev *mouse = MOUSE_CHARDEV(chr);\n@@ -247,6 +262,7 @@ static void char_msmouse_finalize(Object *obj)\n {\n     MouseChardev *mouse = MOUSE_CHARDEV(obj);\n \n+    vmstate_unregister(NULL, &vmstate_msmouse, mouse);\n     if (mouse->hs) {\n         qemu_input_handler_unregister(mouse->hs);\n     }\n@@ -263,6 +279,7 @@ static bool msmouse_chr_open(Chardev *chr,\n                                             &msmouse_handler);\n     mouse->tiocm = 0;\n     fifo8_create(&mouse->outbuf, MSMOUSE_BUF_SZ);\n+    vmstate_register_any(NULL, &vmstate_msmouse, mouse);\n \n     /* Never send CHR_EVENT_OPENED */\n     return true;\n","prefixes":[]}