@@ -153,6 +153,14 @@ struct ResettableState {
bool exit_phase_in_progress;
};
+/**
+ * resettable_state_clear:
+ * Clear the state. It puts the state to the initial (zeroed) state required
+ * to reuse an object. Typically used in realize step of base classes
+ * implementing the interface.
+ */
+void resettable_state_clear(ResettableState *state);
+
/**
* resettable_reset:
* Trigger a reset on an object @obj of type @type. @obj must implement
@@ -948,6 +948,12 @@ static void device_set_realized(Object *obj, bool value, Error **errp)
}
}
+ /*
+ * Clear the reset state, in case the object was previously unrealized
+ * with a dirty state.
+ */
+ resettable_state_clear(&dev->reset);
+
QLIST_FOREACH(bus, &dev->child_bus, sibling) {
object_property_set_bool(OBJECT(bus), true, "realized",
&local_err);
@@ -956,7 +962,14 @@ static void device_set_realized(Object *obj, bool value, Error **errp)
}
}
if (dev->hotplugged) {
- device_legacy_reset(dev);
+ /*
+ * Reset the device, as well as its subtree which, at this point,
+ * should be realized too.
+ */
+ resettable_assert_reset(OBJECT(dev), RESET_TYPE_COLD);
+ resettable_change_parent(OBJECT(dev), OBJECT(dev->parent_bus),
+ NULL);
+ resettable_release_reset(OBJECT(dev), RESET_TYPE_COLD);
}
dev->pending_deleted_event = false;
@@ -15,6 +15,11 @@
#include "hw/resettable.h"
#include "trace.h"
+void resettable_state_clear(ResettableState *state)
+{
+ memset(state, 0, sizeof(ResettableState));
+}
+
/**
* resettable_phase_enter/hold/exit:
* Function executing a phase recursively in a resettable object and its
This commit make use of the resettable API to reset the device being hotplugged when it is realized. Also it ensures it is put in a reset state coherent with the parent it is plugged into. Note that there is a difference in the reset. Instead of resetting only the hotplugged device, we reset also its subtree (switch to resettable API). This is not expected to be a problem because sub-buses are just realized too. If a hotplugged device has any sub-buses it is logical to reset them too at this point. The recently added should_be_hidden and PCI's partially_hotplugged mechanisms do not interfere with realize operation: + In the should_be_hidden use case, device creation is delayed. + The partially_hotplugged mechanism prevents a device to be unplugged and unrealized from qdev POV and unrealized. Signed-off-by: Damien Hedde <damien.hedde@greensocs.com> --- v6 update: clear the reset state before doing any reset. Although it is apparently highly improbable that a device be realized again after being unrealized. See here for a discussion about this point and the partially_hotplugged/shoud_be_hidden cases. https://lists.nongnu.org/archive/html/qemu-devel/2019-11/msg04897.html --- include/hw/resettable.h | 8 ++++++++ hw/core/qdev.c | 15 ++++++++++++++- hw/core/resettable.c | 5 +++++ 3 files changed, 27 insertions(+), 1 deletion(-)