qemu-patch-raspberry4/hw
Paolo Bonzini 5942a19040 qdev: recursively unrealize devices when unrealizing bus
When the patch was posted that became 5c21ce7 (qdev: Realize buses
on device realization, 2014-03-12), it included recursive realization
and unrealization of devices when the bus's "realized" property
was toggled.

However, due to the same old worries about recursive realization
and prerequisites not being realized yet, those hunks were dropped when
committing the patch.  Unfortunately, this causes a use-after-free bug
(easily reproduced by a PCI hot-unplug action).

Before the patch, device_unparent behaved as follows:

   for each child bus
     unparent bus ----------------------------.
     | for each child device                  |
     |   unparent device ---------------.     |
     |   | unrealize device             |     |
     |   | call dc->unparent            |     |
     |   '-------------------------------     |
     '----------------------------------------'
   unrealize device

After the patch, it behaves as follows instead:

   unrealize device --------------------.
   | for each child bus                 |
   |   unrealize bus               (A)  |
   '------------------------------------'
   for each child bus
     unparent bus ----------------------.
     | for each child device            |
     |   unrealize device          (B)  |
     |   call dc->unparent              |
     '----------------------------------'

At the step marked (B) the device might use data from the bus that is
not available anymore due to step (A).

To fix this, we need to unrealize devices before step (A).  To sidestep
concerns about recursive realization, only do recursive unrealization
and leave the "value && !bus->realized" case as it is.

The resulting flow is:

   for each child bus
     unrealize bus ---------------------.
     | for each child device            |
     |   unrealize device          (B)  |
     | call bc->unrealize          (A)  |
     '----------------------------------'
   unrealize device
   for each child bus
     unparent bus ----------------------.
     | for each child device            |
     |   unparent device                |
     '----------------------------------'

where everything is "powered down" before it is unassembled.

Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Tested-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Andreas Färber <afaerber@suse.de>
2014-06-19 18:44:21 +03:00
..
9pfs virtio: Drop superfluous conditionals around g_free() 2014-06-19 16:41:53 +03:00
acpi pc: add acpi-device link to PCMachineState 2014-06-19 16:41:51 +03:00
alpha machine: Conversion of QEMUMachineInitArgs to MachineState 2014-05-28 17:35:01 +02:00
arm vexpress: Add support for the -bios flag to provide firmware 2014-06-09 15:43:22 +01:00
audio savevm: Remove all the unneeded version_minimum_id_old (x86) 2014-06-16 04:55:26 +02:00
block Block pull request 2014-06-16 12:27:47 +01:00
bt Preparation for usb-bt-dongle conditional build 2013-09-10 11:14:41 +02:00
char savevm: Remove all the unneeded version_minimum_id_old (x86) 2014-06-16 04:55:26 +02:00
core qdev: recursively unrealize devices when unrealizing bus 2014-06-19 18:44:21 +03:00
cpu icc_bus: QOM'ify ICC 2013-12-24 18:02:18 +01:00
cris machine: Conversion of QEMUMachineInitArgs to MachineState 2014-05-28 17:35:01 +02:00
display savevm: Remove all the unneeded version_minimum_id_old (x86) 2014-06-16 04:55:26 +02:00
dma savevm: Remove all the unneeded version_minimum_id_old (x86) 2014-06-16 04:55:26 +02:00
gpio savevm: Remove all the unneeded version_minimum_id_old (arm) 2014-05-13 16:09:35 +01:00
i2c savevm: Remove all the unneeded version_minimum_id_old (rest) 2014-05-14 15:24:51 +02:00
i386 pc: pass MachineState to pc_memory_init 2014-06-19 18:44:20 +03:00
ide Patch queue for ppc - 2014-06-16 2014-06-16 18:26:21 +01:00
input savevm: Remove all the unneeded version_minimum_id_old (x86) 2014-06-16 04:55:26 +02:00
intc PPC: openpic_kvm: Implement reset 2014-06-16 13:24:36 +02:00
ipack savevm: Remove all the unneeded version_minimum_id_old (rest) 2014-05-14 15:24:51 +02:00
isa pc: q35: acpi: report error to user on unsupported unplug request 2014-06-19 16:41:53 +03:00
lm32 machine: Conversion of QEMUMachineInitArgs to MachineState 2014-05-28 17:35:01 +02:00
m68k machine: Conversion of QEMUMachineInitArgs to MachineState 2014-05-28 17:35:01 +02:00
mem pc-dimm: add busy slot check and slot auto-allocation 2014-06-19 16:41:49 +03:00
microblaze ssi: Name the CS GPIO 2014-05-28 17:36:21 +02:00
mips pc: add acpi-device link to PCMachineState 2014-06-19 16:41:51 +03:00
misc macio: Fix timer endianness 2014-06-16 13:24:38 +02:00
moxie machine: Conversion of QEMUMachineInitArgs to MachineState 2014-05-28 17:35:01 +02:00
net Add the vhost-user netdev backend to the command line 2014-06-19 18:44:18 +03:00
nvram spapr_nvram: Correct max nvram size 2014-06-16 13:24:26 +02:00
openrisc machine: Conversion of QEMUMachineInitArgs to MachineState 2014-05-28 17:35:01 +02:00
pci savevm: Remove all the unneeded version_minimum_id_old (x86) 2014-06-16 04:55:26 +02:00
pci-bridge savevm: Remove all the unneeded version_minimum_id_old (x86) 2014-06-16 04:55:26 +02:00
pci-host hw/pci-host/ppce500: Fix typo in vmstate definition 2014-06-16 13:24:41 +02:00
pcmcia qom: Add check() argument to object_property_add_link() 2014-03-19 22:23:13 +01:00
ppc NUMA: Add numa_info structure to contain numa nodes info 2014-06-19 18:44:18 +03:00
s390x s390x: cleanup interrupt injection 2014-06-10 09:50:27 +02:00
scsi Add vhost-backend and VhostBackendType 2014-06-19 16:41:56 +03:00
sd hw/sd/sd.c: Drop unused sd_acmd_type[] array 2014-06-10 19:39:34 +04:00
sh4 machine: Conversion of QEMUMachineInitArgs to MachineState 2014-05-28 17:35:01 +02:00
sparc tcx: move initialisation from realizefn to initfn 2014-06-05 20:51:57 +01:00
sparc64 machine: Conversion of QEMUMachineInitArgs to MachineState 2014-05-28 17:35:01 +02:00
ssi ssi: Name the CS GPIO 2014-05-28 17:36:21 +02:00
timer savevm: Remove all the unneeded version_minimum_id_old (x86) 2014-06-16 04:55:26 +02:00
tpm aio / timers: Untangle include files 2013-08-22 19:10:27 +02:00
unicore32 machine: Conversion of QEMUMachineInitArgs to MachineState 2014-05-28 17:35:01 +02:00
usb blockdev: Rename drive_init(), drive_uninit() to drive_new(), drive_del() 2014-06-16 17:23:19 +08:00
virtio Add vhost-user as a vhost backend. 2014-06-19 16:41:56 +03:00
watchdog savevm: Remove all the unneeded version_minimum_id_old (x86) 2014-06-16 04:55:26 +02:00
xen trivial patches for 2014-05-07 2014-05-07 18:38:39 +01:00
xenpv machine: Conversion of QEMUMachineInitArgs to MachineState 2014-05-28 17:35:01 +02:00
xtensa machine: Conversion of QEMUMachineInitArgs to MachineState 2014-05-28 17:35:01 +02:00
Makefile.objs pc: implement pc-dimm device abstraction 2014-06-19 16:41:47 +03:00