[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL v2 094/106] qdev: recursively unrealize devices when
From: |
Michael S. Tsirkin |
Subject: |
[Qemu-devel] [PULL v2 094/106] qdev: recursively unrealize devices when unrealizing bus |
Date: |
Wed, 18 Jun 2014 19:21:54 +0300 |
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>
---
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 65aa041..b9cd4fc 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -568,14 +568,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);
}
}
--
MST
- [Qemu-devel] [PULL v2 084/106] hostmem: allow preallocation of any memory region, (continued)
- [Qemu-devel] [PULL v2 084/106] hostmem: allow preallocation of any memory region, Michael S. Tsirkin, 2014/06/18
- [Qemu-devel] [PULL v2 085/106] hostmem: add property to map memory with MAP_SHARED, Michael S. Tsirkin, 2014/06/18
- [Qemu-devel] [PULL v2 086/106] hostmem: add properties for NUMA memory policy, Michael S. Tsirkin, 2014/06/18
- [Qemu-devel] [PULL v2 087/106] qmp: add query-memdev, Michael S. Tsirkin, 2014/06/18
- [Qemu-devel] [PULL v2 089/106] tests: fix memory leak in test of string input visitor, Michael S. Tsirkin, 2014/06/18
- [Qemu-devel] [PULL v2 088/106] hmp: add info memdev, Michael S. Tsirkin, 2014/06/18
- [Qemu-devel] [PULL v2 090/106] qapi: make string input visitor parse int list, Michael S. Tsirkin, 2014/06/18
- [Qemu-devel] [PULL v2 091/106] qapi: make string output visitor parse int list, Michael S. Tsirkin, 2014/06/18
- [Qemu-devel] [PULL v2 093/106] qdev: reorganize error reporting in bus_set_realized, Michael S. Tsirkin, 2014/06/18
- [Qemu-devel] [PULL v2 092/106] qapi: fix build on glib < 2.28, Michael S. Tsirkin, 2014/06/18
- [Qemu-devel] [PULL v2 094/106] qdev: recursively unrealize devices when unrealizing bus,
Michael S. Tsirkin <=
- [Qemu-devel] [PULL v2 096/106] pc: acpi: do not hardcode preprocessor, Michael S. Tsirkin, 2014/06/18
- [Qemu-devel] [PULL v2 095/106] qmp: clean out whitespace, Michael S. Tsirkin, 2014/06/18
- [Qemu-devel] [PULL v2 097/106] numa: handle mmaped memory allocation failure correctly, Michael S. Tsirkin, 2014/06/18
- [Qemu-devel] [PULL v2 099/106] acpi: introduce TYPE_ACPI_DEVICE_IF interface, Michael S. Tsirkin, 2014/06/18
- [Qemu-devel] [PULL v2 098/106] qmp: add query-memory-devices command, Michael S. Tsirkin, 2014/06/18
- [Qemu-devel] [PULL v2 100/106] acpi: implement ospm_status() method for PIIX4/ICH9_LPC devices, Michael S. Tsirkin, 2014/06/18
- [Qemu-devel] [PULL v2 101/106] qmp: add query-acpi-ospm-status command, Michael S. Tsirkin, 2014/06/18
- [Qemu-devel] [PULL v2 102/106] qmp: add ACPI_DEVICE_OST event handling, Michael S. Tsirkin, 2014/06/18
- [Qemu-devel] [PULL v2 104/106] qapi: fix input visitor bugs, Michael S. Tsirkin, 2014/06/18
- [Qemu-devel] [PULL v2 103/106] acpi: rephrase comment, Michael S. Tsirkin, 2014/06/18