Some devices and machines need to handle the reset before a vmsave
snapshot is loaded differently -- the main user is the handling of
RNG seed information, which does not want to put a new RNG seed into
a ROM blob when we are doing a snapshot load.
Currently this kind of reset handling is supported only for:
* TYPE_MACHINE reset methods, which take a ShutdownCause argument
* reset functions registered with qemu_register_reset_nosnapshotload
To allow a three-phase-reset device to also distinguish "snapshot
load" reset from the normal kind, add a new ResetType
RESET_TYPE_SNAPSHOT_LOAD. All our existing reset methods ignore
the reset type, so we don't need to update any device code.
Add the enum type, and make qemu_devices_reset() use the
right reset type for the ShutdownCause it is passed. This
allows us to get rid of the device_reset_reason global we
were using to implement qemu_register_reset_nosnapshotload().
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
docs/devel/reset.rst | 17 ++++++++++++++---
include/hw/resettable.h | 1 +
hw/core/reset.c | 15 ++++-----------
hw/core/resettable.c | 4 ----
4 files changed, 19 insertions(+), 18 deletions(-)
diff --git a/docs/devel/reset.rst b/docs/devel/reset.rst
index 49baa1ea271..9746a4e8a0b 100644
--- a/docs/devel/reset.rst
+++ b/docs/devel/reset.rst
@@ -27,9 +27,7 @@ instantly reset an object, without keeping it in reset state, just call
``resettable_reset()``. These functions take two parameters: a pointer to the
object to reset and a reset type.
-Several types of reset will be supported. For now only cold reset is defined;
-others may be added later. The Resettable interface handles reset types with an
-enum:
+The Resettable interface handles reset types with an enum ``ResetType``:
``RESET_TYPE_COLD``
Cold reset is supported by every resettable object. In QEMU, it means we reset
@@ -37,6 +35,19 @@ enum:
from what is a real hardware cold reset. It differs from other resets (like
warm or bus resets) which may keep certain parts untouched.
+``RESET_TYPE_SNAPSHOT_LOAD``
+ This is called for a reset which is being done to put the system into a
+ clean state prior to loading a snapshot. (This corresponds to a reset
+ with ``SHUTDOWN_CAUSE_SNAPSHOT_LOAD``.) Almost all devices should treat
+ this the same as ``RESET_TYPE_COLD``. The main exception is devices which
+ have some non-deterministic state they want to reinitialize to a different
+ value on each cold reset, such as RNG seed information, and which they
+ must not reinitialize on a snapshot-load reset.
+
+Devices which implement reset methods must treat any unknown ``ResetType``
+as equivalent to ``RESET_TYPE_COLD``; this will reduce the amount of
+existing code we need to change if we add more types in future.
+
Calling ``resettable_reset()`` is equivalent to calling
``resettable_assert_reset()`` then ``resettable_release_reset()``. It is
possible to interleave multiple calls to these three functions. There may
diff --git a/include/hw/resettable.h b/include/hw/resettable.h
index 3161e471c9b..7e249deb8b5 100644
--- a/include/hw/resettable.h
+++ b/include/hw/resettable.h
@@ -35,6 +35,7 @@ typedef struct ResettableState ResettableState;
*/
typedef enum ResetType {
RESET_TYPE_COLD,
+ RESET_TYPE_SNAPSHOT_LOAD,
} ResetType;
/*
diff --git a/hw/core/reset.c b/hw/core/reset.c
index f9fef45e050..58dfc8db3dc 100644
--- a/hw/core/reset.c
+++ b/hw/core/reset.c
@@ -43,13 +43,6 @@ static ResettableContainer *get_root_reset_container(void)
return root_reset_container;
}
-/*
- * Reason why the currently in-progress qemu_devices_reset() was called.
- * If we made at least SHUTDOWN_CAUSE_SNAPSHOT_LOAD have a corresponding
- * ResetType we could perhaps avoid the need for this global.
- */
-static ShutdownCause device_reset_reason;
-
/*
* This is an Object which implements Resettable simply to call the
* callback function in the hold phase.
@@ -77,8 +70,7 @@ static void legacy_reset_hold(Object *obj, ResetType type)
{
LegacyReset *lr = LEGACY_RESET(obj);
- if (device_reset_reason == SHUTDOWN_CAUSE_SNAPSHOT_LOAD &&
- lr->skip_on_snapshot_load) {
+ if (type == RESET_TYPE_SNAPSHOT_LOAD && lr->skip_on_snapshot_load) {
return;
}
lr->func(lr->opaque);
@@ -180,8 +172,9 @@ void qemu_unregister_resettable(Object *obj)
void qemu_devices_reset(ShutdownCause reason)
{
- device_reset_reason = reason;
+ ResetType type = (reason == SHUTDOWN_CAUSE_SNAPSHOT_LOAD) ?
+ RESET_TYPE_SNAPSHOT_LOAD : RESET_TYPE_COLD;
/* Reset the simulation */
- resettable_reset(OBJECT(get_root_reset_container()), RESET_TYPE_COLD);
+ resettable_reset(OBJECT(get_root_reset_container()), type);
}
diff --git a/hw/core/resettable.c b/hw/core/resettable.c
index bebf7f10b26..6dd3e3dc487 100644
--- a/hw/core/resettable.c
+++ b/hw/core/resettable.c
@@ -48,8 +48,6 @@ void resettable_reset(Object *obj, ResetType type)
void resettable_assert_reset(Object *obj, ResetType type)
{
- /* TODO: change this assert when adding support for other reset types */
- assert(type == RESET_TYPE_COLD);
trace_resettable_reset_assert_begin(obj, type);
assert(!enter_phase_in_progress);
@@ -64,8 +62,6 @@ void resettable_assert_reset(Object *obj, ResetType type)
void resettable_release_reset(Object *obj, ResetType type)
{
- /* TODO: change this assert when adding support for other reset types */
- assert(type == RESET_TYPE_COLD);
trace_resettable_reset_release_begin(obj, type);
assert(!enter_phase_in_progress);
--
2.34.1
On 17:08 Fri 12 Apr , Peter Maydell wrote:
> Some devices and machines need to handle the reset before a vmsave
> snapshot is loaded differently -- the main user is the handling of
> RNG seed information, which does not want to put a new RNG seed into
> a ROM blob when we are doing a snapshot load.
>
> Currently this kind of reset handling is supported only for:
> * TYPE_MACHINE reset methods, which take a ShutdownCause argument
> * reset functions registered with qemu_register_reset_nosnapshotload
>
> To allow a three-phase-reset device to also distinguish "snapshot
> load" reset from the normal kind, add a new ResetType
> RESET_TYPE_SNAPSHOT_LOAD. All our existing reset methods ignore
> the reset type, so we don't need to update any device code.
>
> Add the enum type, and make qemu_devices_reset() use the
> right reset type for the ShutdownCause it is passed. This
> allows us to get rid of the device_reset_reason global we
> were using to implement qemu_register_reset_nosnapshotload().
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Luc Michel <luc.michel@amd.com>
> ---
> docs/devel/reset.rst | 17 ++++++++++++++---
> include/hw/resettable.h | 1 +
> hw/core/reset.c | 15 ++++-----------
> hw/core/resettable.c | 4 ----
> 4 files changed, 19 insertions(+), 18 deletions(-)
>
> diff --git a/docs/devel/reset.rst b/docs/devel/reset.rst
> index 49baa1ea271..9746a4e8a0b 100644
> --- a/docs/devel/reset.rst
> +++ b/docs/devel/reset.rst
> @@ -27,9 +27,7 @@ instantly reset an object, without keeping it in reset state, just call
> ``resettable_reset()``. These functions take two parameters: a pointer to the
> object to reset and a reset type.
>
> -Several types of reset will be supported. For now only cold reset is defined;
> -others may be added later. The Resettable interface handles reset types with an
> -enum:
> +The Resettable interface handles reset types with an enum ``ResetType``:
>
> ``RESET_TYPE_COLD``
> Cold reset is supported by every resettable object. In QEMU, it means we reset
> @@ -37,6 +35,19 @@ enum:
> from what is a real hardware cold reset. It differs from other resets (like
> warm or bus resets) which may keep certain parts untouched.
>
> +``RESET_TYPE_SNAPSHOT_LOAD``
> + This is called for a reset which is being done to put the system into a
> + clean state prior to loading a snapshot. (This corresponds to a reset
> + with ``SHUTDOWN_CAUSE_SNAPSHOT_LOAD``.) Almost all devices should treat
> + this the same as ``RESET_TYPE_COLD``. The main exception is devices which
> + have some non-deterministic state they want to reinitialize to a different
> + value on each cold reset, such as RNG seed information, and which they
> + must not reinitialize on a snapshot-load reset.
> +
> +Devices which implement reset methods must treat any unknown ``ResetType``
> +as equivalent to ``RESET_TYPE_COLD``; this will reduce the amount of
> +existing code we need to change if we add more types in future.
> +
> Calling ``resettable_reset()`` is equivalent to calling
> ``resettable_assert_reset()`` then ``resettable_release_reset()``. It is
> possible to interleave multiple calls to these three functions. There may
> diff --git a/include/hw/resettable.h b/include/hw/resettable.h
> index 3161e471c9b..7e249deb8b5 100644
> --- a/include/hw/resettable.h
> +++ b/include/hw/resettable.h
> @@ -35,6 +35,7 @@ typedef struct ResettableState ResettableState;
> */
> typedef enum ResetType {
> RESET_TYPE_COLD,
> + RESET_TYPE_SNAPSHOT_LOAD,
> } ResetType;
>
> /*
> diff --git a/hw/core/reset.c b/hw/core/reset.c
> index f9fef45e050..58dfc8db3dc 100644
> --- a/hw/core/reset.c
> +++ b/hw/core/reset.c
> @@ -43,13 +43,6 @@ static ResettableContainer *get_root_reset_container(void)
> return root_reset_container;
> }
>
> -/*
> - * Reason why the currently in-progress qemu_devices_reset() was called.
> - * If we made at least SHUTDOWN_CAUSE_SNAPSHOT_LOAD have a corresponding
> - * ResetType we could perhaps avoid the need for this global.
> - */
> -static ShutdownCause device_reset_reason;
> -
> /*
> * This is an Object which implements Resettable simply to call the
> * callback function in the hold phase.
> @@ -77,8 +70,7 @@ static void legacy_reset_hold(Object *obj, ResetType type)
> {
> LegacyReset *lr = LEGACY_RESET(obj);
>
> - if (device_reset_reason == SHUTDOWN_CAUSE_SNAPSHOT_LOAD &&
> - lr->skip_on_snapshot_load) {
> + if (type == RESET_TYPE_SNAPSHOT_LOAD && lr->skip_on_snapshot_load) {
> return;
> }
> lr->func(lr->opaque);
> @@ -180,8 +172,9 @@ void qemu_unregister_resettable(Object *obj)
>
> void qemu_devices_reset(ShutdownCause reason)
> {
> - device_reset_reason = reason;
> + ResetType type = (reason == SHUTDOWN_CAUSE_SNAPSHOT_LOAD) ?
> + RESET_TYPE_SNAPSHOT_LOAD : RESET_TYPE_COLD;
>
> /* Reset the simulation */
> - resettable_reset(OBJECT(get_root_reset_container()), RESET_TYPE_COLD);
> + resettable_reset(OBJECT(get_root_reset_container()), type);
> }
> diff --git a/hw/core/resettable.c b/hw/core/resettable.c
> index bebf7f10b26..6dd3e3dc487 100644
> --- a/hw/core/resettable.c
> +++ b/hw/core/resettable.c
> @@ -48,8 +48,6 @@ void resettable_reset(Object *obj, ResetType type)
>
> void resettable_assert_reset(Object *obj, ResetType type)
> {
> - /* TODO: change this assert when adding support for other reset types */
> - assert(type == RESET_TYPE_COLD);
> trace_resettable_reset_assert_begin(obj, type);
> assert(!enter_phase_in_progress);
>
> @@ -64,8 +62,6 @@ void resettable_assert_reset(Object *obj, ResetType type)
>
> void resettable_release_reset(Object *obj, ResetType type)
> {
> - /* TODO: change this assert when adding support for other reset types */
> - assert(type == RESET_TYPE_COLD);
> trace_resettable_reset_release_begin(obj, type);
> assert(!enter_phase_in_progress);
>
> --
> 2.34.1
>
>
--
On 12/4/24 18:08, Peter Maydell wrote: > Some devices and machines need to handle the reset before a vmsave > snapshot is loaded differently -- the main user is the handling of > RNG seed information, which does not want to put a new RNG seed into > a ROM blob when we are doing a snapshot load. > > Currently this kind of reset handling is supported only for: > * TYPE_MACHINE reset methods, which take a ShutdownCause argument > * reset functions registered with qemu_register_reset_nosnapshotload > > To allow a three-phase-reset device to also distinguish "snapshot > load" reset from the normal kind, add a new ResetType > RESET_TYPE_SNAPSHOT_LOAD. All our existing reset methods ignore > the reset type, so we don't need to update any device code. > > Add the enum type, and make qemu_devices_reset() use the > right reset type for the ShutdownCause it is passed. This > allows us to get rid of the device_reset_reason global we > were using to implement qemu_register_reset_nosnapshotload(). > > Signed-off-by: Peter Maydell <peter.maydell@linaro.org> > --- > docs/devel/reset.rst | 17 ++++++++++++++--- > include/hw/resettable.h | 1 + > hw/core/reset.c | 15 ++++----------- > hw/core/resettable.c | 4 ---- > 4 files changed, 19 insertions(+), 18 deletions(-) Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
On 4/12/24 09:08, Peter Maydell wrote: > Some devices and machines need to handle the reset before a vmsave > snapshot is loaded differently -- the main user is the handling of > RNG seed information, which does not want to put a new RNG seed into > a ROM blob when we are doing a snapshot load. > > Currently this kind of reset handling is supported only for: > * TYPE_MACHINE reset methods, which take a ShutdownCause argument > * reset functions registered with qemu_register_reset_nosnapshotload > > To allow a three-phase-reset device to also distinguish "snapshot > load" reset from the normal kind, add a new ResetType > RESET_TYPE_SNAPSHOT_LOAD. All our existing reset methods ignore > the reset type, so we don't need to update any device code. > > Add the enum type, and make qemu_devices_reset() use the > right reset type for the ShutdownCause it is passed. This > allows us to get rid of the device_reset_reason global we > were using to implement qemu_register_reset_nosnapshotload(). > > Signed-off-by: Peter Maydell<peter.maydell@linaro.org> > --- > docs/devel/reset.rst | 17 ++++++++++++++--- > include/hw/resettable.h | 1 + > hw/core/reset.c | 15 ++++----------- > hw/core/resettable.c | 4 ---- > 4 files changed, 19 insertions(+), 18 deletions(-) Reviewed-by: Richard Henderson <richard.henderson@linaro.org> r~
© 2016 - 2026 Red Hat, Inc.