aboutsummaryrefslogtreecommitdiff
path: root/arch_init.c
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2014-06-11 14:52:09 +0200
committerMichael Roth <mdroth@linux.vnet.ibm.com>2014-08-05 13:55:40 -0500
commit88efef64db627c5fa26af2abf943bdb94c03eeb9 (patch)
treed74981f40894bb740deb169cac027a72a6c63815 /arch_init.c
parentab139bf9d278e7ce4fe83d81a4a01b51c7d82091 (diff)
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> (cherry picked from commit 5942a19040fed313b316ab7b6e3d2d8e7b1625bb) Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Diffstat (limited to 'arch_init.c')
0 files changed, 0 insertions, 0 deletions