[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-stable] [PATCH 076/108] qdev: recursively unrealize devices when u
From: |
Michael Roth |
Subject: |
[Qemu-stable] [PATCH 076/108] qdev: recursively unrealize devices when unrealizing bus |
Date: |
Wed, 6 Aug 2014 15:39:26 -0500 |
From: Paolo Bonzini <address@hidden>
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: address@hidden
Signed-off-by: Paolo Bonzini <address@hidden>
Tested-by: Michael S. Tsirkin <address@hidden>
Reviewed-by: Michael S. Tsirkin <address@hidden>
Signed-off-by: Michael S. Tsirkin <address@hidden>
Reviewed-by: Andreas Färber <address@hidden>
(cherry picked from commit 5942a19040fed313b316ab7b6e3d2d8e7b1625bb)
Signed-off-by: Michael Roth <address@hidden>
---
hw/core/qdev.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index f52f0ac..79db470 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -515,14 +515,25 @@ static void bus_set_realized(Object *obj, bool value,
Error **errp)
{
BusState *bus = BUS(obj);
BusClass *bc = BUS_GET_CLASS(bus);
+ BusChild *kid;
Error *local_err = NULL;
if (value && !bus->realized) {
if (bc->realize) {
bc->realize(bus, &local_err);
}
+
+ /* TODO: recursive realization */
} else if (!value && bus->realized) {
- if (bc->unrealize) {
+ QTAILQ_FOREACH(kid, &bus->children, sibling) {
+ DeviceState *dev = kid->child;
+ object_property_set_bool(OBJECT(dev), false, "realized",
+ &local_err);
+ if (local_err != NULL) {
+ break;
+ }
+ }
+ if (bc->unrealize && local_err == NULL) {
bc->unrealize(bus, &local_err);
}
}
--
1.9.1
- [Qemu-stable] [PATCH 066/108] target-arm: Fix errors in writes to generic timer control registers, (continued)
- [Qemu-stable] [PATCH 066/108] target-arm: Fix errors in writes to generic timer control registers, Michael Roth, 2014/08/06
- [Qemu-stable] [PATCH 067/108] s390x/css: handle emw correctly for tsch, Michael Roth, 2014/08/06
- [Qemu-stable] [PATCH 034/108] qdev: Fix crash by validating the object type, Michael Roth, 2014/08/06
- [Qemu-stable] [PATCH 070/108] migration: remove duplicate code, Michael Roth, 2014/08/06
- [Qemu-stable] [PATCH 068/108] aio: fix qemu_bh_schedule() bh->ctx race condition, Michael Roth, 2014/08/06
- [Qemu-stable] [PATCH 069/108] qga: Fix handle fd leak in acquire_privilege(), Michael Roth, 2014/08/06
- [Qemu-stable] [PATCH 071/108] arch_init: Be sure of only one exit entry with DPRINTF() for ram_load(), Michael Roth, 2014/08/06
- [Qemu-stable] [PATCH 073/108] rdma: bug fixes, Michael Roth, 2014/08/06
- [Qemu-stable] [PATCH 072/108] migration: catch unknown flags in ram_load, Michael Roth, 2014/08/06
- [Qemu-stable] [PATCH 075/108] qdev: reorganize error reporting in bus_set_realized, Michael Roth, 2014/08/06
- [Qemu-stable] [PATCH 076/108] qdev: recursively unrealize devices when unrealizing bus,
Michael Roth <=
- [Qemu-stable] [PATCH 077/108] scsi-disk: fix bug in scsi_block_new_request() introduced by commit 137745c, Michael Roth, 2014/08/06
- [Qemu-stable] [PATCH 078/108] vhost: fix resource leak in error handling, Michael Roth, 2014/08/06
- [Qemu-stable] [PATCH 080/108] usb: Fix usb-bt-dongle initialization., Michael Roth, 2014/08/06
- [Qemu-stable] [PATCH 079/108] virtio-scsi: define dummy handle_output for vhost-scsi vqs, Michael Roth, 2014/08/06
- [Qemu-stable] [PATCH 083/108] coroutine-win32.c: Add noinline attribute to work around gcc bug, Michael Roth, 2014/08/06
- [Qemu-stable] [PATCH 086/108] target-i386: Filter FEAT_7_0_EBX TCG features too, Michael Roth, 2014/08/06
- [Qemu-stable] [PATCH 082/108] q35: Use PC_Q35_COMPAT_1_4 on pc-q35-1.4 compat_props, Michael Roth, 2014/08/06
- [Qemu-stable] [PATCH 084/108] hw/xtensa/xtfpga: fix FLASH mapping to boot region for KC705, Michael Roth, 2014/08/06
- [Qemu-stable] [PATCH 085/108] target-i386: Make TCG feature filtering more readable, Michael Roth, 2014/08/06
- [Qemu-stable] [PATCH 088/108] virtio-serial: don't migrate the config space, Michael Roth, 2014/08/06