From nobody Fri Nov 7 04:09:25 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1545352948133542.0225857198178; Thu, 20 Dec 2018 16:42:28 -0800 (PST) Received: from localhost ([::1]:41693 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ga8tW-0001o1-HY for importer@patchew.org; Thu, 20 Dec 2018 19:42:26 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:59306) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ga8nA-0004xy-Fr for qemu-devel@nongnu.org; Thu, 20 Dec 2018 19:35:53 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ga8n6-0005CF-Vl for qemu-devel@nongnu.org; Thu, 20 Dec 2018 19:35:52 -0500 Received: from 9.mo6.mail-out.ovh.net ([87.98.171.146]:50397) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ga8n6-00059p-PM for qemu-devel@nongnu.org; Thu, 20 Dec 2018 19:35:48 -0500 Received: from player695.ha.ovh.net (unknown [10.109.160.54]) by mo6.mail-out.ovh.net (Postfix) with ESMTP id 580D519FF27 for ; Fri, 21 Dec 2018 01:35:47 +0100 (CET) Received: from kaod.org (lns-bzn-46-82-253-208-248.adsl.proxad.net [82.253.208.248]) (Authenticated sender: groug@kaod.org) by player695.ha.ovh.net (Postfix) with ESMTPSA id E5A52F16757; Fri, 21 Dec 2018 00:35:30 +0000 (UTC) From: Greg Kurz To: qemu-devel@nongnu.org Date: Fri, 21 Dec 2018 01:35:30 +0100 Message-ID: <154535253055.862554.10471167343589360987.stgit@bahia.lan> In-Reply-To: <154535246529.862554.6113740443866753456.stgit@bahia.lan> References: <154535246529.862554.6113740443866753456.stgit@bahia.lan> User-Agent: StGit/unknown-version MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Ovh-Tracer-Id: 3846637034106034626 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtkedrudejgedgvdduucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecuhedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 87.98.171.146 Subject: [Qemu-devel] [PATCH 03/15] pci: allow cleanup/unregistration of PCI root buses X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Cornelia Huck , Gerd Hoffmann , Eduardo Habkost , "Michael S. Tsirkin" , Alexey Kardashevskiy , David Hildenbrand , Michael Roth , qemu-s390x@nongnu.org, Dmitry Fleytman , qemu-ppc@nongnu.org, =?utf-8?q?C=C3=A9dric?= Le Goater , Marcel Apfelbaum , Paolo Bonzini , David Gibson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" From: Michael Roth This adds cleanup counterparts to pci_register_root_bus(), pci_root_bus_new(), and pci_bus_irqs(). These cleanup routines are needed in the case of hotpluggable PCIHostBridge implementations. Currently we can rely on the object_unparent()'ing of the PCIHostState recursively unparenting and cleaning up it's child buses, but we need explicit calls to also: 1) remove the PCIHostState from pci_host_bridges global list. otherwise, we risk accessing freed memory when we access the list later 2) clean up memory allocated in pci_bus_irqs() Both are handled outside the context of any particular bus or host bridge's init/realize functions, making it difficult to avoid the need for explicit cleanup functions without remodeling how PCIHostBridges are created. So keep it simple and just add them for now. Cc: Michael S. Tsirkin Cc: Paolo Bonzini Signed-off-by: Michael Roth Reviewed-by: David Gibson Signed-off-by: Greg Kurz Reviewed-by: Michael S. Tsirkin --- hw/pci/pci.c | 33 +++++++++++++++++++++++++++++++++ include/hw/pci/pci.h | 3 +++ 2 files changed, 36 insertions(+) diff --git a/hw/pci/pci.c b/hw/pci/pci.c index efb5ce196ffb..16354f91206c 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -333,6 +333,13 @@ static void pci_host_bus_register(DeviceState *host) QLIST_INSERT_HEAD(&pci_host_bridges, host_bridge, next); } =20 +static void pci_host_bus_unregister(DeviceState *host) +{ + PCIHostState *host_bridge =3D PCI_HOST_BRIDGE(host); + + QLIST_REMOVE(host_bridge, next); +} + PCIBus *pci_device_root_bus(const PCIDevice *d) { PCIBus *bus =3D pci_get_bus(d); @@ -379,6 +386,11 @@ static void pci_root_bus_init(PCIBus *bus, DeviceState= *parent, pci_host_bus_register(parent); } =20 +static void pci_bus_uninit(PCIBus *bus) +{ + pci_host_bus_unregister(BUS(bus)->parent); +} + bool pci_bus_is_express(PCIBus *bus) { return object_dynamic_cast(OBJECT(bus), TYPE_PCIE_BUS); @@ -413,6 +425,12 @@ PCIBus *pci_root_bus_new(DeviceState *parent, const ch= ar *name, return bus; } =20 +void pci_root_bus_cleanup(PCIBus *bus) +{ + pci_bus_uninit(bus); + object_unparent(OBJECT(bus)); +} + void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn map_= irq, void *irq_opaque, int nirq) { @@ -423,6 +441,15 @@ void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq,= pci_map_irq_fn map_irq, bus->irq_count =3D g_malloc0(nirq * sizeof(bus->irq_count[0])); } =20 +void pci_bus_irqs_cleanup(PCIBus *bus) +{ + bus->set_irq =3D NULL; + bus->map_irq =3D NULL; + bus->irq_opaque =3D NULL; + bus->nirq =3D 0; + g_free(bus->irq_count); +} + PCIBus *pci_register_root_bus(DeviceState *parent, const char *name, pci_set_irq_fn set_irq, pci_map_irq_fn map_i= rq, void *irq_opaque, @@ -439,6 +466,12 @@ PCIBus *pci_register_root_bus(DeviceState *parent, con= st char *name, return bus; } =20 +void pci_unregister_root_bus(PCIBus *bus) +{ + pci_bus_irqs_cleanup(bus); + pci_root_bus_cleanup(bus); +} + int pci_bus_num(PCIBus *s) { return PCI_BUS_GET_CLASS(s)->bus_num(s); diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index e6514bba23aa..8998e3be3390 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -405,8 +405,10 @@ PCIBus *pci_root_bus_new(DeviceState *parent, const ch= ar *name, MemoryRegion *address_space_mem, MemoryRegion *address_space_io, uint8_t devfn_min, const char *typename); +void pci_root_bus_cleanup(PCIBus *bus); void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn map_= irq, void *irq_opaque, int nirq); +void pci_bus_irqs_cleanup(PCIBus *bus); int pci_bus_get_irq_level(PCIBus *bus, int irq_num); /* 0 <=3D pin <=3D 3 0 =3D INTA, 1 =3D INTB, 2 =3D INTC, 3 =3D INTD */ int pci_swizzle_map_irq_fn(PCIDevice *pci_dev, int pin); @@ -417,6 +419,7 @@ PCIBus *pci_register_root_bus(DeviceState *parent, cons= t char *name, MemoryRegion *address_space_io, uint8_t devfn_min, int nirq, const char *typename); +void pci_unregister_root_bus(PCIBus *bus); void pci_bus_set_route_irq_fn(PCIBus *, pci_route_irq_fn); PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin); bool pci_intx_route_changed(PCIINTxRoute *old, PCIINTxRoute *new);