spapr_pci: Unregister listeners before destroying the IOMMU address space
commita2166410ad7434a6830288beb5858b22d5e35ec5
authorGreg Kurz <groug@kaod.org>
Fri, 21 Jun 2019 09:27:33 +0000 (21 11:27 +0200)
committerDavid Gibson <david@gibson.dropbear.id.au>
Mon, 1 Jul 2019 23:43:58 +0000 (2 09:43 +1000)
treed8a09bd42cc84389b83ce1284b0376d48b4c1075
parentc9f4e4d8b63259fdfba7b3a43a398c7acb90bf91
spapr_pci: Unregister listeners before destroying the IOMMU address space

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 <groug@kaod.org>
Message-Id: <156110925375.92514.11649846071216864570.stgit@bahia.lan>
Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru>
[dwg: Correct spelling error pointed out by aik]
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
hw/ppc/spapr_pci.c
include/exec/memory.h
memory.c