diff options
author | Greg Kurz <groug@kaod.org> | 2020-12-18 11:33:56 +0100 |
---|---|---|
committer | David Gibson <david@gibson.dropbear.id.au> | 2021-01-06 11:09:59 +1100 |
commit | 930ef3b5c212bf8056bd265cc43ed9fff2e31b08 (patch) | |
tree | 52ed376346c2d060357ab7de169ed56100772a5f /hw/ppc/spapr_hcall.c | |
parent | cd725bd7489e52445a15dd2f0ad1aa746dfa91fc (diff) | |
download | qemu-930ef3b5c212bf8056bd265cc43ed9fff2e31b08.zip qemu-930ef3b5c212bf8056bd265cc43ed9fff2e31b08.tar.gz qemu-930ef3b5c212bf8056bd265cc43ed9fff2e31b08.tar.bz2 |
spapr: Fix reset of transient DR connectors
Documentation of object_property_iter_init() clearly stipulates that
"it is forbidden to modify the property list while iterating". But this
is exactly what we do when resetting transient DR connectors during CAS.
The call to spapr_drc_reset() can finalize the hot-unplug sequence of a
PHB or a PCI bridge, both of which will then in turn destroy their PCI
DRCs. This could potentially invalidate the iterator. It is pure luck
that this haven't caused any issues so far.
Change spapr_drc_reset() to return true if it caused a device to be
removed. Restart from scratch in this case. This can potentially
increase the overall DRC reset time, especially with a high maxmem
which generates a lot of LMB DRCs. But this kind of setup is rare,
and so is the use case of rebooting a guest while doing hot-unplug.
Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <20201218103400.689660-3-groug@kaod.org>
Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Tested-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Diffstat (limited to 'hw/ppc/spapr_hcall.c')
-rw-r--r-- | hw/ppc/spapr_hcall.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index 4e9d50c..aa22830 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -1639,6 +1639,7 @@ static void spapr_handle_transient_dev_before_cas(SpaprMachineState *spapr) ObjectPropertyIterator iter; drc_container = container_get(object_get_root(), "/dr-connector"); +restart: object_property_iter_init(&iter, drc_container); while ((prop = object_property_iter_next(&iter))) { SpaprDrc *drc; @@ -1652,8 +1653,13 @@ static void spapr_handle_transient_dev_before_cas(SpaprMachineState *spapr) /* * This will complete any pending plug/unplug requests. + * In case of a unplugged PHB or PCI bridge, this will + * cause some DRCs to be destroyed and thus potentially + * invalidate the iterator. */ - spapr_drc_reset(drc); + if (spapr_drc_reset(drc)) { + goto restart; + } } spapr_clear_pending_hotplug_events(spapr); |