From nobody Sat Sep 6 17:34:03 2025 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 lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 175712502557573.64973616071336; Fri, 5 Sep 2025 19:17:05 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uuiRn-0003yI-75; Fri, 05 Sep 2025 22:14:35 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uuiRb-0003wD-PP; Fri, 05 Sep 2025 22:14:23 -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 1uuiRO-0006Q8-EU; Fri, 05 Sep 2025 22:14:22 -0400 Received: from [10.40.4.92] (93-51-222-138.ip268.fastwebnet.it [93.51.222.138]) (authenticated bits=0) by www3579.sakura.ne.jp (8.16.1/8.16.1) with ESMTPSA id 5862BtnY041566 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Sat, 6 Sep 2025 11:12:42 +0900 (JST) (envelope-from odaki@rsg.ci.i.u-tokyo.ac.jp) DKIM-Signature: a=rsa-sha256; bh=py43IqlzE5vFeWpPuIxLuLFKrIYuMLr2zAmltTreJ00=; c=relaxed/relaxed; d=rsg.ci.i.u-tokyo.ac.jp; h=From:Date:Subject:Message-Id:To; s=rs20250326; t=1757124775; v=1; b=VbJCYqxH2/eRo37csaPkOpuuaaq8F0hQg7WkRM2yL7VfoyshlhNa2jyE818GZYTH 31xIxOUYS6gV3Z3CRO70xop0foGngyuEmLi80vpYM+Vs1GyQJECbXjFjzuCEXjx8 y/SEmaN31/GB4u3kDYDh7XbsDk29oOvJzWPEnbkNwmyNAYD4gVqjXEx7tDwEtxlt gYIYWeGmTqYnXuu+0cgEgcinm26jB9fEdenIcGAVXW31xTi3rmbfc34KlvpVDsjk U2fyVssXUSL0yDUmHywl4FW/LHy7PpdbOKR/5okrbZp3Ic1YKhFYisQQVu5jSnN7 vVuqgk9TDGBrIawqnlBfuA== From: Akihiko Odaki Date: Sat, 06 Sep 2025 04:11:12 +0200 Subject: [PATCH 03/22] hw/pci-bridge: Do not assume immediate MemoryRegion finalization MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250906-use-v1-3-c51caafd1eb7@rsg.ci.i.u-tokyo.ac.jp> References: <20250906-use-v1-0-c51caafd1eb7@rsg.ci.i.u-tokyo.ac.jp> In-Reply-To: <20250906-use-v1-0-c51caafd1eb7@rsg.ci.i.u-tokyo.ac.jp> To: qemu-devel@nongnu.org Cc: Alex Williamson , =?utf-8?q?C=C3=A9dric_Le_Goater?= , Paolo Bonzini , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , Eduardo Habkost , Peter Xu , David Hildenbrand , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , Richard Henderson , Helge Deller , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , "Michael S. Tsirkin" , Gerd Hoffmann , John Snow , qemu-block@nongnu.org, Keith Busch , Klaus Jensen , Jesper Devantier , Marcel Apfelbaum , Nicholas Piggin , qemu-ppc@nongnu.org, John Levon , Thanos Makatos , Yanan Wang , BALATON Zoltan , Jiaxun Yang , Daniel Henrique Barboza , David Gibson , Harsh Prateek Bora , Alexey Kardashevskiy , =?utf-8?q?Alex_Benn=C3=A9e?= , Fabiano Rosas , Thomas Huth , Laurent Vivier , Peter Maydell , Aurelien Jarno , Aleksandar Rikalo , Max Filippov , =?utf-8?q?Herv=C3=A9_Poussineau?= , Mark Cave-Ayland , Artyom Tarasenko , Akihiko Odaki X-Mailer: b4 0.14.2 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=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, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, 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: 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: 1757125030698124100 When updating memory mappings, pci_bridge_update_mappings() performed the following operations: 1. Start a transaction 2. Delete the subregions from the container 3. Unparent the subregions 4. Initialize the subregions 5. End the transaction This assumes the old subregion instances are finalized immediately after 3, but it is not true; the finalization is delayed until 5. Remove the assumption by using functions to dynamically update MemoryRegions. Signed-off-by: Akihiko Odaki --- include/hw/pci/pci.h | 1 + hw/pci/pci.c | 2 +- hw/pci/pci_bridge.c | 96 ++++++++++++++++++++++++++++--------------------= ---- 3 files changed, 54 insertions(+), 45 deletions(-) diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index 6b7d3ac8a3611d00d1c1c949c260f3dd44d36cc4..d0bd214b4e11eccc085f7ebe421= d170f37552ac3 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -256,6 +256,7 @@ void pci_register_bar(PCIDevice *pci_dev, int region_nu= m, uint8_t attr, MemoryRegion *memory); void pci_register_vga(PCIDevice *pci_dev, MemoryRegion *mem, MemoryRegion *io_lo, MemoryRegion *io_hi); +void pci_update_vga(PCIDevice *pci_dev); void pci_unregister_vga(PCIDevice *pci_dev); pcibus_t pci_get_bar_addr(PCIDevice *pci_dev, int region_num); =20 diff --git a/hw/pci/pci.c b/hw/pci/pci.c index c70b5ceebaf1f2b10768bd030526cbb518da2b8d..516029f66cda6705bded15322cb= 6f7eb3d42f82c 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -1521,7 +1521,7 @@ void pci_register_bar(PCIDevice *pci_dev, int region_= num, } } =20 -static void pci_update_vga(PCIDevice *pci_dev) +void pci_update_vga(PCIDevice *pci_dev) { uint16_t cmd; =20 diff --git a/hw/pci/pci_bridge.c b/hw/pci/pci_bridge.c index 76255c4cd8929cf9f350af4be1a8448791d52afa..240d0f904de9771f81a392ad26b= e6ba38a41e4f6 100644 --- a/hw/pci/pci_bridge.c +++ b/hw/pci/pci_bridge.c @@ -145,11 +145,10 @@ pcibus_t pci_bridge_get_limit(const PCIDevice *bridge= , uint8_t type) return limit; } =20 -static void pci_bridge_init_alias(PCIBridge *bridge, MemoryRegion *alias, - uint8_t type, const char *name, - MemoryRegion *space, - MemoryRegion *parent_space, - bool enabled) +static void pci_bridge_update_alias(PCIBridge *bridge, bool init, + MemoryRegion *alias, uint8_t type, + const char *name, MemoryRegion *space, + MemoryRegion *parent_space, bool enabl= ed) { PCIDevice *bridge_dev =3D PCI_DEVICE(bridge); pcibus_t base =3D pci_bridge_get_base(bridge_dev, type); @@ -158,25 +157,37 @@ static void pci_bridge_init_alias(PCIBridge *bridge, = MemoryRegion *alias, * Apparently no way to do this with existing memory APIs. */ pcibus_t size =3D enabled && limit >=3D base ? limit + 1 - base : 0; =20 - memory_region_init_alias(alias, OBJECT(bridge), name, space, base, siz= e); + if (init) { + memory_region_init_alias(alias, OBJECT(bridge), name, space, base,= size); + } else { + memory_region_set_size(alias, size); + memory_region_set_alias_offset(alias, base); + } + memory_region_add_subregion_overlap(parent_space, base, alias, 1); } =20 -static void pci_bridge_init_vga_aliases(PCIBridge *br, PCIBus *parent, - MemoryRegion *alias_vga) +static void pci_bridge_update_vga_aliases(PCIBridge *br, bool init, + PCIBus *parent, + MemoryRegion *alias_vga) { PCIDevice *pd =3D PCI_DEVICE(br); uint16_t brctl =3D pci_get_word(pd->config + PCI_BRIDGE_CONTROL); =20 - memory_region_init_alias(&alias_vga[QEMU_PCI_VGA_IO_LO], OBJECT(br), - "pci_bridge_vga_io_lo", &br->address_space_io, - QEMU_PCI_VGA_IO_LO_BASE, QEMU_PCI_VGA_IO_LO_S= IZE); - memory_region_init_alias(&alias_vga[QEMU_PCI_VGA_IO_HI], OBJECT(br), - "pci_bridge_vga_io_hi", &br->address_space_io, - QEMU_PCI_VGA_IO_HI_BASE, QEMU_PCI_VGA_IO_HI_S= IZE); - memory_region_init_alias(&alias_vga[QEMU_PCI_VGA_MEM], OBJECT(br), - "pci_bridge_vga_mem", &br->address_space_mem, - QEMU_PCI_VGA_MEM_BASE, QEMU_PCI_VGA_MEM_SIZE); + if (init) { + memory_region_init_alias(&alias_vga[QEMU_PCI_VGA_IO_LO], OBJECT(br= ), + "pci_bridge_vga_io_lo", &br->address_spac= e_io, + QEMU_PCI_VGA_IO_LO_BASE, + QEMU_PCI_VGA_IO_LO_SIZE); + memory_region_init_alias(&alias_vga[QEMU_PCI_VGA_IO_HI], OBJECT(br= ), + "pci_bridge_vga_io_hi", &br->address_spac= e_io, + QEMU_PCI_VGA_IO_HI_BASE, + QEMU_PCI_VGA_IO_HI_SIZE); + memory_region_init_alias(&alias_vga[QEMU_PCI_VGA_MEM], OBJECT(br), + "pci_bridge_vga_mem", &br->address_space_= mem, + QEMU_PCI_VGA_MEM_BASE, + QEMU_PCI_VGA_MEM_SIZE); + } =20 if (brctl & PCI_BRIDGE_CTL_VGA) { pci_register_vga(pd, &alias_vga[QEMU_PCI_VGA_MEM], @@ -185,33 +196,33 @@ static void pci_bridge_init_vga_aliases(PCIBridge *br= , PCIBus *parent, } } =20 -static void pci_bridge_region_init(PCIBridge *br) +static void pci_bridge_region_update(PCIBridge *br, bool init) { PCIDevice *pd =3D PCI_DEVICE(br); PCIBus *parent =3D pci_get_bus(pd); PCIBridgeWindows *w =3D &br->windows; uint16_t cmd =3D pci_get_word(pd->config + PCI_COMMAND); =20 - pci_bridge_init_alias(br, &w->alias_pref_mem, - PCI_BASE_ADDRESS_MEM_PREFETCH, - "pci_bridge_pref_mem", - &br->address_space_mem, - parent->address_space_mem, - cmd & PCI_COMMAND_MEMORY); - pci_bridge_init_alias(br, &w->alias_mem, - PCI_BASE_ADDRESS_SPACE_MEMORY, - "pci_bridge_mem", - &br->address_space_mem, - parent->address_space_mem, - cmd & PCI_COMMAND_MEMORY); - pci_bridge_init_alias(br, &w->alias_io, - PCI_BASE_ADDRESS_SPACE_IO, - "pci_bridge_io", - &br->address_space_io, - parent->address_space_io, - cmd & PCI_COMMAND_IO); - - pci_bridge_init_vga_aliases(br, parent, w->alias_vga); + pci_bridge_update_alias(br, init, &w->alias_pref_mem, + PCI_BASE_ADDRESS_MEM_PREFETCH, + "pci_bridge_pref_mem", + &br->address_space_mem, + parent->address_space_mem, + cmd & PCI_COMMAND_MEMORY); + pci_bridge_update_alias(br, init, &w->alias_mem, + PCI_BASE_ADDRESS_SPACE_MEMORY, + "pci_bridge_mem", + &br->address_space_mem, + parent->address_space_mem, + cmd & PCI_COMMAND_MEMORY); + pci_bridge_update_alias(br, init, &w->alias_io, + PCI_BASE_ADDRESS_SPACE_IO, + "pci_bridge_io", + &br->address_space_io, + parent->address_space_io, + cmd & PCI_COMMAND_IO); + + pci_bridge_update_vga_aliases(br, init, parent, w->alias_vga); } =20 static void pci_bridge_region_del(PCIBridge *br, PCIBridgeWindows *w) @@ -237,14 +248,11 @@ static void pci_bridge_region_cleanup(PCIBridge *br, = PCIBridgeWindows *w) =20 void pci_bridge_update_mappings(PCIBridge *br) { - PCIBridgeWindows *w =3D &br->windows; - /* Make updates atomic to: handle the case of one VCPU updating the br= idge * while another accesses an unaffected region. */ memory_region_transaction_begin(); - pci_bridge_region_del(br, w); - pci_bridge_region_cleanup(br, w); - pci_bridge_region_init(br); + pci_bridge_region_del(br, &br->windows); + pci_bridge_region_update(br, false); memory_region_transaction_commit(); } =20 @@ -386,7 +394,7 @@ void pci_bridge_initfn(PCIDevice *dev, const char *type= name) memory_region_init(&br->address_space_io, OBJECT(br), "pci_bridge_io", 4 * GiB); address_space_init(&br->as_io, &br->address_space_io, "pci_bridge_pci_= io"); - pci_bridge_region_init(br); + pci_bridge_region_update(br, true); QLIST_INIT(&sec_bus->child); QLIST_INSERT_HEAD(&parent->child, sec_bus, sibling); =20 --=20 2.51.0