[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-ppc] [PATCH 04/15] spapr_pci: add proper rollback on PHB realize e
From: |
Greg Kurz |
Subject: |
[Qemu-ppc] [PATCH 04/15] spapr_pci: add proper rollback on PHB realize error path |
Date: |
Fri, 21 Dec 2018 01:35:52 +0100 |
User-agent: |
StGit/unknown-version |
The current realize code assumes the PHB is coldplugged, ie, QEMU will
terminate if an error is detected, and does not bother to free anything
it has already allocated.
In order to support PHB hotplug, let's first ensure spapr_phb_realize()
doesn't leak anything in case of error.
Signed-off-by: Greg Kurz <address@hidden>
---
hw/ppc/spapr_pci.c | 40 +++++++++++++++++++++++++++++++++++-----
1 file changed, 35 insertions(+), 5 deletions(-)
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index e59adbe706bb..46d7062dd143 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -1570,6 +1570,7 @@ static void spapr_phb_realize(DeviceState *dev, Error
**errp)
sPAPRTCETable *tcet;
const unsigned windows_supported =
sphb->ddw_enabled ? SPAPR_PCI_DMA_MAX_WINDOWS : 1;
+ Object *drcs[PCI_SLOT_MAX * 8];
if (!spapr) {
error_setg(errp, TYPE_SPAPR_PCI_HOST_BRIDGE " needs a pseries
machine");
@@ -1733,7 +1734,10 @@ static void spapr_phb_realize(DeviceState *dev, Error
**errp)
spapr_irq_claim(spapr, irq, true, &local_err);
if (local_err) {
error_propagate_prepend(errp, local_err, "can't allocate LSIs: ");
- return;
+ while (--i >= 0) {
+ spapr_irq_free(spapr, sphb->lsi_table[i].irq, 1);
+ }
+ goto fail_del_msiwindow;
}
sphb->lsi_table[i].irq = irq;
@@ -1741,9 +1745,10 @@ static void spapr_phb_realize(DeviceState *dev, Error
**errp)
/* allocate connectors for child PCI devices */
if (sphb->dr_enabled) {
- for (i = 0; i < PCI_SLOT_MAX * 8; i++) {
- spapr_dr_connector_new(OBJECT(phb), TYPE_SPAPR_DRC_PCI,
- (sphb->index << 16) | i);
+ for (i = 0; i < ARRAY_SIZE(drcs); i++) {
+ drcs[i] =
+ OBJECT(spapr_dr_connector_new(OBJECT(phb), TYPE_SPAPR_DRC_PCI,
+ (sphb->index << 16) | i));
}
}
@@ -1753,13 +1758,38 @@ static void spapr_phb_realize(DeviceState *dev, Error
**errp)
if (!tcet) {
error_setg(errp, "Creating window#%d failed for %s",
i, sphb->dtbusname);
- return;
+ while (--i >= 0) {
+ tcet = spapr_tce_find_by_liobn(sphb->dma_liobn[i]);
+ assert(tcet);
+ memory_region_del_subregion(&sphb->iommu_root,
+ spapr_tce_get_iommu(tcet));
+ object_unparent(OBJECT(tcet));
+ }
+ goto fail_free_drcs;
}
memory_region_add_subregion(&sphb->iommu_root, 0,
spapr_tce_get_iommu(tcet));
}
sphb->msi = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, g_free);
+ return;
+
+fail_free_drcs:
+ if (sphb->dr_enabled) {
+ for (i = 0; i < ARRAY_SIZE(drcs); i++) {
+ object_unparent(drcs[i]);
+ }
+ }
+fail_del_msiwindow:
+ 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 != (hwaddr)-1) {
+ memory_region_del_subregion(get_system_memory(), &sphb->mem64window);
+ }
+ memory_region_del_subregion(get_system_memory(), &sphb->mem32window);
}
static int spapr_phb_children_reset(Object *child, void *opaque)
- [Qemu-ppc] [PATCH 00/15] spapr: Add support for PHB hotplug, Greg Kurz, 2018/12/20
- [Qemu-ppc] [PATCH 01/15] ppc/spapr: Receive and store device tree blob from SLOF, Greg Kurz, 2018/12/20
- [Qemu-ppc] [PATCH 02/15] spapr: move spapr_create_phb() to core machine code, Greg Kurz, 2018/12/20
- [Qemu-ppc] [PATCH 03/15] pci: allow cleanup/unregistration of PCI root buses, Greg Kurz, 2018/12/20
- [Qemu-ppc] [PATCH 04/15] spapr_pci: add proper rollback on PHB realize error path,
Greg Kurz <=
- [Qemu-ppc] [PATCH 05/15] spapr_pci: add PHB unrealize, Greg Kurz, 2018/12/20
- [Qemu-ppc] [PATCH 06/15] spapr: enable PHB hotplug for default pseries machine type, Greg Kurz, 2018/12/20
- [Qemu-ppc] [PATCH 07/15] spapr_pci: Define SPAPR_MAX_PHBS in hw/pci-host/spapr.h, Greg Kurz, 2018/12/20
- [Qemu-ppc] [PATCH 08/15] spapr: create DR connectors for PHBs, Greg Kurz, 2018/12/20
- [Qemu-ppc] [PATCH 09/15] spapr: populate PHB DRC entries for root DT node, Greg Kurz, 2018/12/20
- [Qemu-ppc] [PATCH 10/15] spapr_events: add support for phb hotplug events, Greg Kurz, 2018/12/20
- [Qemu-ppc] [PATCH 11/15] qdev: pass an Object * to qbus_set_hotplug_handler(), Greg Kurz, 2018/12/20
- [Qemu-ppc] [PATCH 12/15] spapr_pci: provide node start offset via spapr_populate_pci_dt(), Greg Kurz, 2018/12/20