diff options
Diffstat (limited to 'hw')
-rw-r--r-- | hw/ppc/spapr.c | 21 | ||||
-rw-r--r-- | hw/ppc/spapr_drc.c | 7 |
2 files changed, 21 insertions, 7 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); /* diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c index 915e9b51c4..e3b122968e 100644 --- a/hw/ppc/spapr_drc.c +++ b/hw/ppc/spapr_drc.c @@ -455,11 +455,6 @@ void spapr_drc_reset(sPAPRDRConnector *drc) } } -static void drc_reset(void *opaque) -{ - spapr_drc_reset(SPAPR_DR_CONNECTOR(opaque)); -} - bool spapr_drc_needed(void *opaque) { sPAPRDRConnector *drc = (sPAPRDRConnector *)opaque; @@ -518,7 +513,6 @@ static void realize(DeviceState *d, Error **errp) } vmstate_register(DEVICE(drc), spapr_drc_index(drc), &vmstate_spapr_drc, drc); - qemu_register_reset(drc_reset, drc); trace_spapr_drc_realize_complete(spapr_drc_index(drc)); } @@ -529,7 +523,6 @@ static void unrealize(DeviceState *d, Error **errp) gchar *name; trace_spapr_drc_unrealize(spapr_drc_index(drc)); - qemu_unregister_reset(drc_reset, drc); vmstate_unregister(DEVICE(drc), &vmstate_spapr_drc, drc); root_container = container_get(object_get_root(), DRC_CONTAINER_PATH); name = g_strdup_printf("%x", spapr_drc_index(drc)); |