[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-ppc] [PULL 42/49] spapr_pci: Unregister listeners before destroyin
From: |
David Gibson |
Subject: |
[Qemu-ppc] [PULL 42/49] spapr_pci: Unregister listeners before destroying the IOMMU address space |
Date: |
Tue, 2 Jul 2019 16:08:50 +1000 |
From: Greg Kurz <address@hidden>
Hot-unplugging a PHB with a VFIO device connected to it crashes QEMU:
-device spapr-pci-host-bridge,index=1,id=phb1 \
-device vfio-pci,host=0034:01:00.3,id=vfio0
(qemu) device_del phb1
[ 357.207183] iommu: Removing device 0001:00:00.0 from group 1
[ 360.375523] rpadlpar_io: slot PHB 1 removed
qemu-system-ppc64: memory.c:2742:
do_address_space_destroy: Assertion `QTAILQ_EMPTY(&as->listeners)' failed.
'as' is the IOMMU address space, which indeed has a listener registered
to by vfio_connect_container() when the VFIO device is realized. This
listener is supposed to be unregistered by vfio_disconnect_container()
when the VFIO device is finalized. Unfortunately, the VFIO device hasn't
reached finalize yet at the time the PHB unrealize function is called,
and address_space_destroy() gets called with the VFIO listener still
being registered.
All regions have just been unmapped from the address space. Listeners
aren't needed anymore at this point. Remove them before destroying the
address space.
The VFIO code will try to remove them _again_ at device finalize,
but it is okay since memory_listener_unregister() is idempotent.
Signed-off-by: Greg Kurz <address@hidden>
Message-Id: <address@hidden>
Reviewed-by: Alexey Kardashevskiy <address@hidden>
[dwg: Correct spelling error pointed out by aik]
Signed-off-by: David Gibson <address@hidden>
---
hw/ppc/spapr_pci.c | 6 ++++++
include/exec/memory.h | 10 ++++++++++
memory.c | 7 +++++++
3 files changed, 23 insertions(+)
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 5591723bb2..9003fe9010 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -1788,6 +1788,12 @@ static void spapr_phb_unrealize(DeviceState *dev, Error
**errp)
memory_region_del_subregion(&sphb->iommu_root, &sphb->msiwindow);
+ /*
+ * An attached PCI device may have memory listeners, eg. VFIO PCI. We have
+ * unmapped all sections. Remove the listeners now, before destroying the
+ * address space.
+ */
+ address_space_remove_listeners(&sphb->iommu_as);
address_space_destroy(&sphb->iommu_as);
qbus_set_hotplug_handler(BUS(phb->bus), NULL, &error_abort);
diff --git a/include/exec/memory.h b/include/exec/memory.h
index e6140e8a04..2c5cdffa31 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -1757,6 +1757,16 @@ void address_space_init(AddressSpace *as, MemoryRegion
*root, const char *name);
*/
void address_space_destroy(AddressSpace *as);
+/**
+ * address_space_remove_listeners: unregister all listeners of an address space
+ *
+ * Removes all callbacks previously registered with memory_listener_register()
+ * for @as.
+ *
+ * @as: an initialized #AddressSpace
+ */
+void address_space_remove_listeners(AddressSpace *as);
+
/**
* address_space_rw: read from or write to an address space.
*
diff --git a/memory.c b/memory.c
index 0a089a73ae..480f3d989b 100644
--- a/memory.c
+++ b/memory.c
@@ -2723,6 +2723,13 @@ void memory_listener_unregister(MemoryListener *listener)
listener->address_space = NULL;
}
+void address_space_remove_listeners(AddressSpace *as)
+{
+ while (!QTAILQ_EMPTY(&as->listeners)) {
+ memory_listener_unregister(QTAILQ_FIRST(&as->listeners));
+ }
+}
+
void address_space_init(AddressSpace *as, MemoryRegion *root, const char *name)
{
memory_region_ref(root);
--
2.21.0
- [Qemu-ppc] [PULL 12/49] target/ppc: remove getVSR()/putVSR() from fpu_helper.c, (continued)
- [Qemu-ppc] [PULL 12/49] target/ppc: remove getVSR()/putVSR() from fpu_helper.c, David Gibson, 2019/07/02
- [Qemu-ppc] [PULL 43/49] spapr/xive: rework the mapping the KVM memory regions, David Gibson, 2019/07/02
- [Qemu-ppc] [PULL 13/49] target/ppc: remove getVSR()/putVSR() from mem_helper.c, David Gibson, 2019/07/02
- [Qemu-ppc] [PULL 25/49] xics/kvm: Add error propagation to ic*_set_kvm_state() functions, David Gibson, 2019/07/02
- [Qemu-ppc] [PULL 22/49] xics/spapr: Rename xics_kvm_init(), David Gibson, 2019/07/02
- [Qemu-ppc] [PULL 11/49] xics: Add comment about CPU hotplug, David Gibson, 2019/07/02
- [Qemu-ppc] [PULL 20/49] hw/ppc: Drop useless CONFIG_KVM ifdefery, David Gibson, 2019/07/02
- [Qemu-ppc] [PULL 38/49] target/ppc: introduce GEN_VSX_HELPER_R2_AB macro to fpu_helper.c, David Gibson, 2019/07/02
- [Qemu-ppc] [PULL 24/49] xics/kvm: Always use local_err in xics_kvm_init(), David Gibson, 2019/07/02
- [Qemu-ppc] [PULL 41/49] target/ppc: improve VSX_FMADD with new GEN_VSX_HELPER_VSX_MADD macro, David Gibson, 2019/07/02
- [Qemu-ppc] [PULL 42/49] spapr_pci: Unregister listeners before destroying the IOMMU address space,
David Gibson <=
- [Qemu-ppc] [PULL 23/49] xics/kvm: Skip rollback when KVM XICS is absent, David Gibson, 2019/07/02
- [Qemu-ppc] [PULL 21/49] xics/spapr: Drop unused function declaration, David Gibson, 2019/07/02
- [Qemu-ppc] [PULL 27/49] ppc: Introduce kvmppc_set_reg_tb_offset() helper, David Gibson, 2019/07/02
- [Qemu-ppc] [PULL 26/49] xics/kvm: Add proper rollback to xics_kvm_init(), David Gibson, 2019/07/02
- [Qemu-ppc] [PULL 19/49] hw/ppc/prep: Drop useless CONFIG_KVM ifdefery, David Gibson, 2019/07/02
- [Qemu-ppc] [PULL 34/49] target/ppc: introduce GEN_VSX_HELPER_X2_AB macro to fpu_helper.c, David Gibson, 2019/07/02
- [Qemu-ppc] [PULL 35/49] target/ppc: introduce GEN_VSX_HELPER_X1 macro to fpu_helper.c, David Gibson, 2019/07/02
- [Qemu-ppc] [PULL 37/49] target/ppc: introduce GEN_VSX_HELPER_R2 macro to fpu_helper.c, David Gibson, 2019/07/02
- [Qemu-ppc] [PULL 45/49] ppc/xive: Force the Physical CAM line value to group mode, David Gibson, 2019/07/02
- [Qemu-ppc] [PULL 44/49] spapr/xive: simplify spapr_irq_init_device() to remove the emulated init, David Gibson, 2019/07/02