aboutsummaryrefslogtreecommitdiff
path: root/hw/ppc/spapr.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/ppc/spapr.c')
-rw-r--r--hw/ppc/spapr.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 6841bd294b..6285f7211f 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1411,6 +1411,19 @@ static void find_unknown_sysbus_device(SysBusDevice *sbdev, void *opaque)
}
}
+static int spapr_reset_drcs(Object *child, void *opaque)
+{
+ sPAPRDRConnector *drc =
+ (sPAPRDRConnector *) object_dynamic_cast(child,
+ TYPE_SPAPR_DR_CONNECTOR);
+
+ if (drc) {
+ spapr_drc_reset(drc);
+ }
+
+ return 0;
+}
+
static void ppc_spapr_reset(void)
{
MachineState *machine = MACHINE(qdev_get_machine());
@@ -1434,6 +1447,14 @@ static void ppc_spapr_reset(void)
}
qemu_devices_reset();
+
+ /* DRC reset may cause a device to be unplugged. This will cause troubles
+ * if this device is used by another device (eg, a running vhost backend
+ * will crash QEMU if the DIMM holding the vring goes away). To avoid such
+ * situations, we reset DRCs after all devices have been reset.
+ */
+ object_child_foreach_recursive(object_get_root(), spapr_reset_drcs, NULL);
+
spapr_clear_pending_events(spapr);
/*