Message ID | 20240412160809.1260625-7-peter.maydell@linaro.org |
---|---|
State | Superseded |
Headers | show |
Series | reset: Add RESET_TYPE_SNAPSHOT_LOAD | expand |
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~
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 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 > > --
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);
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(-)