From nobody Sat Jul 4 21:12:58 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; 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=fail(p=reject dis=none) header.from=rsg.ci.i.u-tokyo.ac.jp Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1783056203069252.9606117616937; Thu, 2 Jul 2026 22:23:23 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wfWMW-0005TB-Og; Fri, 03 Jul 2026 01:22:53 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wfWMU-0005So-VB; Fri, 03 Jul 2026 01:22:50 -0400 Received: from www3579.sakura.ne.jp ([49.212.243.89]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wfWMS-0005s0-2Q; Fri, 03 Jul 2026 01:22:50 -0400 Received: from h183.csg.ci.i.u-tokyo.ac.jp (h183.csg.ci.i.u-tokyo.ac.jp [133.11.54.183]) (authenticated bits=0) by www3579.sakura.ne.jp (8.16.1/8.16.1) with ESMTPSA id 6635LT8O018373 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Fri, 3 Jul 2026 14:21:42 +0900 (JST) (envelope-from odaki@rsg.ci.i.u-tokyo.ac.jp) DKIM-Signature: a=rsa-sha256; bh=SuGsYbGlKlc6b1DT5vt3OpkvoEjMGNIgH0RWbpVGexY=; c=relaxed/relaxed; d=rsg.ci.i.u-tokyo.ac.jp; h=From:Message-Id:To:Subject:Date; s=rs20250326; t=1783056103; v=1; b=S20lgzeIrAK4H5mymbVMmwynLidXIEr8fLV0kex6TpzJb5R7oEizYlM/qZE1O+0g uFjFcXYzOE14hzhJFWsTFYQdrmv0K6in73PtRufsQ8r/GM5NKIH1s+recQO8juh2 OaLEHIJBnUFgD+64n49UVucLVF9m+evAEg5zzgel4m7DkbrP1GMHAxna2ees1IG7 5bZ5m1XfKnCX5ZK+nZtBXgbqRIx9vn+a6hMl6pJd4EDLfwO1HrN2/08um2ZcPz8+ LyZlj6HTfbSxhxolTgpyMFL4zAzoXqOeexN24QPRCs+XynFBalZt3684DJiym37y lwANSpgPCJHO5Vz6eFRBtg== From: Akihiko Odaki Date: Fri, 03 Jul 2026 14:19:17 +0900 Subject: [PATCH v2 1/7] hw/nvram/fw_cfg: Remove acpi-mr-restore MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260703-ram-v2-1-7f07fc06fba9@rsg.ci.i.u-tokyo.ac.jp> References: <20260703-ram-v2-0-7f07fc06fba9@rsg.ci.i.u-tokyo.ac.jp> In-Reply-To: <20260703-ram-v2-0-7f07fc06fba9@rsg.ci.i.u-tokyo.ac.jp> To: qemu-devel@nongnu.org Cc: Kevin Wolf , Hanna Reitz , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , Zhao Liu , Stefano Stabellini , Anthony PERARD , "Edgar E. Iglesias" , Peter Xu , Fabiano Rosas , Paolo Bonzini , Reinoud Zandijk , Marcelo Tosatti , Alex Williamson , =?utf-8?q?C=C3=A9dric_Le_Goater?= , qemu-block@nongnu.org, xen-devel@lists.xenproject.org, kvm@vger.kernel.org, Gerd Hoffmann , Mauro Carvalho Chehab , "Michael S. Tsirkin" , Igor Mammedov , Ani Sinha , Peter Maydell , Richard Henderson , Song Gao , Bibo Mao , Jiaxun Yang , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Sunil V L , Palmer Dabbelt , Alistair Francis , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Chao Liu , linux-edac@vger.kernel.org, qemu-arm@nongnu.org, qemu-riscv@nongnu.org, Akihiko Odaki X-Mailer: b4 0.16-dev-925f5 X-Developer-Signature: v=1; a=openpgp-sha256; l=2570; i=odaki@rsg.ci.i.u-tokyo.ac.jp; h=from:subject:message-id; bh=rfWCLDHUcpahNgEC3SGqI/nzOlyqMecU43nGCyZYC8s=; b=owGbwMvMwCWmMbc20y1CyJDxtFoSQ5a7292uvb5fvrnm7tp9b5dvJte9v0uYEovO1uddvZ35h NFhQtvZjlIWBjEuBlkxRZaUot3cGtG1nwoT4ltg5rAygQxh4OIUgInUXWD4n3Q8Z7FJ9M3+/FlP yrWtlv46vnNK17JZ90Nzdlx6dcBGrpWRYeH/uf8fOdSpt8X3Xi7e9oZt790XTTtv/ZL4+X3x6UM KvHwA X-Developer-Key: i=odaki@rsg.ci.i.u-tokyo.ac.jp; a=openpgp; fpr=AEDC03C9AF734F2EC26A7BFFA4BAEAA73536753C 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=lists1p.gnu.org; Received-SPF: pass client-ip=49.212.243.89; envelope-from=odaki@rsg.ci.i.u-tokyo.ac.jp; helo=www3579.sakura.ne.jp X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_INVALID=0.1, DKIM_SIGNED=0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no 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-ZM-MESSAGEID: 1783056208503158500 The acpi-mr-restore property exists only for migration compatibility with QEMU 4.2, which is no longer a supported migration source. Signed-off-by: Akihiko Odaki --- include/hw/nvram/fw_cfg.h | 1 - hw/core/machine.c | 1 - hw/nvram/fw_cfg.c | 8 +------- 3 files changed, 1 insertion(+), 9 deletions(-) diff --git a/include/hw/nvram/fw_cfg.h b/include/hw/nvram/fw_cfg.h index 56f17a0bdcf7..6aad9aad7694 100644 --- a/include/hw/nvram/fw_cfg.h +++ b/include/hw/nvram/fw_cfg.h @@ -73,7 +73,6 @@ struct FWCfgState { MemoryRegion dma_iomem; =20 /* restore during migration */ - bool acpi_mr_restore; uint64_t table_mr_size; uint64_t linker_mr_size; uint64_t rsdp_mr_size; diff --git a/hw/core/machine.c b/hw/core/machine.c index 9a10e45aabd5..44803e884140 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -214,7 +214,6 @@ GlobalProperty hw_compat_4_2[] =3D { { "usb-redir", "suppress-remote-wake", "off" }, { "qxl", "revision", "4" }, { "qxl-vga", "revision", "4" }, - { "fw_cfg", "acpi-mr-restore", "false" }, { "virtio-device", "use-disabled-flag", "false" }, }; const size_t hw_compat_4_2_len =3D G_N_ELEMENTS(hw_compat_4_2); diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c index 1d7d83542137..f4e3e50224ca 100644 --- a/hw/nvram/fw_cfg.c +++ b/hw/nvram/fw_cfg.c @@ -612,7 +612,7 @@ static bool fw_cfg_acpi_mr_restore(void *opaque) mr_aligned =3D QEMU_IS_ALIGNED(s->table_mr_size, qemu_real_host_page_s= ize()) && QEMU_IS_ALIGNED(s->linker_mr_size, qemu_real_host_page_si= ze()) && QEMU_IS_ALIGNED(s->rsdp_mr_size, qemu_real_host_page_size= ()); - return s->acpi_mr_restore && !mr_aligned; + return !mr_aligned; } =20 static void fw_cfg_update_mr(FWCfgState *s, uint16_t key, size_t size) @@ -987,10 +987,6 @@ static void fw_cfg_machine_ready(struct Notifier *n, v= oid *data) qemu_register_reset(fw_cfg_machine_reset, s); } =20 -static const Property fw_cfg_properties[] =3D { - DEFINE_PROP_BOOL("acpi-mr-restore", FWCfgState, acpi_mr_restore, true), -}; - static void fw_cfg_common_realize(DeviceState *dev, Error **errp) { FWCfgState *s =3D FW_CFG(dev); @@ -1149,8 +1145,6 @@ static void fw_cfg_class_init(ObjectClass *klass, con= st void *data) =20 device_class_set_legacy_reset(dc, fw_cfg_reset); dc->vmsd =3D &vmstate_fw_cfg; - - device_class_set_props(dc, fw_cfg_properties); } =20 static const TypeInfo fw_cfg_info =3D { --=20 2.54.0 From nobody Sat Jul 4 21:12:58 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; 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=fail(p=reject dis=none) header.from=rsg.ci.i.u-tokyo.ac.jp Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 178305631822460.99805617629636; Thu, 2 Jul 2026 22:25:18 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wfWMg-0005aq-Kd; Fri, 03 Jul 2026 01:23:02 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wfWMZ-0005WO-VZ; Fri, 03 Jul 2026 01:22:56 -0400 Received: from www3579.sakura.ne.jp ([49.212.243.89]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wfWMW-0005vx-Kz; Fri, 03 Jul 2026 01:22:55 -0400 Received: from h183.csg.ci.i.u-tokyo.ac.jp (h183.csg.ci.i.u-tokyo.ac.jp [133.11.54.183]) (authenticated bits=0) by www3579.sakura.ne.jp (8.16.1/8.16.1) with ESMTPSA id 6635LT8P018373 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Fri, 3 Jul 2026 14:21:43 +0900 (JST) (envelope-from odaki@rsg.ci.i.u-tokyo.ac.jp) DKIM-Signature: a=rsa-sha256; bh=yI7z983L2jKLplCj01xQZlmdHreHtJMxOkjcK5D3Uhg=; c=relaxed/relaxed; d=rsg.ci.i.u-tokyo.ac.jp; h=From:Message-Id:To:Subject:Date; s=rs20250326; t=1783056104; v=1; b=eA+u+b5Pn/F6Fsu4XPL2Fil+YxYg1ZkQ4++IfHV0CZAegdmINv/jec+3gJCku6sS 1Kgpnin6bB3a3dKwGxXYGzMFW0yn2kSvLDRJhbYW6gNMl45KzgJUA5tKmCHwgCSk f+IEKE214HwMehUnBmsvSTUaJXjU9iJmVJ3UYsaxlKNbAnQckH5wIPNhsyk7jwuH ufv2SYJDdz1XC7HnPTzFKX/oKmtFL9DMPxfozld5JtnfqYEh5V3JK6epFJQYzkIY 2Oj/IWFYlmHYiy5KblnCVeIwkAuOfStcpVUtczbk42Y87GNMCuDCMkNBm1h34uA6 fqVOF77PetcRnkg4/nn5fw== From: Akihiko Odaki Date: Fri, 03 Jul 2026 14:19:18 +0900 Subject: [PATCH v2 2/7] hw/nvram/fw_cfg: Avoid resizing RAM at runtime MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260703-ram-v2-2-7f07fc06fba9@rsg.ci.i.u-tokyo.ac.jp> References: <20260703-ram-v2-0-7f07fc06fba9@rsg.ci.i.u-tokyo.ac.jp> In-Reply-To: <20260703-ram-v2-0-7f07fc06fba9@rsg.ci.i.u-tokyo.ac.jp> To: qemu-devel@nongnu.org Cc: Kevin Wolf , Hanna Reitz , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , Zhao Liu , Stefano Stabellini , Anthony PERARD , "Edgar E. Iglesias" , Peter Xu , Fabiano Rosas , Paolo Bonzini , Reinoud Zandijk , Marcelo Tosatti , Alex Williamson , =?utf-8?q?C=C3=A9dric_Le_Goater?= , qemu-block@nongnu.org, xen-devel@lists.xenproject.org, kvm@vger.kernel.org, Gerd Hoffmann , Mauro Carvalho Chehab , "Michael S. Tsirkin" , Igor Mammedov , Ani Sinha , Peter Maydell , Richard Henderson , Song Gao , Bibo Mao , Jiaxun Yang , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Sunil V L , Palmer Dabbelt , Alistair Francis , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Chao Liu , linux-edac@vger.kernel.org, qemu-arm@nongnu.org, qemu-riscv@nongnu.org, Akihiko Odaki X-Mailer: b4 0.16-dev-925f5 X-Developer-Signature: v=1; a=openpgp-sha256; l=19046; i=odaki@rsg.ci.i.u-tokyo.ac.jp; h=from:subject:message-id; bh=ccy6opZLwUXKw1fFsJIq/3ZXHcSwmcArvoTXP9WAi+0=; b=owGbwMvMwCWmMbc20y1CyJDxtFoSQ5a72z3zK461+97OmDpTvi9l0bklb0+z3bYv1f54sjWfX WrvcfHojlIWBjEuBlkxRZaUot3cGtG1nwoT4ltg5rAygQxh4OIUgInEKzD89zaprCy8/LN69qYr CxdKmMr9Pi0Xv04h877g7W097KrC0xl+s0tJXjefVnx68x7j59pp5zKvXOdS57/pdO30fYu5vIE nGAE= X-Developer-Key: i=odaki@rsg.ci.i.u-tokyo.ac.jp; a=openpgp; fpr=AEDC03C9AF734F2EC26A7BFFA4BAEAA73536753C 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=lists1p.gnu.org; Received-SPF: pass client-ip=49.212.243.89; envelope-from=odaki@rsg.ci.i.u-tokyo.ac.jp; helo=www3579.sakura.ne.jp X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_INVALID=0.1, DKIM_SIGNED=0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no 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-ZM-MESSAGEID: 1783056319509158500 There is a chance that migration is aborted when the following conditions are met: 1. The machine has not booted yet, or devices have been hotplugged since the last boot. 2. The machine is (re)booting. 3. Migration is running concurrently. This is because the size of ACPI data is determined after the firmware configures the machine at boot time, and that may change the size of backing RAM. This aborts migration if the RAM is concurrently being copied. It is rare that all three conditions are met at the same time, but migrating after device hotplug and migrating during reboot are supported, so ideally their combination should be supported. To support this scenario, allocate RAM for the maximum ACPI data size up front, while exposing only the current ACPI data size through fw_cfg. This avoids runtime RAMBlock resize during ACPI rebuilds and lets the memory and migration code handle the RAMBlock like any other fixed-size RAMBlock. The ACPI data still uses resizable RAM for migration compatibility. The destination may resize it while loading migration streams from older QEMU versions, but it immediately grows the RAM back to the maximum size. This destination-side resize does not cause migration to abort. Signed-off-by: Akihiko Odaki --- include/hw/core/loader.h | 1 + include/hw/nvram/fw_cfg.h | 4 ++- hw/acpi/ghes.c | 6 ++-- hw/acpi/vmgenid.c | 1 + hw/arm/virt-acpi-build.c | 3 +- hw/core/loader.c | 14 +++++--- hw/display/ramfb.c | 2 +- hw/i386/acpi-build.c | 3 +- hw/isa/lpc_ich9.c | 2 ++ hw/loongarch/virt-acpi-build.c | 3 +- hw/misc/vmcoreinfo.c | 3 +- hw/nvram/fw_cfg.c | 74 ++++++++++++++++++++++++++------------= ---- hw/riscv/virt-acpi-build.c | 3 +- 13 files changed, 77 insertions(+), 42 deletions(-) diff --git a/include/hw/core/loader.h b/include/hw/core/loader.h index d9431e8a8d12..d563acc1f1dd 100644 --- a/include/hw/core/loader.h +++ b/include/hw/core/loader.h @@ -259,6 +259,7 @@ void pstrcpy_targphys(const char *name, hwaddr dest, int buf_size, const char *source); =20 +void rom_resize(const MemoryRegion *mr, size_t len); ssize_t rom_add_file(const char *file, const char *fw_dir, hwaddr addr, int32_t bootindex, bool has_option_rom, MemoryRegion *mr, AddressSpace *= as); diff --git a/include/hw/nvram/fw_cfg.h b/include/hw/nvram/fw_cfg.h index 6aad9aad7694..201b33434a3c 100644 --- a/include/hw/nvram/fw_cfg.h +++ b/include/hw/nvram/fw_cfg.h @@ -240,6 +240,7 @@ void fw_cfg_add_file(FWCfgState *s, const char *filenam= e, void *data, * @callback_opaque: argument to be passed into callback function * @data: pointer to start of item data * @len: size of item data + * @max_len: maximum size of item data * @read_only: is file read only * * Add a new NAMED fw_cfg item as a raw "blob" of the given size. The data @@ -258,7 +259,8 @@ void fw_cfg_add_file_callback(FWCfgState *s, const char= *filename, FWCfgCallback select_cb, FWCfgWriteCallback write_cb, void *callback_opaque, - void *data, size_t len, bool read_only); + void *data, size_t len, size_t max_len, + bool read_only); =20 /** * fw_cfg_modify_file: diff --git a/hw/acpi/ghes.c b/hw/acpi/ghes.c index b2d5e3499320..9679059100e5 100644 --- a/hw/acpi/ghes.c +++ b/hw/acpi/ghes.c @@ -415,11 +415,13 @@ void acpi_ghes_add_fw_cfg(AcpiGhesState *ags, FWCfgSt= ate *s, =20 if (ags->use_hest_addr) { fw_cfg_add_file_callback(s, ACPI_HEST_ADDR_FW_CFG_FILE, NULL, NULL, - NULL, &(ags->hest_addr_le), sizeof(ags->hest_addr_le), false); + NULL, &(ags->hest_addr_le), + sizeof(ags->hest_addr_le), sizeof(ags->hest_addr_le), false); } else { /* Create a read-write fw_cfg file for Address */ fw_cfg_add_file_callback(s, ACPI_HW_ERROR_ADDR_FW_CFG_FILE, NULL, = NULL, - NULL, &(ags->hw_error_le), sizeof(ags->hw_error_le), false); + NULL, &(ags->hw_error_le), + sizeof(ags->hw_error_le), sizeof(ags->hw_error_le), false); } } =20 diff --git a/hw/acpi/vmgenid.c b/hw/acpi/vmgenid.c index 27cc0128d117..c2a4eb7ac394 100644 --- a/hw/acpi/vmgenid.c +++ b/hw/acpi/vmgenid.c @@ -130,6 +130,7 @@ void vmgenid_add_fw_cfg(VmGenIdState *vms, FWCfgState *= s, GArray *guid) /* Create a read-write fw_cfg file for Address */ fw_cfg_add_file_callback(s, VMGENID_ADDR_FW_CFG_FILE, NULL, NULL, NULL, vms->vmgenid_addr_le, + ARRAY_SIZE(vms->vmgenid_addr_le), ARRAY_SIZE(vms->vmgenid_addr_le), false); } =20 diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index 99490aa7b1fb..9e3ae08f1f8e 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -32,6 +32,7 @@ #include "qemu/error-report.h" #include "trace.h" #include "hw/core/cpu.h" +#include "hw/core/loader.h" #include "hw/acpi/acpi-defs.h" #include "hw/acpi/acpi.h" #include "hw/acpi/pcihp.h" @@ -1469,7 +1470,7 @@ static void acpi_ram_update(MemoryRegion *mr, GArray = *data) =20 /* Make sure RAM size is correct - in case it got changed * e.g. by migration */ - memory_region_ram_resize(mr, size, &error_abort); + rom_resize(mr, size); =20 memcpy(memory_region_get_ram_ptr(mr), data->data, size); memory_region_set_dirty(mr, 0, size); diff --git a/hw/core/loader.c b/hw/core/loader.c index 5cbfba0a86d2..14d56f52e4ec 100644 --- a/hw/core/loader.c +++ b/hw/core/loader.c @@ -1051,10 +1051,14 @@ static void rom_insert(Rom *rom) QTAILQ_INSERT_TAIL(&roms, rom, next); } =20 -static void fw_cfg_resized(const char *id, uint64_t length, void *host) +void rom_resize(const MemoryRegion *mr, size_t len) { if (fw_cfg) { - fw_cfg_modify_file(fw_cfg, id + strlen("/rom@"), host, length); + const char *name =3D memory_region_name(mr); + void *host =3D memory_region_get_ram_ptr(mr); + + assert(len <=3D memory_region_size(mr)); + fw_cfg_modify_file(fw_cfg, name + strlen("/rom@"), host, len); } } =20 @@ -1064,8 +1068,8 @@ static void *rom_set_mr(Rom *rom, Object *owner, cons= t char *name, bool ro) =20 rom->mr =3D g_malloc(sizeof(*rom->mr)); memory_region_init_resizeable_ram(rom->mr, owner, name, - rom->datasize, rom->romsize, - fw_cfg_resized, + rom->romsize, rom->romsize, + NULL, &error_fatal); memory_region_set_readonly(rom->mr, ro); vmstate_register_ram_global(rom->mr); @@ -1196,7 +1200,7 @@ MemoryRegion *rom_add_blob(const char *name, const vo= id *blob, size_t len, =20 fw_cfg_add_file_callback(fw_cfg, fw_file_name, fw_callback, NULL, callback_opaque, - data, rom->datasize, read_only); + data, rom->datasize, rom->romsize, read_o= nly); } return mr; } diff --git a/hw/display/ramfb.c b/hw/display/ramfb.c index f477bdcc2186..3c4be28072fb 100644 --- a/hw/display/ramfb.c +++ b/hw/display/ramfb.c @@ -154,6 +154,6 @@ RAMFBState *ramfb_setup(bool romfile, Error **errp) } fw_cfg_add_file_callback(fw_cfg, "etc/ramfb", NULL, ramfb_fw_cfg_write, s, - &s->cfg, sizeof(s->cfg), false); + &s->cfg, sizeof(s->cfg), sizeof(s->cfg), fals= e); return s; } diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 2ee061558c08..a83a9893a827 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -30,6 +30,7 @@ #include "hw/pci/pci_bridge.h" #include "hw/cxl/cxl.h" #include "hw/core/cpu.h" +#include "hw/core/loader.h" #include "target/i386/cpu.h" #include "hw/timer/hpet.h" #include "hw/acpi/acpi-defs.h" @@ -2138,7 +2139,7 @@ static void acpi_ram_update(MemoryRegion *mr, GArray = *data) uint32_t size =3D acpi_data_len(data); =20 /* Make sure RAM size is correct - in case it got changed e.g. by migr= ation */ - memory_region_ram_resize(mr, size, &error_abort); + rom_resize(mr, size); =20 memcpy(memory_region_get_ram_ptr(mr), data->data, size); memory_region_set_dirty(mr, 0, size); diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c index 9cec18a378c2..fe5c8d6f44f4 100644 --- a/hw/isa/lpc_ich9.c +++ b/hw/isa/lpc_ich9.c @@ -449,11 +449,13 @@ static void ich9_lpc_pm_init(ICH9LPCState *lpc) NULL, NULL, NULL, lpc->smi_guest_features_le, sizeof lpc->smi_guest_features_le, + sizeof lpc->smi_guest_features_le, false); fw_cfg_add_file_callback(fw_cfg, "etc/smi/features-ok", smi_features_ok_callback, NULL, lpc, &lpc->smi_features_ok, sizeof lpc->smi_features_ok, + sizeof lpc->smi_features_ok, true); } } diff --git a/hw/loongarch/virt-acpi-build.c b/hw/loongarch/virt-acpi-build.c index a0b445f297b4..4be390189637 100644 --- a/hw/loongarch/virt-acpi-build.c +++ b/hw/loongarch/virt-acpi-build.c @@ -11,6 +11,7 @@ #include "qemu/bitmap.h" #include "hw/pci/pci.h" #include "hw/core/cpu.h" +#include "hw/core/loader.h" #include "target/loongarch/cpu.h" #include "hw/acpi/acpi-defs.h" #include "hw/acpi/acpi.h" @@ -630,7 +631,7 @@ static void acpi_ram_update(MemoryRegion *mr, GArray *d= ata) * Make sure RAM size is correct - in case it got changed * e.g. by migration */ - memory_region_ram_resize(mr, size, &error_abort); + rom_resize(mr, size); =20 memcpy(memory_region_get_ram_ptr(mr), data->data, size); memory_region_set_dirty(mr, 0, size); diff --git a/hw/misc/vmcoreinfo.c b/hw/misc/vmcoreinfo.c index 9c2e9005ad32..8cb1763c1a44 100644 --- a/hw/misc/vmcoreinfo.c +++ b/hw/misc/vmcoreinfo.c @@ -59,7 +59,8 @@ static void vmcoreinfo_realize(DeviceState *dev, Error **= errp) =20 fw_cfg_add_file_callback(fw_cfg, FW_CFG_VMCOREINFO_FILENAME, NULL, fw_cfg_vmci_write, s, - &s->vmcoreinfo, sizeof(s->vmcoreinfo), false); + &s->vmcoreinfo, sizeof(s->vmcoreinfo), + sizeof(s->vmcoreinfo), false); =20 /* * This device requires to register a global reset because it is diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c index f4e3e50224ca..03fb4b569fe7 100644 --- a/hw/nvram/fw_cfg.c +++ b/hw/nvram/fw_cfg.c @@ -60,6 +60,7 @@ =20 struct FWCfgEntry { uint32_t len; + uint32_t max_len; bool allow_write; uint8_t *data; void *callback_opaque; @@ -604,20 +605,8 @@ bool fw_cfg_dma_enabled(void *opaque) return s->dma_enabled; } =20 -static bool fw_cfg_acpi_mr_restore(void *opaque) +static MemoryRegion *fw_cfg_get_mr(FWCfgState *s, uint16_t key) { - FWCfgState *s =3D opaque; - bool mr_aligned; - - mr_aligned =3D QEMU_IS_ALIGNED(s->table_mr_size, qemu_real_host_page_s= ize()) && - QEMU_IS_ALIGNED(s->linker_mr_size, qemu_real_host_page_si= ze()) && - QEMU_IS_ALIGNED(s->rsdp_mr_size, qemu_real_host_page_size= ()); - return !mr_aligned; -} - -static void fw_cfg_update_mr(FWCfgState *s, uint16_t key, size_t size) -{ - MemoryRegion *mr; ram_addr_t offset; int arch =3D !!(key & FW_CFG_ARCH_LOCAL); void *ptr; @@ -626,31 +615,57 @@ static void fw_cfg_update_mr(FWCfgState *s, uint16_t = key, size_t size) assert(key < fw_cfg_max_entry(s)); =20 ptr =3D s->entries[arch][key].data; - mr =3D memory_region_from_host(ptr, &offset); + return memory_region_from_host(ptr, &offset); +} + +static bool fw_cfg_pre_load_errp(void *opaque, Error **errp) +{ + FWCfgState *s =3D opaque; + + s->table_mr_size =3D UINT64_MAX; + s->linker_mr_size =3D UINT64_MAX; + s->rsdp_mr_size =3D UINT64_MAX; =20 - memory_region_ram_resize(mr, size, &error_abort); + return true; } =20 -static int fw_cfg_acpi_mr_restore_post_load(void *opaque, int version_id) +static bool fw_cfg_post_load_errp(void *opaque, int version_id, Error **er= rp) { FWCfgState *s =3D opaque; int i, index; + uint64_t *size; =20 assert(s->files); =20 index =3D be32_to_cpu(s->files->count); =20 for (i =3D 0; i < index; i++) { + uint16_t key =3D FW_CFG_FILE_FIRST + i; + MemoryRegion *mr; + int arch =3D !!(key & FW_CFG_ARCH_LOCAL); + if (!strcmp(s->files->f[i].name, ACPI_BUILD_TABLE_FILE)) { - fw_cfg_update_mr(s, FW_CFG_FILE_FIRST + i, s->table_mr_size); + size =3D &s->table_mr_size; } else if (!strcmp(s->files->f[i].name, ACPI_BUILD_LOADER_FILE)) { - fw_cfg_update_mr(s, FW_CFG_FILE_FIRST + i, s->linker_mr_size); + size =3D &s->linker_mr_size; } else if (!strcmp(s->files->f[i].name, ACPI_BUILD_RSDP_FILE)) { - fw_cfg_update_mr(s, FW_CFG_FILE_FIRST + i, s->rsdp_mr_size); + size =3D &s->rsdp_mr_size; + } else { + continue; } + + mr =3D fw_cfg_get_mr(s, key); + + if (*size =3D=3D UINT64_MAX) { + *size =3D memory_region_size(mr); + } + + rom_resize(mr, *size); + memory_region_ram_resize(mr, s->entries[arch][key].max_len, + &error_abort); } =20 - return 0; + return true; } =20 static const VMStateDescription vmstate_fw_cfg_dma =3D { @@ -666,8 +681,6 @@ static const VMStateDescription vmstate_fw_cfg_acpi_mr = =3D { .name =3D "fw_cfg/acpi_mr", .version_id =3D 1, .minimum_version_id =3D 1, - .needed =3D fw_cfg_acpi_mr_restore, - .post_load =3D fw_cfg_acpi_mr_restore_post_load, .fields =3D (const VMStateField[]) { VMSTATE_UINT64(table_mr_size, FWCfgState), VMSTATE_UINT64(linker_mr_size, FWCfgState), @@ -680,6 +693,8 @@ static const VMStateDescription vmstate_fw_cfg =3D { .name =3D "fw_cfg", .version_id =3D 2, .minimum_version_id =3D 1, + .pre_load_errp =3D fw_cfg_pre_load_errp, + .post_load_errp =3D fw_cfg_post_load_errp, .fields =3D (const VMStateField[]) { VMSTATE_UINT16(cur_entry, FWCfgState), VMSTATE_UINT16_HACK(cur_offset, FWCfgState, is_version_1), @@ -697,7 +712,7 @@ static void fw_cfg_add_bytes_callback(FWCfgState *s, ui= nt16_t key, FWCfgCallback select_cb, FWCfgWriteCallback write_cb, void *callback_opaque, - void *data, size_t len, + void *data, size_t len, size_t max_l= en, bool read_only) { int arch =3D !!(key & FW_CFG_ARCH_LOCAL); @@ -709,6 +724,7 @@ static void fw_cfg_add_bytes_callback(FWCfgState *s, ui= nt16_t key, =20 s->entries[arch][key].data =3D data; s->entries[arch][key].len =3D (uint32_t)len; + s->entries[arch][key].max_len =3D (uint32_t)max_len; s->entries[arch][key].select_cb =3D select_cb; s->entries[arch][key].write_cb =3D write_cb; s->entries[arch][key].callback_opaque =3D callback_opaque; @@ -737,7 +753,7 @@ static void *fw_cfg_modify_bytes_read(FWCfgState *s, ui= nt16_t key, void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, void *data, size_t len) { trace_fw_cfg_add_bytes(key, trace_key_name(key), len); - fw_cfg_add_bytes_callback(s, key, NULL, NULL, NULL, data, len, true); + fw_cfg_add_bytes_callback(s, key, NULL, NULL, NULL, data, len, len, tr= ue); } =20 void fw_cfg_add_string(FWCfgState *s, uint16_t key, const char *value) @@ -838,7 +854,8 @@ void fw_cfg_add_file_callback(FWCfgState *s, const cha= r *filename, FWCfgCallback select_cb, FWCfgWriteCallback write_cb, void *callback_opaque, - void *data, size_t len, bool read_only) + void *data, size_t len, size_t max_len, + bool read_only) { int i, index, count; size_t dsize; @@ -889,7 +906,7 @@ void fw_cfg_add_file_callback(FWCfgState *s, const cha= r *filename, =20 fw_cfg_add_bytes_callback(s, FW_CFG_FILE_FIRST + index, select_cb, write_cb, - callback_opaque, data, len, + callback_opaque, data, len, max_len, read_only); =20 s->files->f[index].size =3D cpu_to_be32(len); @@ -904,7 +921,8 @@ void fw_cfg_add_file_callback(FWCfgState *s, const cha= r *filename, void fw_cfg_add_file(FWCfgState *s, const char *filename, void *data, size_t len) { - fw_cfg_add_file_callback(s, filename, NULL, NULL, NULL, data, len, tru= e); + fw_cfg_add_file_callback(s, filename, NULL, NULL, NULL, + data, len, len, true); } =20 void *fw_cfg_modify_file(FWCfgState *s, const char *filename, @@ -930,7 +948,7 @@ void *fw_cfg_modify_file(FWCfgState *s, const char *fil= ename, assert(index < fw_cfg_file_slots(s)); =20 /* add new one */ - fw_cfg_add_file_callback(s, filename, NULL, NULL, NULL, data, len, tru= e); + fw_cfg_add_file(s, filename, data, len); return NULL; } =20 diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c index 413d47d70ef1..10825fa37769 100644 --- a/hw/riscv/virt-acpi-build.c +++ b/hw/riscv/virt-acpi-build.c @@ -29,6 +29,7 @@ #include "hw/acpi/aml-build.h" #include "hw/acpi/pci.h" #include "hw/acpi/utils.h" +#include "hw/core/loader.h" #include "hw/intc/riscv_aclint.h" #include "hw/nvram/fw_cfg_acpi.h" #include "hw/pci-host/gpex.h" @@ -961,7 +962,7 @@ static void acpi_ram_update(MemoryRegion *mr, GArray *d= ata) * Make sure RAM size is correct - in case it got changed * e.g. by migration */ - memory_region_ram_resize(mr, size, &error_abort); + rom_resize(mr, size); =20 memcpy(memory_region_get_ram_ptr(mr), data->data, size); memory_region_set_dirty(mr, 0, size); --=20 2.54.0 From nobody Sat Jul 4 21:12:58 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; 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=fail(p=reject dis=none) header.from=rsg.ci.i.u-tokyo.ac.jp Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1783056215839757.1349059129371; Thu, 2 Jul 2026 22:23:35 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wfWMY-0005VL-NW; Fri, 03 Jul 2026 01:22:54 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wfWMV-0005T0-R5; Fri, 03 Jul 2026 01:22:51 -0400 Received: from www3579.sakura.ne.jp ([49.212.243.89]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wfWMS-0005s1-0K; Fri, 03 Jul 2026 01:22:51 -0400 Received: from h183.csg.ci.i.u-tokyo.ac.jp (h183.csg.ci.i.u-tokyo.ac.jp [133.11.54.183]) (authenticated bits=0) by www3579.sakura.ne.jp (8.16.1/8.16.1) with ESMTPSA id 6635LT8Q018373 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Fri, 3 Jul 2026 14:21:44 +0900 (JST) (envelope-from odaki@rsg.ci.i.u-tokyo.ac.jp) DKIM-Signature: a=rsa-sha256; bh=8Z+IPYMxREf+abkIImBqXakTaTGWJQ+kmZT646AKWUY=; c=relaxed/relaxed; d=rsg.ci.i.u-tokyo.ac.jp; h=From:Message-Id:To:Subject:Date; s=rs20250326; t=1783056104; v=1; b=mHK+MzHFe5pufb2GxF26lI1muKh0LM+Rd1oFmcUJgWtJDzyFLEyjJTIMi9/UcG9e b6m3yIJruONYSU9TQbQxLPoMEcnG0kf5jFjS2l+n6JAbeK31JNC+hybrwvXnkhJR CG2PwqJugDdAZw7Gq+S+cEf1bBXJ2CehRXn6Zm+byZrqs5/zxSCr3J9Vj7FWVEYI RsrkydzvZE6U7li2a+bESxJ0pFUF36jchgz9/3gCXYzrS6j6CtVSjPUfhtDrgTPY OQIWzIYZLqeZ8afzJdDGh/Wrm8rVJU4n+foWkCyCwvP+A5ahHBTDWNDjflCsEBez 8b8WsIzbrLT4qSjrTeLFkw== From: Akihiko Odaki Date: Fri, 03 Jul 2026 14:19:19 +0900 Subject: [PATCH v2 3/7] system/memory: Remove the resized callback MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260703-ram-v2-3-7f07fc06fba9@rsg.ci.i.u-tokyo.ac.jp> References: <20260703-ram-v2-0-7f07fc06fba9@rsg.ci.i.u-tokyo.ac.jp> In-Reply-To: <20260703-ram-v2-0-7f07fc06fba9@rsg.ci.i.u-tokyo.ac.jp> To: qemu-devel@nongnu.org Cc: Kevin Wolf , Hanna Reitz , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , Zhao Liu , Stefano Stabellini , Anthony PERARD , "Edgar E. Iglesias" , Peter Xu , Fabiano Rosas , Paolo Bonzini , Reinoud Zandijk , Marcelo Tosatti , Alex Williamson , =?utf-8?q?C=C3=A9dric_Le_Goater?= , qemu-block@nongnu.org, xen-devel@lists.xenproject.org, kvm@vger.kernel.org, Gerd Hoffmann , Mauro Carvalho Chehab , "Michael S. Tsirkin" , Igor Mammedov , Ani Sinha , Peter Maydell , Richard Henderson , Song Gao , Bibo Mao , Jiaxun Yang , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Sunil V L , Palmer Dabbelt , Alistair Francis , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Chao Liu , linux-edac@vger.kernel.org, qemu-arm@nongnu.org, qemu-riscv@nongnu.org, Akihiko Odaki X-Mailer: b4 0.16-dev-925f5 X-Developer-Signature: v=1; a=openpgp-sha256; l=10859; i=odaki@rsg.ci.i.u-tokyo.ac.jp; h=from:subject:message-id; bh=L+KVAMGTsaOt599iuSVgif1jV4HKCoTCrodEu6dG+Qg=; b=owGbwMvMwCWmMbc20y1CyJDxtFoSQ5a72wPp7bZLZ897U1e/sKCf4VvVg/3yNqKLXbesnyLwy /id7LyJHaUsDGJcDLJiiiwpRbu5NaJrPxUmxLfAzGFlAhnCwMUpABPZrcPwP+Flw5Xje7OyFpQu b3h/6c6hbJ/E5wdKXi42TboU9Oen+k+G/1nv1azc0lxehausvPHl3iWuB9z5xvNMzaIFN25JPG0 5ix8A X-Developer-Key: i=odaki@rsg.ci.i.u-tokyo.ac.jp; a=openpgp; fpr=AEDC03C9AF734F2EC26A7BFFA4BAEAA73536753C 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=lists1p.gnu.org; Received-SPF: pass client-ip=49.212.243.89; envelope-from=odaki@rsg.ci.i.u-tokyo.ac.jp; helo=www3579.sakura.ne.jp X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_INVALID=0.1, DKIM_SIGNED=0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no 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-ZM-MESSAGEID: 1783056217294158500 The previous change moved fw_cfg updates out of the RAMBlock resize callback, leaving the callback pointer unused. Remove the now-unused callback plumbing. Signed-off-by: Akihiko Odaki --- include/system/memory.h | 4 ---- include/system/ramblock.h | 7 +------ hw/core/loader.c | 4 +--- system/memory.c | 7 ++----- system/physmem.c | 24 ++++++------------------ 5 files changed, 10 insertions(+), 36 deletions(-) diff --git a/include/system/memory.h b/include/system/memory.h index e143c9c3f396..6a2d5f5f855f 100644 --- a/include/system/memory.h +++ b/include/system/memory.h @@ -1407,7 +1407,6 @@ bool memory_region_init_ram_flags_nomigrate(MemoryReg= ion *mr, * must be unique within any device * @size: used size of the region. * @max_size: max size of the region. - * @resized: callback to notify owner about used size change. * @errp: pointer to Error*, to store an error if it happens. * * Note that this function does not do anything to cause the data in the @@ -1420,9 +1419,6 @@ bool memory_region_init_resizeable_ram(MemoryRegion *= mr, const char *name, uint64_t size, uint64_t max_size, - void (*resized)(const char*, - uint64_t length, - void *host), Error **errp); #ifdef CONFIG_POSIX =20 diff --git a/include/system/ramblock.h b/include/system/ramblock.h index 4435f8d55fe7..1a95fba87f0c 100644 --- a/include/system/ramblock.h +++ b/include/system/ramblock.h @@ -30,7 +30,6 @@ struct RAMBlock { ram_addr_t offset; ram_addr_t used_length; ram_addr_t max_length; - void (*resized)(const char*, uint64_t length, void *host); uint32_t flags; /* Protected by the BQL. */ char idstr[256]; @@ -244,7 +243,6 @@ static inline unsigned long int ramblock_recv_bitmap_of= fset(void *host_addr, * @size: the size in bytes of the ram block * @max_size: the maximum size of the block after resizing * @mr: the memory region where the ram block is - * @resized: callback after calls to qemu_ram_resize * @ram_flags: RamBlock flags. Supported flags: RAM_SHARED, RAM_PMEM, * RAM_NORESERVE, RAM_PROTECTED, RAM_NAMED_FILE, RAM_READONLY, * RAM_READONLY_FD, RAM_GUEST_MEMFD @@ -257,13 +255,11 @@ static inline unsigned long int ramblock_recv_bitmap_= offset(void *host_addr, * On success, return a pointer to the ram block. * On failure, return NULL. */ -typedef void (*qemu_ram_resize_cb)(const char *, uint64_t length, void *ho= st); - RAMBlock *qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr, uint32_t ram_flags, const char *mem_pat= h, off_t offset, Error **errp); RAMBlock *qemu_ram_alloc_from_fd(ram_addr_t size, ram_addr_t max_size, - qemu_ram_resize_cb resized, MemoryRegion = *mr, + MemoryRegion *mr, uint32_t ram_flags, int fd, off_t offset, bool grow, Error **errp); @@ -273,7 +269,6 @@ RAMBlock *qemu_ram_alloc_from_ptr(ram_addr_t size, void= *host, RAMBlock *qemu_ram_alloc(ram_addr_t size, uint32_t ram_flags, MemoryRegion= *mr, Error **errp); RAMBlock *qemu_ram_alloc_resizeable(ram_addr_t size, ram_addr_t max_size, - qemu_ram_resize_cb resized, MemoryRegion *mr, Error **errp); void qemu_ram_free(RAMBlock *block); =20 diff --git a/hw/core/loader.c b/hw/core/loader.c index 14d56f52e4ec..147b872031eb 100644 --- a/hw/core/loader.c +++ b/hw/core/loader.c @@ -1068,9 +1068,7 @@ static void *rom_set_mr(Rom *rom, Object *owner, cons= t char *name, bool ro) =20 rom->mr =3D g_malloc(sizeof(*rom->mr)); memory_region_init_resizeable_ram(rom->mr, owner, name, - rom->romsize, rom->romsize, - NULL, - &error_fatal); + rom->romsize, rom->romsize, &error_f= atal); memory_region_set_readonly(rom->mr, ro); vmstate_register_ram_global(rom->mr); =20 diff --git a/system/memory.c b/system/memory.c index 8436668c181d..6ec4b4ebb20e 100644 --- a/system/memory.c +++ b/system/memory.c @@ -1610,16 +1610,13 @@ bool memory_region_init_resizeable_ram(MemoryRegion= *mr, const char *name, uint64_t size, uint64_t max_size, - void (*resized)(const char*, - uint64_t length, - void *host), Error **errp) { RAMBlock *rb; =20 memory_region_init(mr, owner, name, size); mr->ram =3D true; - rb =3D qemu_ram_alloc_resizeable(size, max_size, resized, mr, errp); + rb =3D qemu_ram_alloc_resizeable(size, max_size, mr, errp); return memory_region_set_ram_block(mr, rb); } =20 @@ -1650,7 +1647,7 @@ bool memory_region_init_ram_from_fd(MemoryRegion *mr,= Object *owner, memory_region_init(mr, owner, name, size); mr->ram =3D true; mr->readonly =3D !!(ram_flags & RAM_READONLY); - rb =3D qemu_ram_alloc_from_fd(size, size, NULL, mr, ram_flags, fd, off= set, + rb =3D qemu_ram_alloc_from_fd(size, size, mr, ram_flags, fd, offset, false, errp); return memory_region_set_ram_block(mr, rb); } diff --git a/system/physmem.c b/system/physmem.c index 9e5b50c5b1ca..54fe820ce828 100644 --- a/system/physmem.c +++ b/system/physmem.c @@ -2032,9 +2032,6 @@ int qemu_ram_resize(RAMBlock *block, ram_addr_t newsi= ze, Error **errp) */ if (unaligned_size !=3D memory_region_size(block->mr)) { memory_region_set_size(block->mr, unaligned_size); - if (block->resized) { - block->resized(block->idstr, unaligned_size, block->host); - } } return 0; } @@ -2065,9 +2062,6 @@ int qemu_ram_resize(RAMBlock *block, ram_addr_t newsi= ze, Error **errp) physical_memory_set_dirty_range(block->offset, block->used_length, DIRTY_CLIENTS_ALL); memory_region_set_size(block->mr, unaligned_size); - if (block->resized) { - block->resized(block->idstr, unaligned_size, block->host); - } return 0; } =20 @@ -2297,7 +2291,7 @@ out_free: =20 #if defined(CONFIG_POSIX) && !defined(EMSCRIPTEN) RAMBlock *qemu_ram_alloc_from_fd(ram_addr_t size, ram_addr_t max_size, - qemu_ram_resize_cb resized, MemoryRegion = *mr, + MemoryRegion *mr, uint32_t ram_flags, int fd, off_t offset, bool grow, Error **errp) @@ -2356,7 +2350,6 @@ RAMBlock *qemu_ram_alloc_from_fd(ram_addr_t size, ram= _addr_t max_size, new_block->mr =3D mr; new_block->used_length =3D size; new_block->max_length =3D max_size; - new_block->resized =3D resized; new_block->flags =3D ram_flags; new_block->guest_memfd =3D -1; new_block->host =3D file_ram_alloc(new_block, max_size, fd, @@ -2413,7 +2406,7 @@ RAMBlock *qemu_ram_alloc_from_file(ram_addr_t size, M= emoryRegion *mr, return NULL; } =20 - block =3D qemu_ram_alloc_from_fd(size, size, NULL, mr, ram_flags, fd, = offset, + block =3D qemu_ram_alloc_from_fd(size, size, mr, ram_flags, fd, offset, false, errp); if (!block) { if (created) { @@ -2458,7 +2451,6 @@ static int qemu_ram_get_shared_fd(const char *name, b= ool *reused, Error **errp) =20 static RAMBlock *qemu_ram_alloc_internal(ram_addr_t size, ram_addr_t max_size, - qemu_ram_resize_cb resized, void *host, uint32_t ram_flags, MemoryRegion *mr, Error **errp) { @@ -2504,7 +2496,7 @@ RAMBlock *qemu_ram_alloc_internal(ram_addr_t size, ra= m_addr_t max_size, * region if necessary. The extra space will be usable after a * guest reset. */ - new_block =3D qemu_ram_alloc_from_fd(size, max_size, resized, = mr, + new_block =3D qemu_ram_alloc_from_fd(size, max_size, mr, ram_flags, fd, 0, reused, N= ULL); if (new_block) { trace_qemu_ram_alloc_shared(name, new_block->used_length, @@ -2527,7 +2519,6 @@ RAMBlock *qemu_ram_alloc_internal(ram_addr_t size, ra= m_addr_t max_size, =20 new_block =3D g_malloc0(sizeof(*new_block)); new_block->mr =3D mr; - new_block->resized =3D resized; new_block->used_length =3D size; new_block->max_length =3D max_size; new_block->fd =3D -1; @@ -2547,8 +2538,7 @@ RAMBlock *qemu_ram_alloc_internal(ram_addr_t size, ra= m_addr_t max_size, RAMBlock *qemu_ram_alloc_from_ptr(ram_addr_t size, void *host, MemoryRegion *mr, Error **errp) { - return qemu_ram_alloc_internal(size, size, NULL, host, RAM_PREALLOC, m= r, - errp); + return qemu_ram_alloc_internal(size, size, host, RAM_PREALLOC, mr, err= p); } =20 RAMBlock *qemu_ram_alloc(ram_addr_t size, uint32_t ram_flags, @@ -2556,15 +2546,13 @@ RAMBlock *qemu_ram_alloc(ram_addr_t size, uint32_t = ram_flags, { assert((ram_flags & ~(RAM_SHARED | RAM_NORESERVE | RAM_GUEST_MEMFD | RAM_PRIVATE)) =3D=3D 0); - return qemu_ram_alloc_internal(size, size, NULL, NULL, ram_flags, mr, = errp); + return qemu_ram_alloc_internal(size, size, NULL, ram_flags, mr, errp); } =20 RAMBlock *qemu_ram_alloc_resizeable(ram_addr_t size, ram_addr_t maxsz, - qemu_ram_resize_cb resized, MemoryRegion *mr, Error **errp) { - return qemu_ram_alloc_internal(size, maxsz, resized, NULL, - RAM_RESIZEABLE, mr, errp); + return qemu_ram_alloc_internal(size, maxsz, NULL, RAM_RESIZEABLE, mr, = errp); } =20 static void reclaim_ramblock(RAMBlock *block) --=20 2.54.0 From nobody Sat Jul 4 21:12:58 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; 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=fail(p=reject dis=none) header.from=rsg.ci.i.u-tokyo.ac.jp Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1783056287941277.6020374320399; Thu, 2 Jul 2026 22:24:47 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wfWMZ-0005Vh-M5; Fri, 03 Jul 2026 01:22:55 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wfWMX-0005Tj-2r; Fri, 03 Jul 2026 01:22:53 -0400 Received: from www3579.sakura.ne.jp ([49.212.243.89]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wfWMS-0005s2-78; Fri, 03 Jul 2026 01:22:52 -0400 Received: from h183.csg.ci.i.u-tokyo.ac.jp (h183.csg.ci.i.u-tokyo.ac.jp [133.11.54.183]) (authenticated bits=0) by www3579.sakura.ne.jp (8.16.1/8.16.1) with ESMTPSA id 6635LT8R018373 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Fri, 3 Jul 2026 14:21:44 +0900 (JST) (envelope-from odaki@rsg.ci.i.u-tokyo.ac.jp) DKIM-Signature: a=rsa-sha256; bh=1XctemCKId3obTQH3ZovbZHJwhFnldkwzVWAd9daGoI=; c=relaxed/relaxed; d=rsg.ci.i.u-tokyo.ac.jp; h=From:Message-Id:To:Subject:Date; s=rs20250326; t=1783056105; v=1; b=lOmH1V74tPa8qWyAGMoaN8+qD3tmBei04vq78uHgb7l7b+WQ+3zM3PMIvHn8/TRa 8syfLjgTgpV3X4fDZTMtdlX9OB5m77mosQeHcbazz5H5/+uZA1YDmZFEbQVHkjoT gS++fCJokYCR2F1pYfmWCykRXaEyGYi22kvdR0vdcUD+0pvotWc3SdOBV6ynAMUf hUA0RO+9PpLiXohv0CPrbaolxXAACX433bsOBBF7iCX3l1BFjMscT7Gv/4JvSyU+ +vUSl/TznH+WSOYbj0ni1MZx+My0o0Q3xm2kKaN8uQ8fa3oW1wMwp2YDfDqc5BLP OzItrwUOnlAgGDW79VMvMA== From: Akihiko Odaki Date: Fri, 03 Jul 2026 14:19:20 +0900 Subject: [PATCH v2 4/7] system/physmem: Pass RAMBlock to RAMBlockNotifier callbacks MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260703-ram-v2-4-7f07fc06fba9@rsg.ci.i.u-tokyo.ac.jp> References: <20260703-ram-v2-0-7f07fc06fba9@rsg.ci.i.u-tokyo.ac.jp> In-Reply-To: <20260703-ram-v2-0-7f07fc06fba9@rsg.ci.i.u-tokyo.ac.jp> To: qemu-devel@nongnu.org Cc: Kevin Wolf , Hanna Reitz , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , Zhao Liu , Stefano Stabellini , Anthony PERARD , "Edgar E. Iglesias" , Peter Xu , Fabiano Rosas , Paolo Bonzini , Reinoud Zandijk , Marcelo Tosatti , Alex Williamson , =?utf-8?q?C=C3=A9dric_Le_Goater?= , qemu-block@nongnu.org, xen-devel@lists.xenproject.org, kvm@vger.kernel.org, Gerd Hoffmann , Mauro Carvalho Chehab , "Michael S. Tsirkin" , Igor Mammedov , Ani Sinha , Peter Maydell , Richard Henderson , Song Gao , Bibo Mao , Jiaxun Yang , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Sunil V L , Palmer Dabbelt , Alistair Francis , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Chao Liu , linux-edac@vger.kernel.org, qemu-arm@nongnu.org, qemu-riscv@nongnu.org, Akihiko Odaki X-Mailer: b4 0.16-dev-925f5 X-Developer-Signature: v=1; a=openpgp-sha256; l=13441; i=odaki@rsg.ci.i.u-tokyo.ac.jp; h=from:subject:message-id; bh=A4x2pli6Z2hhm28AnwmhhlYROeELntD3dbuFAdERfwE=; b=owGbwMvMwCWmMbc20y1CyJDxtFoSQ5a728PquWdc0iI3ML86sGPnrt/i77oNF3dtnRmyeOkGt j8adzq3dpSyMIhxMciKKbKkFO3m1oiu/VSYEN8CM4eVCWQIAxenAEykVpOR4clX5cu1D58ERBgI un5fvulmsmjCoyKZuqOtHPFG9ba81Qz/Q6IKL5zONHw0T2GLYPO+vfJbJ9We+fBmwZJ/T1Sbnix ZxAwA X-Developer-Key: i=odaki@rsg.ci.i.u-tokyo.ac.jp; a=openpgp; fpr=AEDC03C9AF734F2EC26A7BFFA4BAEAA73536753C 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=lists1p.gnu.org; Received-SPF: pass client-ip=49.212.243.89; envelope-from=odaki@rsg.ci.i.u-tokyo.ac.jp; helo=www3579.sakura.ne.jp X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_INVALID=0.1, DKIM_SIGNED=0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no 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-ZM-MESSAGEID: 1783056289484158500 The RAM save/restore code needs the RAMBlock in RAMBlockNotifier callbacks to decide whether migration must be aborted and to update RAMBlock state for postcopy. Looking up the RAMBlock inside callbacks is hazardous: with Xen mapcache it can deadlock, and it also leaves the callback contract unclear. Pass the RAMBlock explicitly to RAMBlockNotifier callbacks. The ram_block_resized callback takes a non-const RAMBlock because it may modify the RAMBlock, while the other callbacks take const RAMBlock. Xen mapcache passes NULL because mapcache entries do not have a one-to-one relationship with RAMBlocks. ram_block_resized() is never called from Xen mapcache, so its RAMBlock argument is always non-NULL. Drop redundant parameters from ram_block_resized() because they can be derived from the RAMBlock. Keep them for the other callbacks because their RAMBlock argument may be NULL. Signed-off-by: Akihiko Odaki --- include/system/ramlist.h | 18 ++++++++++-------- block/block-ram-registrar.c | 8 ++++---- hw/core/numa.c | 18 ++++++++++-------- hw/xen/xen-mapcache.c | 6 +++--- migration/ram.c | 12 +++--------- system/physmem.c | 7 +++---- target/i386/nvmm/nvmm-all.c | 4 ++-- target/i386/sev.c | 8 ++++---- util/vfio-helpers.c | 7 ++++--- 9 files changed, 43 insertions(+), 45 deletions(-) diff --git a/include/system/ramlist.h b/include/system/ramlist.h index c7f388f487d7..32157cc84305 100644 --- a/include/system/ramlist.h +++ b/include/system/ramlist.h @@ -62,11 +62,11 @@ void qemu_mutex_lock_ramlist(void); void qemu_mutex_unlock_ramlist(void); =20 struct RAMBlockNotifier { - void (*ram_block_added)(RAMBlockNotifier *n, void *host, size_t size, - size_t max_size); - void (*ram_block_removed)(RAMBlockNotifier *n, void *host, size_t size, - size_t max_size); - void (*ram_block_resized)(RAMBlockNotifier *n, void *host, size_t old_= size, + void (*ram_block_added)(RAMBlockNotifier *n, const RAMBlock *rb, + void *host, size_t size, size_t max_size); + void (*ram_block_removed)(RAMBlockNotifier *n, const RAMBlock *rb, + void *host, size_t size, size_t max_size); + void (*ram_block_resized)(RAMBlockNotifier *n, RAMBlock *rb, size_t new_size); QLIST_ENTRY(RAMBlockNotifier) next; }; @@ -77,9 +77,11 @@ int qemu_ram_foreach_block(RAMBlockIterFunc func, void *= opaque); =20 void ram_block_notifier_add(RAMBlockNotifier *n); void ram_block_notifier_remove(RAMBlockNotifier *n); -void ram_block_notify_add(void *host, size_t size, size_t max_size); -void ram_block_notify_remove(void *host, size_t size, size_t max_size); -void ram_block_notify_resize(void *host, size_t old_size, size_t new_size); +void ram_block_notify_add(const RAMBlock *rb, + void *host, size_t size, size_t max_size); +void ram_block_notify_remove(const RAMBlock *rb, + void *host, size_t size, size_t max_size); +void ram_block_notify_resize(RAMBlock *rb, size_t new_size); =20 GString *ram_block_format(void); =20 diff --git a/block/block-ram-registrar.c b/block/block-ram-registrar.c index fcda2b86afb2..5b938de22587 100644 --- a/block/block-ram-registrar.c +++ b/block/block-ram-registrar.c @@ -9,8 +9,8 @@ #include "system/block-ram-registrar.h" #include "qapi/error.h" =20 -static void ram_block_added(RAMBlockNotifier *n, void *host, size_t size, - size_t max_size) +static void ram_block_added(RAMBlockNotifier *n, const RAMBlock *rb, + void *host, size_t size, size_t max_size) { BlockRAMRegistrar *r =3D container_of(n, BlockRAMRegistrar, notifier); Error *err =3D NULL; @@ -26,8 +26,8 @@ static void ram_block_added(RAMBlockNotifier *n, void *ho= st, size_t size, } } =20 -static void ram_block_removed(RAMBlockNotifier *n, void *host, size_t size, - size_t max_size) +static void ram_block_removed(RAMBlockNotifier *n, const RAMBlock *rb, + void *host, size_t size, size_t max_size) { BlockRAMRegistrar *r =3D container_of(n, BlockRAMRegistrar, notifier); blk_unregister_buf(r->blk, host, max_size); diff --git a/hw/core/numa.c b/hw/core/numa.c index f462883c87cf..40acb98bdd0b 100644 --- a/hw/core/numa.c +++ b/hw/core/numa.c @@ -824,7 +824,7 @@ static int ram_block_notify_add_single(RAMBlock *rb, vo= id *opaque) RAMBlockNotifier *notifier =3D opaque; =20 if (host) { - notifier->ram_block_added(notifier, host, size, max_size); + notifier->ram_block_added(notifier, rb, host, size, max_size); } return 0; } @@ -837,7 +837,7 @@ static int ram_block_notify_remove_single(RAMBlock *rb,= void *opaque) RAMBlockNotifier *notifier =3D opaque; =20 if (host) { - notifier->ram_block_removed(notifier, host, size, max_size); + notifier->ram_block_removed(notifier, rb, host, size, max_size); } return 0; } @@ -861,38 +861,40 @@ void ram_block_notifier_remove(RAMBlockNotifier *n) } } =20 -void ram_block_notify_add(void *host, size_t size, size_t max_size) +void ram_block_notify_add(const RAMBlock *rb, + void *host, size_t size, size_t max_size) { RAMBlockNotifier *notifier; RAMBlockNotifier *next; =20 QLIST_FOREACH_SAFE(notifier, &ram_list.ramblock_notifiers, next, next)= { if (notifier->ram_block_added) { - notifier->ram_block_added(notifier, host, size, max_size); + notifier->ram_block_added(notifier, rb, host, size, max_size); } } } =20 -void ram_block_notify_remove(void *host, size_t size, size_t max_size) +void ram_block_notify_remove(const RAMBlock *rb, + void *host, size_t size, size_t max_size) { RAMBlockNotifier *notifier; RAMBlockNotifier *next; =20 QLIST_FOREACH_SAFE(notifier, &ram_list.ramblock_notifiers, next, next)= { if (notifier->ram_block_removed) { - notifier->ram_block_removed(notifier, host, size, max_size); + notifier->ram_block_removed(notifier, rb, host, size, max_size= ); } } } =20 -void ram_block_notify_resize(void *host, size_t old_size, size_t new_size) +void ram_block_notify_resize(RAMBlock *rb, size_t new_size) { RAMBlockNotifier *notifier; RAMBlockNotifier *next; =20 QLIST_FOREACH_SAFE(notifier, &ram_list.ramblock_notifiers, next, next)= { if (notifier->ram_block_resized) { - notifier->ram_block_resized(notifier, host, old_size, new_size= ); + notifier->ram_block_resized(notifier, rb, new_size); } } } diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c index 85cf0cf359ca..f321c65b630e 100644 --- a/hw/xen/xen-mapcache.c +++ b/hw/xen/xen-mapcache.c @@ -222,7 +222,7 @@ static void xen_remap_bucket(MapCache *mc, =20 if (entry->vaddr_base !=3D NULL) { if (!(entry->flags & XEN_MAPCACHE_ENTRY_DUMMY)) { - ram_block_notify_remove(entry->vaddr_base, entry->size, + ram_block_notify_remove(NULL, entry->vaddr_base, entry->size, entry->size); } =20 @@ -308,7 +308,7 @@ static void xen_remap_bucket(MapCache *mc, } =20 if (!(entry->flags & XEN_MAPCACHE_ENTRY_DUMMY)) { - ram_block_notify_add(vaddr_base, size, size); + ram_block_notify_add(NULL, vaddr_base, size, size); } =20 entry->vaddr_base =3D vaddr_base; @@ -601,7 +601,7 @@ static void xen_invalidate_map_cache_entry_unlocked(Map= Cache *mc, return; } =20 - ram_block_notify_remove(entry->vaddr_base, entry->size, entry->size); + ram_block_notify_remove(NULL, entry->vaddr_base, entry->size, entry->s= ize); if (entry->flags & XEN_MAPCACHE_ENTRY_GRANT) { rc =3D xengnttab_unmap(xen_region_gnttabdev, entry->vaddr_base, entry->size >> mc->bucket_shift); diff --git a/migration/ram.c b/migration/ram.c index fc38ffbf8af1..6bc7f705d31a 100644 --- a/migration/ram.c +++ b/migration/ram.c @@ -4699,18 +4699,12 @@ static SaveVMHandlers savevm_ram_handlers =3D { .save_postcopy_prepare =3D ram_save_postcopy_prepare, }; =20 -static void ram_mig_ram_block_resized(RAMBlockNotifier *n, void *host, - size_t old_size, size_t new_size) +static void ram_mig_ram_block_resized(RAMBlockNotifier *n, RAMBlock *rb, + size_t new_size) { PostcopyState ps =3D postcopy_state_get(); - ram_addr_t offset; - RAMBlock *rb =3D qemu_ram_block_from_host(host, false, &offset); Error *err =3D NULL; - - if (!rb) { - error_report("RAM block not found"); - return; - } + ram_addr_t old_size =3D qemu_ram_get_used_length(rb); =20 if (migrate_ram_is_ignored(rb)) { return; diff --git a/system/physmem.c b/system/physmem.c index 54fe820ce828..1427949b72cd 100644 --- a/system/physmem.c +++ b/system/physmem.c @@ -2019,7 +2019,6 @@ static int memory_try_enable_merging(void *addr, size= _t len) */ int qemu_ram_resize(RAMBlock *block, ram_addr_t newsize, Error **errp) { - const ram_addr_t oldsize =3D block->used_length; const ram_addr_t unaligned_size =3D newsize; =20 newsize =3D TARGET_PAGE_ALIGN(newsize); @@ -2054,7 +2053,7 @@ int qemu_ram_resize(RAMBlock *block, ram_addr_t newsi= ze, Error **errp) =20 /* Notify before modifying the ram block and touching the bitmaps. */ if (block->host) { - ram_block_notify_resize(block->host, oldsize, newsize); + ram_block_notify_resize(block, newsize); } =20 physical_memory_clear_dirty_range(block->offset, block->used_length); @@ -2277,7 +2276,7 @@ static void ram_block_add(RAMBlock *new_block, Error = **errp) qemu_madvise(new_block->host, new_block->max_length, QEMU_MADV_DONTFORK); } - ram_block_notify_add(new_block->host, new_block->used_length, + ram_block_notify_add(new_block, new_block->host, new_block->used_l= ength, new_block->max_length); } return; @@ -2588,7 +2587,7 @@ void qemu_ram_free(RAMBlock *block) } =20 if (block->host) { - ram_block_notify_remove(block->host, block->used_length, + ram_block_notify_remove(block, block->host, block->used_length, block->max_length); } =20 diff --git a/target/i386/nvmm/nvmm-all.c b/target/i386/nvmm/nvmm-all.c index 8a1af35ed32b..f29b9c504ea8 100644 --- a/target/i386/nvmm/nvmm-all.c +++ b/target/i386/nvmm/nvmm-all.c @@ -1134,8 +1134,8 @@ static MemoryListener nvmm_memory_listener =3D { }; =20 static void -nvmm_ram_block_added(RAMBlockNotifier *n, void *host, size_t size, - size_t max_size) +nvmm_ram_block_added(RAMBlockNotifier *n, const RAMBlock *rb, + void *host, size_t size, size_t max_size) { struct nvmm_machine *mach =3D get_nvmm_mach(); uintptr_t hva =3D (uintptr_t)host; diff --git a/target/i386/sev.c b/target/i386/sev.c index 99cf30806be7..55e74f1c8f9c 100644 --- a/target/i386/sev.c +++ b/target/i386/sev.c @@ -329,8 +329,8 @@ sev_set_guest_state(SevCommonState *sev_common, SevStat= e new_state) } =20 static void -sev_ram_block_added(RAMBlockNotifier *n, void *host, size_t size, - size_t max_size) +sev_ram_block_added(RAMBlockNotifier *n, const RAMBlock *rb, + void *host, size_t size, size_t max_size) { int r; struct kvm_enc_region range; @@ -359,8 +359,8 @@ sev_ram_block_added(RAMBlockNotifier *n, void *host, si= ze_t size, } =20 static void -sev_ram_block_removed(RAMBlockNotifier *n, void *host, size_t size, - size_t max_size) +sev_ram_block_removed(RAMBlockNotifier *n, const RAMBlock *rb, + void *host, size_t size, size_t max_size) { int r; struct kvm_enc_region range; diff --git a/util/vfio-helpers.c b/util/vfio-helpers.c index aab0bf9d485d..5059ed44b8af 100644 --- a/util/vfio-helpers.c +++ b/util/vfio-helpers.c @@ -465,8 +465,8 @@ fail_container: return ret; } =20 -static void qemu_vfio_ram_block_added(RAMBlockNotifier *n, void *host, - size_t size, size_t max_size) +static void qemu_vfio_ram_block_added(RAMBlockNotifier *n, const RAMBlock = *rb, + void *host, size_t size, size_t max_= size) { QEMUVFIOState *s =3D container_of(n, QEMUVFIOState, ram_notifier); Error *local_err =3D NULL; @@ -481,7 +481,8 @@ static void qemu_vfio_ram_block_added(RAMBlockNotifier = *n, void *host, } } =20 -static void qemu_vfio_ram_block_removed(RAMBlockNotifier *n, void *host, +static void qemu_vfio_ram_block_removed(RAMBlockNotifier *n, const RAMBloc= k *rb, + void *host, size_t size, size_t max_size) { QEMUVFIOState *s =3D container_of(n, QEMUVFIOState, ram_notifier); --=20 2.54.0 From nobody Sat Jul 4 21:12:58 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; 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=fail(p=reject dis=none) header.from=rsg.ci.i.u-tokyo.ac.jp Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1783056264607359.9697519631766; Thu, 2 Jul 2026 22:24:24 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wfWMh-0005c3-JR; Fri, 03 Jul 2026 01:23:03 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wfWMc-0005Xi-21; Fri, 03 Jul 2026 01:22:58 -0400 Received: from www3579.sakura.ne.jp ([49.212.243.89]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wfWMa-0005yH-47; Fri, 03 Jul 2026 01:22:57 -0400 Received: from h183.csg.ci.i.u-tokyo.ac.jp (h183.csg.ci.i.u-tokyo.ac.jp [133.11.54.183]) (authenticated bits=0) by www3579.sakura.ne.jp (8.16.1/8.16.1) with ESMTPSA id 6635LT8S018373 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Fri, 3 Jul 2026 14:21:45 +0900 (JST) (envelope-from odaki@rsg.ci.i.u-tokyo.ac.jp) DKIM-Signature: a=rsa-sha256; bh=WU1hr20De0lfszJxA0uPYsBXpl0cfWRc8y3s2m5DLyo=; c=relaxed/relaxed; d=rsg.ci.i.u-tokyo.ac.jp; h=From:Message-Id:To:Subject:Date; s=rs20250326; t=1783056105; v=1; b=gEgffcsnVdi4RhMOLhBBOniG1feoYZwJT9L5utV6OW+IZhP80LZjkYDeME0aTo3l 1W16YXUzbn5FUpKcST6EH+3m8+bykMSx5KwFS4+QPzJyIng2Szk/RVurI+V/lIC5 qkyvSM6hexvMZdwVTbBuiqurNIwrIhX2Srp8j0je94K3O/xub+Bl4hxOpPHfEYSM 1T/pl6z1nUPTVms6uMYKRsADoT7HwDZyomv04fuCLCZjUbeK/tj5Uv8mhZyXDeGn 9Bq3BUNw6y9YyrczlqYF/RZWSQayNsUBMdD1hXSff9mmKwL4gso7ZztRW9IW3mux skjYUOGS72p628LwPYl1kw== From: Akihiko Odaki Date: Fri, 03 Jul 2026 14:19:21 +0900 Subject: [PATCH v2 5/7] system/physmem: Notify RAMBlock migratable and idstr changes MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260703-ram-v2-5-7f07fc06fba9@rsg.ci.i.u-tokyo.ac.jp> References: <20260703-ram-v2-0-7f07fc06fba9@rsg.ci.i.u-tokyo.ac.jp> In-Reply-To: <20260703-ram-v2-0-7f07fc06fba9@rsg.ci.i.u-tokyo.ac.jp> To: qemu-devel@nongnu.org Cc: Kevin Wolf , Hanna Reitz , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , Zhao Liu , Stefano Stabellini , Anthony PERARD , "Edgar E. Iglesias" , Peter Xu , Fabiano Rosas , Paolo Bonzini , Reinoud Zandijk , Marcelo Tosatti , Alex Williamson , =?utf-8?q?C=C3=A9dric_Le_Goater?= , qemu-block@nongnu.org, xen-devel@lists.xenproject.org, kvm@vger.kernel.org, Gerd Hoffmann , Mauro Carvalho Chehab , "Michael S. Tsirkin" , Igor Mammedov , Ani Sinha , Peter Maydell , Richard Henderson , Song Gao , Bibo Mao , Jiaxun Yang , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Sunil V L , Palmer Dabbelt , Alistair Francis , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Chao Liu , linux-edac@vger.kernel.org, qemu-arm@nongnu.org, qemu-riscv@nongnu.org, Akihiko Odaki X-Mailer: b4 0.16-dev-925f5 X-Developer-Signature: v=1; a=openpgp-sha256; l=4261; i=odaki@rsg.ci.i.u-tokyo.ac.jp; h=from:subject:message-id; bh=Vv3pUHunatuIlFi+mPBDZxRdUfxT6q4pEQh1tsUM+Qo=; b=owGbwMvMwCWmMbc20y1CyJDxtFoSQ5a726ND9w/dXfQpO81K6NZK4facBVzav74u1818Y1XX4 lIfGVLQUcrCIMbFICumyJJStJtbI7r2U2FCfAvMHFYmkCEMXJwCMBEnDYb/6fOf2K58tvDttid3 V5/6czJNMrJ+bnzsu6Kt7qe/pNmc+MTI8OLW3dSjm0Qmrrf/suSZ5XzV5Uv2CSTeWhm8qPuW4OU dL5kB X-Developer-Key: i=odaki@rsg.ci.i.u-tokyo.ac.jp; a=openpgp; fpr=AEDC03C9AF734F2EC26A7BFFA4BAEAA73536753C 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=lists1p.gnu.org; Received-SPF: pass client-ip=49.212.243.89; envelope-from=odaki@rsg.ci.i.u-tokyo.ac.jp; helo=www3579.sakura.ne.jp X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_INVALID=0.1, DKIM_SIGNED=0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no 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-ZM-MESSAGEID: 1783056267368158500 The RAM migration code assumes that the set of migratable RAMBlocks and their idstr values do not change while migration is running. Add RAMBlockNotifier callbacks for RAM_MIGRATABLE flag and idstr changes so migration can detect attempts to make such changes at runtime and abort with a clear error. Signed-off-by: Akihiko Odaki --- include/system/ramlist.h | 6 ++++++ hw/core/numa.c | 36 ++++++++++++++++++++++++++++++++++++ system/physmem.c | 9 +++++++++ 3 files changed, 51 insertions(+) diff --git a/include/system/ramlist.h b/include/system/ramlist.h index 32157cc84305..e96de5573eed 100644 --- a/include/system/ramlist.h +++ b/include/system/ramlist.h @@ -66,6 +66,9 @@ struct RAMBlockNotifier { void *host, size_t size, size_t max_size); void (*ram_block_removed)(RAMBlockNotifier *n, const RAMBlock *rb, void *host, size_t size, size_t max_size); + void (*ram_block_set_migratable)(RAMBlockNotifier *n, const RAMBlock *= rb); + void (*ram_block_unset_migratable)(RAMBlockNotifier *n, const RAMBlock= *rb); + void (*ram_block_set_idstr)(RAMBlockNotifier *n, const RAMBlock *rb); void (*ram_block_resized)(RAMBlockNotifier *n, RAMBlock *rb, size_t new_size); QLIST_ENTRY(RAMBlockNotifier) next; @@ -81,6 +84,9 @@ void ram_block_notify_add(const RAMBlock *rb, void *host, size_t size, size_t max_size); void ram_block_notify_remove(const RAMBlock *rb, void *host, size_t size, size_t max_size); +void ram_block_notify_set_migratable(const RAMBlock *rb); +void ram_block_notify_unset_migratable(const RAMBlock *rb); +void ram_block_notify_set_idstr(const RAMBlock *rb); void ram_block_notify_resize(RAMBlock *rb, size_t new_size); =20 GString *ram_block_format(void); diff --git a/hw/core/numa.c b/hw/core/numa.c index 40acb98bdd0b..0685cd1c6ccc 100644 --- a/hw/core/numa.c +++ b/hw/core/numa.c @@ -887,6 +887,42 @@ void ram_block_notify_remove(const RAMBlock *rb, } } =20 +void ram_block_notify_set_migratable(const RAMBlock *rb) +{ + RAMBlockNotifier *notifier; + RAMBlockNotifier *next; + + QLIST_FOREACH_SAFE(notifier, &ram_list.ramblock_notifiers, next, next)= { + if (notifier->ram_block_set_migratable) { + notifier->ram_block_set_migratable(notifier, rb); + } + } +} + +void ram_block_notify_unset_migratable(const RAMBlock *rb) +{ + RAMBlockNotifier *notifier; + RAMBlockNotifier *next; + + QLIST_FOREACH_SAFE(notifier, &ram_list.ramblock_notifiers, next, next)= { + if (notifier->ram_block_unset_migratable) { + notifier->ram_block_unset_migratable(notifier, rb); + } + } +} + +void ram_block_notify_set_idstr(const RAMBlock *rb) +{ + RAMBlockNotifier *notifier; + RAMBlockNotifier *next; + + QLIST_FOREACH_SAFE(notifier, &ram_list.ramblock_notifiers, next, next)= { + if (notifier->ram_block_set_idstr) { + notifier->ram_block_set_idstr(notifier, rb); + } + } +} + void ram_block_notify_resize(RAMBlock *rb, size_t new_size) { RAMBlockNotifier *notifier; diff --git a/system/physmem.c b/system/physmem.c index 1427949b72cd..e8ec6a152af4 100644 --- a/system/physmem.c +++ b/system/physmem.c @@ -1911,11 +1911,17 @@ bool qemu_ram_is_migratable(const RAMBlock *rb) =20 void qemu_ram_set_migratable(RAMBlock *rb) { + /* Notify before modifying the ram block. */ + ram_block_notify_set_migratable(rb); + rb->flags |=3D RAM_MIGRATABLE; } =20 void qemu_ram_unset_migratable(RAMBlock *rb) { + /* Notify before modifying the ram block. */ + ram_block_notify_unset_migratable(rb); + rb->flags &=3D ~RAM_MIGRATABLE; } =20 @@ -1937,6 +1943,9 @@ void qemu_ram_set_idstr(RAMBlock *new_block, const ch= ar *name, DeviceState *dev) assert(new_block); assert(!new_block->idstr[0]); =20 + /* Notify before modifying the ram block. */ + ram_block_notify_set_idstr(new_block); + if (dev) { char *id =3D qdev_get_dev_path(dev); if (id) { --=20 2.54.0 From nobody Sat Jul 4 21:12:58 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; 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=fail(p=reject dis=none) header.from=rsg.ci.i.u-tokyo.ac.jp Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 17830562656691019.5959624119686; Thu, 2 Jul 2026 22:24:25 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wfWMc-0005Xo-AR; Fri, 03 Jul 2026 01:22:58 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wfWMY-0005VI-G2; Fri, 03 Jul 2026 01:22:54 -0400 Received: from www3579.sakura.ne.jp ([49.212.243.89]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wfWMW-0005w9-LJ; Fri, 03 Jul 2026 01:22:54 -0400 Received: from h183.csg.ci.i.u-tokyo.ac.jp (h183.csg.ci.i.u-tokyo.ac.jp [133.11.54.183]) (authenticated bits=0) by www3579.sakura.ne.jp (8.16.1/8.16.1) with ESMTPSA id 6635LT8T018373 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Fri, 3 Jul 2026 14:21:45 +0900 (JST) (envelope-from odaki@rsg.ci.i.u-tokyo.ac.jp) DKIM-Signature: a=rsa-sha256; bh=6SxS8nVg3xnGkGVZhxJ3G3DZU8jRBJGr+RtAwqpbPdU=; c=relaxed/relaxed; d=rsg.ci.i.u-tokyo.ac.jp; h=From:Message-Id:To:Subject:Date; s=rs20250326; t=1783056106; v=1; b=QgYN2xsCcD3xLna//lkUa8qytMBfIhKXr/m/42WJSe23dJFVmFc8yRSPhU5iHenl OZo6Vl9ITdMn+SLCFkupO4MY+6oQg9Sc+S0X+8aLSXo7WIg1kHpXhlL2Yn2aOZfy J2zWXQsg9T7VQmRg9umr+me0rHqZD634DFtCKEzEJC/Ay3/lp+gOBphyJ2UTlY8F J/WMZcB5vh7ReK9I2StGrBSGxpXdNQRufr2y3gfv80If2ATSAD/9pC9f6QzyjXiD g9wjXkQXuVaCnS4h3iqzXu843CfMCjL5FURg/d0yNvmc8z06Ey+Az1PSbDIt89b8 cOfEwrXXkc073eh77wa3Hw== From: Akihiko Odaki Date: Fri, 03 Jul 2026 14:19:22 +0900 Subject: [PATCH v2 6/7] migration/ram: Fix ram_save_complete() return value MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260703-ram-v2-6-7f07fc06fba9@rsg.ci.i.u-tokyo.ac.jp> References: <20260703-ram-v2-0-7f07fc06fba9@rsg.ci.i.u-tokyo.ac.jp> In-Reply-To: <20260703-ram-v2-0-7f07fc06fba9@rsg.ci.i.u-tokyo.ac.jp> To: qemu-devel@nongnu.org Cc: Kevin Wolf , Hanna Reitz , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , Zhao Liu , Stefano Stabellini , Anthony PERARD , "Edgar E. Iglesias" , Peter Xu , Fabiano Rosas , Paolo Bonzini , Reinoud Zandijk , Marcelo Tosatti , Alex Williamson , =?utf-8?q?C=C3=A9dric_Le_Goater?= , qemu-block@nongnu.org, xen-devel@lists.xenproject.org, kvm@vger.kernel.org, Gerd Hoffmann , Mauro Carvalho Chehab , "Michael S. Tsirkin" , Igor Mammedov , Ani Sinha , Peter Maydell , Richard Henderson , Song Gao , Bibo Mao , Jiaxun Yang , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Sunil V L , Palmer Dabbelt , Alistair Francis , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Chao Liu , linux-edac@vger.kernel.org, qemu-arm@nongnu.org, qemu-riscv@nongnu.org, Akihiko Odaki X-Mailer: b4 0.16-dev-925f5 X-Developer-Signature: v=1; a=openpgp-sha256; l=813; i=odaki@rsg.ci.i.u-tokyo.ac.jp; h=from:subject:message-id; bh=/MegIW1B5Ph/z9o6j3vpknjkTxLfDtRU9G3pSaGuRSs=; b=owGbwMvMwCWmMbc20y1CyJDxtFoSQ5a72+M7k1Jrb37eu8tUIZdTP/fDhrsTP61dfWWHw81ej daUOadjOkpZGMS4GGTFFFlSinZza0TXfipMiG+BmcPKBDKEgYtTACbyWIGRYb35lvigt8rvKyvE 9bymzzeZZbXGY4aDYdXFyOD70p3r2xn+6cSvM9obe2Pl/b7mtusfv7tx/UrJSzz61v/wL9mbbfb WLAA= X-Developer-Key: i=odaki@rsg.ci.i.u-tokyo.ac.jp; a=openpgp; fpr=AEDC03C9AF734F2EC26A7BFFA4BAEAA73536753C 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=lists1p.gnu.org; Received-SPF: pass client-ip=49.212.243.89; envelope-from=odaki@rsg.ci.i.u-tokyo.ac.jp; helo=www3579.sakura.ne.jp X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_INVALID=0.1, DKIM_SIGNED=0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no 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-ZM-MESSAGEID: 1783056267301158500 ram_save_complete() and qemu_file_get_error_obj() are documented to return negative values on error, but ram_save_complete() inverts the sign of qemu_file_get_error_obj()'s return value. Remove the sign inversion. Signed-off-by: Akihiko Odaki --- migration/ram.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/migration/ram.c b/migration/ram.c index 6bc7f705d31a..e1c191ec4383 100644 --- a/migration/ram.c +++ b/migration/ram.c @@ -3431,7 +3431,7 @@ static int ram_save_complete(QEMUFile *f, void *opaqu= e) int err =3D qemu_file_get_error_obj(f, &local_err); =20 error_reportf_err(local_err, "Failed to write bitmap to file: = "); - return -err; + return err; } } =20 --=20 2.54.0 From nobody Sat Jul 4 21:12:58 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; 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=fail(p=reject dis=none) header.from=rsg.ci.i.u-tokyo.ac.jp Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1783056264482856.7553397329998; Thu, 2 Jul 2026 22:24:24 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wfWMb-0005XE-T8; Fri, 03 Jul 2026 01:22:57 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wfWMW-0005TL-La; Fri, 03 Jul 2026 01:22:53 -0400 Received: from www3579.sakura.ne.jp ([49.212.243.89]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wfWMS-0005rz-4H; Fri, 03 Jul 2026 01:22:52 -0400 Received: from h183.csg.ci.i.u-tokyo.ac.jp (h183.csg.ci.i.u-tokyo.ac.jp [133.11.54.183]) (authenticated bits=0) by www3579.sakura.ne.jp (8.16.1/8.16.1) with ESMTPSA id 6635LT8U018373 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Fri, 3 Jul 2026 14:21:46 +0900 (JST) (envelope-from odaki@rsg.ci.i.u-tokyo.ac.jp) DKIM-Signature: a=rsa-sha256; bh=5vN8LLN1cwVkJSeHOFH42uOAevgNgauoNhfEjaG1Qa4=; c=relaxed/relaxed; d=rsg.ci.i.u-tokyo.ac.jp; h=From:Message-Id:To:Subject:Date; s=rs20250326; t=1783056106; v=1; b=BsX3PEyPKdeLkzVfmBzo06LGKElOOo4+ah4cn6ElKvQv6pS3I84i72LCh2Ygd+Q+ KDaWQ2m+tZvx46uoqZBXBA4+Vty4ktd2u9uauB1cfyhLfLoaBEnOYKKv9+yWx+p6 3i0Eas/wc80ZCw251oDLMWVlgt/Vx1XwCf/TOiXxicyTTNmn2pAT8fE1RMmaLcWX 3p8uy0kElZYeIjYLDbBDv0L+dDdmMW/+7Omnq9KGsCivqBGdFhH0wzbn5P+3pBFL RS7JDgp5oZl6wxwExWswamp7PU2OUWFfa3kxg/WDgcGq16bt+dUCBvBCdocCqspz XyyALYQIlcPWHOF0OvmrhQ== From: Akihiko Odaki Date: Fri, 03 Jul 2026 14:19:23 +0900 Subject: [PATCH v2 7/7] migration/ram: Assert RAMBlock stability while streaming RAM MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260703-ram-v2-7-7f07fc06fba9@rsg.ci.i.u-tokyo.ac.jp> References: <20260703-ram-v2-0-7f07fc06fba9@rsg.ci.i.u-tokyo.ac.jp> In-Reply-To: <20260703-ram-v2-0-7f07fc06fba9@rsg.ci.i.u-tokyo.ac.jp> To: qemu-devel@nongnu.org Cc: Kevin Wolf , Hanna Reitz , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , Zhao Liu , Stefano Stabellini , Anthony PERARD , "Edgar E. Iglesias" , Peter Xu , Fabiano Rosas , Paolo Bonzini , Reinoud Zandijk , Marcelo Tosatti , Alex Williamson , =?utf-8?q?C=C3=A9dric_Le_Goater?= , qemu-block@nongnu.org, xen-devel@lists.xenproject.org, kvm@vger.kernel.org, Gerd Hoffmann , Mauro Carvalho Chehab , "Michael S. Tsirkin" , Igor Mammedov , Ani Sinha , Peter Maydell , Richard Henderson , Song Gao , Bibo Mao , Jiaxun Yang , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Sunil V L , Palmer Dabbelt , Alistair Francis , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Chao Liu , linux-edac@vger.kernel.org, qemu-arm@nongnu.org, qemu-riscv@nongnu.org, Akihiko Odaki X-Mailer: b4 0.16-dev-925f5 X-Developer-Signature: v=1; a=openpgp-sha256; l=9631; i=odaki@rsg.ci.i.u-tokyo.ac.jp; h=from:subject:message-id; bh=6rxiBJMURMDjjavfjxxSoOmIDh11hItlYvDbOT13ApM=; b=owGbwMvMwCWmMbc20y1CyJDxtFoSQ5a725OdNgt3n132cuXK3IPcvbM95i8M/lib9V949hfxi 2+e9s7o6yhlYRDjYpAVU2RJKdrNrRFd+6kwIb4FZg4rE8gQBi5OAZiImCsjw8KbEy5yn/oeJTav meUWYw37tlkyRrvuyUSd/21sWsMbI8Dw35fBlYORNSrL/VeSf4bcXpujDyZKxTxJe8zvt3/93Qk neAE= X-Developer-Key: i=odaki@rsg.ci.i.u-tokyo.ac.jp; a=openpgp; fpr=AEDC03C9AF734F2EC26A7BFFA4BAEAA73536753C 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=lists1p.gnu.org; Received-SPF: pass client-ip=49.212.243.89; envelope-from=odaki@rsg.ci.i.u-tokyo.ac.jp; helo=www3579.sakura.ne.jp X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_INVALID=0.1, DKIM_SIGNED=0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no 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-ZM-MESSAGEID: 1783056267420158500 RAM migration sends the RAMBlock list and sizes before transferring page contents. The RAM code cannot cope with migratable RAMBlocks being added, removed, renamed, made migratable/non-migratable, or resized while that stream is active, because the destination has already parsed the stream layout. Add RAMBlock notifier checks so such changes are caught immediately. Ignored RAMBlocks remain exempt because they are not represented in the RAM migration stream. Signed-off-by: Akihiko Odaki --- include/migration/misc.h | 2 +- migration/ram.c | 94 ++++++++++++++++++++++++++++++++++----------= ---- 2 files changed, 68 insertions(+), 28 deletions(-) diff --git a/include/migration/misc.h b/include/migration/misc.h index 3159a5e53c3c..91015524a83d 100644 --- a/include/migration/misc.h +++ b/include/migration/misc.h @@ -40,7 +40,7 @@ void precopy_remove_notifier(NotifierWithReturn *n); int precopy_notify(PrecopyNotifyReason reason, Error **errp); =20 void qemu_guest_free_page_hint(void *addr, size_t len); -bool migrate_ram_is_ignored(RAMBlock *block); +bool migrate_ram_is_ignored(const RAMBlock *block); =20 /* migration/block.c */ =20 diff --git a/migration/ram.c b/migration/ram.c index e1c191ec4383..3cfc1461f13e 100644 --- a/migration/ram.c +++ b/migration/ram.c @@ -224,7 +224,7 @@ static bool postcopy_preempt_active(void) return migrate_postcopy_preempt() && migration_in_postcopy(); } =20 -bool migrate_ram_is_ignored(RAMBlock *block) +bool migrate_ram_is_ignored(const RAMBlock *block) { MigMode mode =3D migrate_mode(); return !qemu_ram_is_migratable(block) || @@ -364,6 +364,12 @@ struct RAMSrcPageRequest { QSIMPLEQ_ENTRY(RAMSrcPageRequest) next_req; }; =20 +typedef enum RAMStateStage { + RAM_STATE_STAGE_ITERATING, + RAM_STATE_STAGE_COMPLETING, + RAM_STATE_STAGE_COMPLETED, +} RAMStateStage; + /* State of RAM for migration */ struct RAMState { /* @@ -398,8 +404,8 @@ struct RAMState { uint64_t xbzrle_bytes_prev; /* Are we really using XBZRLE (e.g., after the first round). */ bool xbzrle_started; - /* Are we on the last stage of migration */ - bool last_stage; + /* Migration stage */ + RAMStateStage stage; =20 /* total handled target pages at the beginning of period */ uint64_t target_page_count_prev; @@ -635,7 +641,7 @@ static int save_xbzrle_page(RAMState *rs, PageSearchSta= tus *pss, =20 if (!cache_is_cached(XBZRLE.cache, current_addr, generation)) { xbzrle_counters.cache_miss++; - if (!rs->last_stage) { + if (rs->stage =3D=3D RAM_STATE_STAGE_ITERATING) { if (cache_insert(XBZRLE.cache, current_addr, *current_data, generation) =3D=3D -1) { return -1; @@ -674,7 +680,7 @@ static int save_xbzrle_page(RAMState *rs, PageSearchSta= tus *pss, * Update the cache contents, so that it corresponds to the data * sent, in all cases except where we skip the page. */ - if (!rs->last_stage && encoded_len !=3D 0) { + if (rs->stage =3D=3D RAM_STATE_STAGE_ITERATING && encoded_len !=3D 0) { memcpy(prev_cached_page, XBZRLE.current_buf, TARGET_PAGE_SIZE); /* * In the case where we couldn't compress, ensure that the caller @@ -840,7 +846,8 @@ static inline bool migration_bitmap_clear_dirty(RAMStat= e *rs, * * Do the same for postcopy due to the same reason. */ - if (!rs->last_stage && !migration_in_postcopy()) { + if (rs->stage =3D=3D RAM_STATE_STAGE_ITERATING && + !migration_in_postcopy()) { /* * Clear dirty bitmap if needed. This _must_ be called before we * send any of the page in the chunk because we need to make sure @@ -1316,7 +1323,7 @@ static int ram_save_page(RAMState *rs, PageSearchStat= us *pss) if (rs->xbzrle_started && !migration_in_postcopy()) { pages =3D save_xbzrle_page(rs, pss, &p, current_addr, block, offset); - if (!rs->last_stage) { + if (rs->stage =3D=3D RAM_STATE_STAGE_ITERATING) { /* Can't send this cached data async, since the cache page * might get updated before it gets to the wire */ @@ -2920,6 +2927,8 @@ static void ram_state_resume_prepare(RAMState *rs, QE= MUFile *out) RAMBlock *block; uint64_t pages =3D 0; =20 + rs->stage =3D RAM_STATE_STAGE_ITERATING; + /* * Postcopy is not using xbzrle/compression, so no need for that. * Also, since source are already halted, we don't need to care @@ -3373,7 +3382,9 @@ static int ram_save_complete(QEMUFile *f, void *opaqu= e) =20 trace_ram_save_complete(rs->migration_dirty_pages, 0); =20 - rs->last_stage =3D !migration_in_colo_state(); + if (!migration_in_colo_state()) { + rs->stage =3D RAM_STATE_STAGE_COMPLETING; + } =20 WITH_RCU_READ_LOCK_GUARD() { if (!migration_in_postcopy()) { @@ -3383,7 +3394,7 @@ static int ram_save_complete(QEMUFile *f, void *opaqu= e) ret =3D rdma_registration_start(f, RAM_CONTROL_FINISH); if (ret < 0) { qemu_file_set_error(f, ret); - return ret; + goto err; } =20 /* try transferring iterative blocks of memory */ @@ -3400,7 +3411,8 @@ static int ram_save_complete(QEMUFile *f, void *opaqu= e) } if (pages < 0) { qemu_mutex_unlock(&rs->bitmap_mutex); - return pages; + ret =3D pages; + goto err; } } qemu_mutex_unlock(&rs->bitmap_mutex); @@ -3408,7 +3420,7 @@ static int ram_save_complete(QEMUFile *f, void *opaqu= e) ret =3D rdma_registration_stop(f, RAM_CONTROL_FINISH); if (ret < 0) { qemu_file_set_error(f, ret); - return ret; + goto err; } } =20 @@ -3419,7 +3431,7 @@ static int ram_save_complete(QEMUFile *f, void *opaqu= e) */ ret =3D multifd_ram_flush_and_sync(f); if (ret < 0) { - return ret; + goto err; } } =20 @@ -3428,10 +3440,10 @@ static int ram_save_complete(QEMUFile *f, void *opa= que) =20 if (qemu_file_get_error(f)) { Error *local_err =3D NULL; - int err =3D qemu_file_get_error_obj(f, &local_err); + ret =3D qemu_file_get_error_obj(f, &local_err); =20 error_reportf_err(local_err, "Failed to write bitmap to file: = "); - return err; + goto err; } } =20 @@ -3439,7 +3451,14 @@ static int ram_save_complete(QEMUFile *f, void *opaq= ue) =20 trace_ram_save_complete(rs->migration_dirty_pages, 1); =20 - return qemu_fflush(f); + ret =3D qemu_fflush(f); + +err: + if (!migration_in_colo_state()) { + rs->stage =3D RAM_STATE_STAGE_COMPLETED; + } + + return ret; } =20 static void ram_state_pending(void *opaque, MigPendingData *pending, @@ -4699,28 +4718,45 @@ static SaveVMHandlers savevm_ram_handlers =3D { .save_postcopy_prepare =3D ram_save_postcopy_prepare, }; =20 +static bool ram_migration_is_running(void) +{ + return ram_state && ram_state->stage !=3D RAM_STATE_STAGE_COMPLETED; +} + +static void ram_mig_ram_block_set_migratable(RAMBlockNotifier *n, + const RAMBlock *rb) +{ + assert(!ram_migration_is_running()); +} + +static void ram_mig_ram_block_unset_migratable(RAMBlockNotifier *n, + const RAMBlock *rb) +{ + assert(!ram_migration_is_running()); +} + +static void ram_mig_ram_block_set_idstr(RAMBlockNotifier *n, const RAMBloc= k *rb) +{ + assert(!ram_migration_is_running() || migrate_ram_is_ignored(rb)); +} + +static void ram_mig_ram_block_removed(RAMBlockNotifier *n, const RAMBlock = *rb, + void *host, size_t size, size_t max_= size) +{ + assert(!rb || !ram_migration_is_running() || migrate_ram_is_ignored(rb= )); +} + static void ram_mig_ram_block_resized(RAMBlockNotifier *n, RAMBlock *rb, size_t new_size) { PostcopyState ps =3D postcopy_state_get(); - Error *err =3D NULL; ram_addr_t old_size =3D qemu_ram_get_used_length(rb); =20 if (migrate_ram_is_ignored(rb)) { return; } =20 - if (migration_is_running()) { - /* - * Precopy code on the source cannot deal with the size of RAM blo= cks - * changing at random points in time - especially after sending the - * RAM block sizes in the migration stream, they must no longer ch= ange. - * Abort and indicate a proper reason. - */ - error_setg(&err, "RAM block '%s' resized during precopy.", rb->ids= tr); - migrate_error_propagate(migrate_get_current(), err); - migration_cancel(); - } + assert(!ram_migration_is_running()); =20 switch (ps) { case POSTCOPY_INCOMING_ADVISE: @@ -4754,6 +4790,10 @@ static void ram_mig_ram_block_resized(RAMBlockNotifi= er *n, RAMBlock *rb, } =20 static RAMBlockNotifier ram_mig_ram_notifier =3D { + .ram_block_removed =3D ram_mig_ram_block_removed, + .ram_block_set_migratable =3D ram_mig_ram_block_set_migratable, + .ram_block_unset_migratable =3D ram_mig_ram_block_unset_migratable, + .ram_block_set_idstr =3D ram_mig_ram_block_set_idstr, .ram_block_resized =3D ram_mig_ram_block_resized, }; =20 --=20 2.54.0