From nobody Sat Nov 8 07:38:24 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.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; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1549996513097151.02075690383242; Tue, 12 Feb 2019 10:35:13 -0800 (PST) Received: from localhost ([127.0.0.1]:44088 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtctc-0000l5-CU for importer@patchew.org; Tue, 12 Feb 2019 13:35:04 -0500 Received: from eggs.gnu.org ([209.51.188.92]:38694) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtcjq-0001GM-QG for qemu-devel@nongnu.org; Tue, 12 Feb 2019 13:25:00 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gtcjl-0003iK-4w for qemu-devel@nongnu.org; Tue, 12 Feb 2019 13:24:58 -0500 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:51546 helo=mx0a-001b2d01.pphosted.com) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gtcjk-0003WH-OX for qemu-devel@nongnu.org; Tue, 12 Feb 2019 13:24:52 -0500 Received: from pps.filterd (m0098416.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x1CILG6Q054597 for ; Tue, 12 Feb 2019 13:24:43 -0500 Received: from e06smtp03.uk.ibm.com (e06smtp03.uk.ibm.com [195.75.94.99]) by mx0b-001b2d01.pphosted.com with ESMTP id 2qm3bf83dg-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Tue, 12 Feb 2019 13:24:43 -0500 Received: from localhost by e06smtp03.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 12 Feb 2019 18:24:41 -0000 Received: from b06cxnps3075.portsmouth.uk.ibm.com (9.149.109.195) by e06smtp03.uk.ibm.com (192.168.101.133) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Tue, 12 Feb 2019 18:24:35 -0000 Received: from d06av26.portsmouth.uk.ibm.com (d06av26.portsmouth.uk.ibm.com [9.149.105.62]) by b06cxnps3075.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id x1CIOYrg59113648 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 12 Feb 2019 18:24:34 GMT Received: from d06av26.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id A7559AE045; Tue, 12 Feb 2019 18:24:34 +0000 (GMT) Received: from d06av26.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 8A119AE055; Tue, 12 Feb 2019 18:24:34 +0000 (GMT) Received: from smtp.lab.toulouse-stg.fr.ibm.com (unknown [9.101.4.1]) by d06av26.portsmouth.uk.ibm.com (Postfix) with ESMTP; Tue, 12 Feb 2019 18:24:34 +0000 (GMT) Received: from bahia.lan (sig-9-145-185-96.de.ibm.com [9.145.185.96]) by smtp.lab.toulouse-stg.fr.ibm.com (Postfix) with ESMTP id 5B151220182; Tue, 12 Feb 2019 19:24:33 +0100 (CET) From: Greg Kurz To: David Gibson Date: Tue, 12 Feb 2019 19:24:33 +0100 In-Reply-To: <154999583316.690774.15072605479770041782.stgit@bahia.lan> References: <154999583316.690774.15072605479770041782.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-TM-AS-GCONF: 00 x-cbid: 19021218-0012-0000-0000-000002F4E972 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 19021218-0013-0000-0000-0000212C5FAA Message-Id: <154999587292.690774.16487295114126456879.stgit@bahia.lan> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2019-02-12_09:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=8 phishscore=0 bulkscore=0 spamscore=0 clxscore=1034 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1902120129 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] [fuzzy] X-Received-From: 148.163.158.5 Subject: [Qemu-devel] [PATCH v4 06/15] spapr_pci: add PHB unrealize 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: Thomas Huth , Cornelia Huck , Gerd Hoffmann , Michael Roth , "Michael S. Tsirkin" , Alexey Kardashevskiy , David Hildenbrand , qemu-devel@nongnu.org, Greg Kurz , qemu-s390x@nongnu.org, Dmitry Fleytman , qemu-ppc@nongnu.org, =?utf-8?q?C=C3=A9dric?= Le Goater , Marcel Apfelbaum , Paolo Bonzini , Eduardo Habkost Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" To support PHB hotplug we need to clean up lingering references, memory, child properties, etc. prior to the PHB object being finalized. Generally this will be called as a result of calling object_unparent() on the PHB object, which in turn would normally be called as the result of an unplug() operation. When the PHB is finalized, child objects will be unparented in turn, and finalized if the PHB was the only reference holder. so we don't bother to explicitly unparent child objects of the PHB (spapr_iommu, spapr_drc, etc). The formula that gives the number of DMA windows is moved to an inline function in the hw/pci-host/spapr.h header because it will have other users. The unrealize function is able to cope with partially realized PHBs. It is hence used to implement proper rollback on the realize error path. Signed-off-by: Michael Roth Signed-off-by: Greg Kurz Reviewed-by: David Gibson --- v4: - reverted to v2 v3: - don't free LSIs at unrealize v2: - implement rollback with unrealize function --- hw/ppc/spapr_pci.c | 75 +++++++++++++++++++++++++++++++++++++++= ++-- include/hw/pci-host/spapr.h | 5 +++ 2 files changed, 76 insertions(+), 4 deletions(-) diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index d68595531d5a..e3781dd110b2 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -1565,6 +1565,64 @@ static void spapr_pci_unplug_request(HotplugHandler = *plug_handler, } } =20 +static void spapr_phb_finalizefn(Object *obj) +{ + sPAPRPHBState *sphb =3D SPAPR_PCI_HOST_BRIDGE(obj); + + g_free(sphb->dtbusname); + sphb->dtbusname =3D NULL; +} + +static void spapr_phb_unrealize(DeviceState *dev, Error **errp) +{ + sPAPRMachineState *spapr =3D SPAPR_MACHINE(qdev_get_machine()); + SysBusDevice *s =3D SYS_BUS_DEVICE(dev); + PCIHostState *phb =3D PCI_HOST_BRIDGE(s); + sPAPRPHBState *sphb =3D SPAPR_PCI_HOST_BRIDGE(phb); + sPAPRTCETable *tcet; + int i; + const unsigned windows_supported =3D spapr_phb_windows_supported(sphb); + + if (sphb->msi) { + g_hash_table_unref(sphb->msi); + sphb->msi =3D NULL; + } + + /* + * Remove IO/MMIO subregions and aliases, rest should get cleaned + * via PHB's unrealize->object_finalize + */ + for (i =3D windows_supported - 1; i >=3D 0; i--) { + tcet =3D spapr_tce_find_by_liobn(sphb->dma_liobn[i]); + if (tcet) { + memory_region_del_subregion(&sphb->iommu_root, + spapr_tce_get_iommu(tcet)); + } + } + + for (i =3D PCI_NUM_PINS - 1; i >=3D 0; i--) { + if (sphb->lsi_table[i].irq) { + spapr_irq_free(spapr, sphb->lsi_table[i].irq, 1); + sphb->lsi_table[i].irq =3D 0; + } + } + + QLIST_REMOVE(sphb, list); + + memory_region_del_subregion(&sphb->iommu_root, &sphb->msiwindow); + + address_space_destroy(&sphb->iommu_as); + + qbus_set_hotplug_handler(BUS(phb->bus), NULL, &error_abort); + pci_unregister_root_bus(phb->bus); + + memory_region_del_subregion(get_system_memory(), &sphb->iowindow); + if (sphb->mem64_win_pciaddr !=3D (hwaddr)-1) { + memory_region_del_subregion(get_system_memory(), &sphb->mem64windo= w); + } + memory_region_del_subregion(get_system_memory(), &sphb->mem32window); +} + static void spapr_phb_realize(DeviceState *dev, Error **errp) { /* We don't use SPAPR_MACHINE() in order to exit gracefully if the user @@ -1582,8 +1640,7 @@ static void spapr_phb_realize(DeviceState *dev, Error= **errp) PCIBus *bus; uint64_t msi_window_size =3D 4096; sPAPRTCETable *tcet; - const unsigned windows_supported =3D - sphb->ddw_enabled ? SPAPR_PCI_DMA_MAX_WINDOWS : 1; + const unsigned windows_supported =3D spapr_phb_windows_supported(sphb); =20 if (!spapr) { error_setg(errp, TYPE_SPAPR_PCI_HOST_BRIDGE " needs a pseries mach= ine"); @@ -1740,6 +1797,10 @@ static void spapr_phb_realize(DeviceState *dev, Erro= r **errp) if (local_err) { error_propagate_prepend(errp, local_err, "can't allocate LSIs: "); + /* + * Older machines will never support PHB hotplug, ie, this= is an + * init only path and QEMU will terminate. No need to roll= back. + */ return; } =20 @@ -1749,7 +1810,7 @@ static void spapr_phb_realize(DeviceState *dev, Error= **errp) spapr_irq_claim(spapr, irq, &local_err); if (local_err) { error_propagate_prepend(errp, local_err, "can't allocate LSIs:= "); - return; + goto unrealize; } =20 sphb->lsi_table[i].irq =3D irq; @@ -1769,13 +1830,17 @@ static void spapr_phb_realize(DeviceState *dev, Err= or **errp) if (!tcet) { error_setg(errp, "Creating window#%d failed for %s", i, sphb->dtbusname); - return; + goto unrealize; } memory_region_add_subregion(&sphb->iommu_root, 0, spapr_tce_get_iommu(tcet)); } =20 sphb->msi =3D g_hash_table_new_full(g_int_hash, g_int_equal, g_free, g= _free); + return; + +unrealize: + spapr_phb_unrealize(dev, NULL); } =20 static int spapr_phb_children_reset(Object *child, void *opaque) @@ -1974,6 +2039,7 @@ static void spapr_phb_class_init(ObjectClass *klass, = void *data) =20 hc->root_bus_path =3D spapr_phb_root_bus_path; dc->realize =3D spapr_phb_realize; + dc->unrealize =3D spapr_phb_unrealize; dc->props =3D spapr_phb_properties; dc->reset =3D spapr_phb_reset; dc->vmsd =3D &vmstate_spapr_pci; @@ -1989,6 +2055,7 @@ static const TypeInfo spapr_phb_info =3D { .name =3D TYPE_SPAPR_PCI_HOST_BRIDGE, .parent =3D TYPE_PCI_HOST_BRIDGE, .instance_size =3D sizeof(sPAPRPHBState), + .instance_finalize =3D spapr_phb_finalizefn, .class_init =3D spapr_phb_class_init, .interfaces =3D (InterfaceInfo[]) { { TYPE_HOTPLUG_HANDLER }, diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h index 51d81c4b7ce8..7cfce54a9449 100644 --- a/include/hw/pci-host/spapr.h +++ b/include/hw/pci-host/spapr.h @@ -163,4 +163,9 @@ static inline void spapr_phb_vfio_reset(DeviceState *qd= ev) =20 void spapr_phb_dma_reset(sPAPRPHBState *sphb); =20 +static inline unsigned spapr_phb_windows_supported(sPAPRPHBState *sphb) +{ + return sphb->ddw_enabled ? SPAPR_PCI_DMA_MAX_WINDOWS : 1; +} + #endif /* PCI_HOST_SPAPR_H */