Skip to content

Commit

Permalink
hw/core/qdev: update hotplug reset regarding resettable
Browse files Browse the repository at this point in the history
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>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-id: 20200123132823.1117486-8-damien.hedde@greensocs.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
dhedde authored and pm215 committed Jan 30, 2020
1 parent a7c3a4f commit e755e12
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 1 deletion.
15 changes: 14 additions & 1 deletion hw/core/qdev.c
Expand Up @@ -909,6 +909,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);
Expand All @@ -917,7 +923,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;

Expand Down
11 changes: 11 additions & 0 deletions include/hw/resettable.h
Expand Up @@ -153,6 +153,17 @@ 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.
*/
static inline void resettable_state_clear(ResettableState *state)
{
memset(state, 0, sizeof(ResettableState));
}

/**
* resettable_reset:
* Trigger a reset on an object @obj of type @type. @obj must implement
Expand Down

0 comments on commit e755e12

Please sign in to comment.