[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 05/15] spapr_pci: add PHB unrealize
From: |
Greg Kurz |
Subject: |
[Qemu-devel] [PATCH 05/15] spapr_pci: add PHB unrealize |
Date: |
Fri, 21 Dec 2018 01:36:12 +0100 |
User-agent: |
StGit/unknown-version |
From: Michael Roth <address@hidden>
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.
Signed-off-by: Michael Roth <address@hidden>
Signed-off-by: Greg Kurz <address@hidden>
---
hw/ppc/spapr_pci.c | 56 +++++++++++++++++++++++++++++++++++++++++--
include/hw/pci-host/spapr.h | 4 +++
2 files changed, 58 insertions(+), 2 deletions(-)
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 46d7062dd143..b772b72d6a48 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -1551,6 +1551,57 @@ static void spapr_pci_unplug_request(HotplugHandler
*plug_handler,
}
}
+static void spapr_phb_finalizefn(Object *obj)
+{
+ sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(obj);
+
+ g_free(sphb->dtbusname);
+ sphb->dtbusname = NULL;
+}
+
+static void spapr_phb_unrealize(DeviceState *dev, Error **errp)
+{
+ sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
+ SysBusDevice *s = SYS_BUS_DEVICE(dev);
+ PCIHostState *phb = PCI_HOST_BRIDGE(s);
+ sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(phb);
+ sPAPRTCETable *tcet;
+ int i;
+ const unsigned windows_supported = spapr_phb_windows_supported(sphb);
+
+ g_hash_table_unref(sphb->msi);
+
+ /*
+ * Remove IO/MMIO subregions and aliases, rest should get cleaned
+ * via PHB's unrealize->object_finalize
+ */
+ for (i = windows_supported - 1; i >= 0; i--) {
+ tcet = spapr_tce_find_by_liobn(sphb->dma_liobn[i]);
+ assert(tcet);
+ memory_region_del_subregion(&sphb->iommu_root,
+ spapr_tce_get_iommu(tcet));
+ }
+
+ for (i = PCI_NUM_PINS - 1; i >= 0; i--) {
+ spapr_irq_free(spapr, sphb->lsi_table[i].irq, 1);
+ }
+
+ 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 != (hwaddr)-1) {
+ memory_region_del_subregion(get_system_memory(), &sphb->mem64window);
+ }
+ 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
@@ -1568,8 +1619,7 @@ static void spapr_phb_realize(DeviceState *dev, Error
**errp)
PCIBus *bus;
uint64_t msi_window_size = 4096;
sPAPRTCETable *tcet;
- const unsigned windows_supported =
- sphb->ddw_enabled ? SPAPR_PCI_DMA_MAX_WINDOWS : 1;
+ const unsigned windows_supported = spapr_phb_windows_supported(sphb);
Object *drcs[PCI_SLOT_MAX * 8];
if (!spapr) {
@@ -1988,6 +2038,7 @@ static void spapr_phb_class_init(ObjectClass *klass, void
*data)
hc->root_bus_path = spapr_phb_root_bus_path;
dc->realize = spapr_phb_realize;
+ dc->unrealize = spapr_phb_unrealize;
dc->props = spapr_phb_properties;
dc->reset = spapr_phb_reset;
dc->vmsd = &vmstate_spapr_pci;
@@ -2002,6 +2053,7 @@ static const TypeInfo spapr_phb_info = {
.name = TYPE_SPAPR_PCI_HOST_BRIDGE,
.parent = TYPE_PCI_HOST_BRIDGE,
.instance_size = sizeof(sPAPRPHBState),
+ .instance_finalize = spapr_phb_finalizefn,
.class_init = spapr_phb_class_init,
.interfaces = (InterfaceInfo[]) {
{ TYPE_HOTPLUG_HANDLER },
diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h
index a65cfef16945..9d2ec1a410e8 100644
--- a/include/hw/pci-host/spapr.h
+++ b/include/hw/pci-host/spapr.h
@@ -162,4 +162,8 @@ static inline void spapr_phb_vfio_reset(DeviceState *qdev)
void spapr_phb_dma_reset(sPAPRPHBState *sphb);
+static inline unsigned spapr_phb_windows_supported(sPAPRPHBState *sphb)
+{
+ return sphb->ddw_enabled ? SPAPR_PCI_DMA_MAX_WINDOWS : 1;
+}
#endif /* PCI_HOST_SPAPR_H */
- [Qemu-devel] [PATCH 00/15] spapr: Add support for PHB hotplug, Greg Kurz, 2018/12/20
- [Qemu-devel] [PATCH 01/15] ppc/spapr: Receive and store device tree blob from SLOF, Greg Kurz, 2018/12/20
- [Qemu-devel] [PATCH 02/15] spapr: move spapr_create_phb() to core machine code, Greg Kurz, 2018/12/20
- [Qemu-devel] [PATCH 03/15] pci: allow cleanup/unregistration of PCI root buses, Greg Kurz, 2018/12/20
- [Qemu-devel] [PATCH 04/15] spapr_pci: add proper rollback on PHB realize error path, Greg Kurz, 2018/12/20
- [Qemu-devel] [PATCH 05/15] spapr_pci: add PHB unrealize,
Greg Kurz <=
- [Qemu-devel] [PATCH 06/15] spapr: enable PHB hotplug for default pseries machine type, Greg Kurz, 2018/12/20
- [Qemu-devel] [PATCH 07/15] spapr_pci: Define SPAPR_MAX_PHBS in hw/pci-host/spapr.h, Greg Kurz, 2018/12/20
- [Qemu-devel] [PATCH 08/15] spapr: create DR connectors for PHBs, Greg Kurz, 2018/12/20
- [Qemu-devel] [PATCH 09/15] spapr: populate PHB DRC entries for root DT node, Greg Kurz, 2018/12/20
- [Qemu-devel] [PATCH 10/15] spapr_events: add support for phb hotplug events, Greg Kurz, 2018/12/20
- [Qemu-devel] [PATCH 11/15] qdev: pass an Object * to qbus_set_hotplug_handler(), Greg Kurz, 2018/12/20
- [Qemu-devel] [PATCH 12/15] spapr_pci: provide node start offset via spapr_populate_pci_dt(), Greg Kurz, 2018/12/20
- [Qemu-devel] [PATCH 13/15] spapr_pci: add ibm, my-drc-index property for PHB hotplug, Greg Kurz, 2018/12/20