[PATCH 6/6] reset: Add RESET_TYPE_SNAPSHOT_LOAD

Peter Maydell posted 6 patches 1 year, 10 months ago
Maintainers: Alistair Francis <alistair@alistair23.me>, Peter Maydell <peter.maydell@linaro.org>, Tyrone Ting <kfting@nuvoton.com>, Hao Wu <wuhaotsh@google.com>, Eric Auger <eric.auger@redhat.com>, Laurent Vivier <laurent@vivier.eu>, Gerd Hoffmann <kraxel@redhat.com>, "Edgar E. Iglesias" <edgar.iglesias@gmail.com>, "Marc-André Lureau" <marcandre.lureau@redhat.com>, Paolo Bonzini <pbonzini@redhat.com>, Bin Meng <bin.meng@windriver.com>, Palmer Dabbelt <palmer@dabbelt.com>, Eduardo Habkost <eduardo@habkost.net>, Marcel Apfelbaum <marcel.apfelbaum@gmail.com>, "Philippe Mathieu-Daudé" <philmd@linaro.org>, Yanan Wang <wangyanan55@huawei.com>, "Daniel P. Berrangé" <berrange@redhat.com>, "Michael S. Tsirkin" <mst@redhat.com>, Arnaud Minier <arnaud.minier@telecom-paris.fr>, "Inès Varhol" <ines.varhol@telecom-paris.fr>, "Maciej S. Szmigiero" <maciej.szmigiero@oracle.com>, Beniamino Galvani <b.galvani@gmail.com>, Strahinja Jankovic <strahinja.p.jankovic@gmail.com>, Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>, Nicholas Piggin <npiggin@gmail.com>, Daniel Henrique Barboza <danielhb413@gmail.com>, David Gibson <david@gibson.dropbear.id.au>, Harsh Prateek Bora <harshpb@linux.ibm.com>, Francisco Iglesias <francisco.iglesias@amd.com>, Vikram Garhwal <vikram.garhwal@amd.com>, Pavel Pisa <pisa@cmp.felk.cvut.cz>, Jason Wang <jasowang@redhat.com>, Dmitry Fleytman <dmitry.fleytman@gmail.com>, Akihiko Odaki <akihiko.odaki@daynix.com>, Sriram Yagnaraman <sriram.yagnaraman@est.tech>, Huacai Chen <chenhuacai@kernel.org>, Jiaxun Yang <jiaxun.yang@flygoat.com>, "Cédric Le Goater" <clg@kaod.org>, "Frédéric Barrat" <fbarrat@linux.ibm.com>, Halil Pasic <pasic@linux.ibm.com>, Christian Borntraeger <borntraeger@linux.ibm.com>, Eric Farman <farman@linux.ibm.com>, Thomas Huth <thuth@redhat.com>, Richard Henderson <richard.henderson@linaro.org>, David Hildenbrand <david@redhat.com>, Ilya Leoshkevich <iii@linux.ibm.com>, Titus Rwantare <titusr@google.com>, Michael Rolnik <mrolnik@gmail.com>, Brian Cain <bcain@quicinc.com>, Song Gao <gaosong@loongson.cn>, Aurelien Jarno <aurelien@aurel32.net>, Aleksandar Rikalo <aleksandar.rikalo@syrmia.com>, Chris Wulff <crwulff@gmail.com>, Marek Vasut <marex@denx.de>, Stafford Horne <shorne@gmail.com>, Weiwei Li <liwei1518@gmail.com>, Liu Zhiwei <zhiwei_liu@linux.alibaba.com>, Yoshinori Sato <ysato@users.sourceforge.jp>, Artyom Tarasenko <atar4qemu@gmail.com>, Bastian Koppelmann <kbastian@mail.uni-paderborn.de>, Max Filippov <jcmvbkbc@gmail.com>
[PATCH 6/6] reset: Add RESET_TYPE_SNAPSHOT_LOAD
Posted by Peter Maydell 1 year, 10 months ago
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
Re: [PATCH 6/6] reset: Add RESET_TYPE_SNAPSHOT_LOAD
Posted by Luc Michel 1 year, 9 months ago
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
> 
> 

--
Re: [PATCH 6/6] reset: Add RESET_TYPE_SNAPSHOT_LOAD
Posted by Philippe Mathieu-Daudé 1 year, 10 months ago
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>


Re: [PATCH 6/6] reset: Add RESET_TYPE_SNAPSHOT_LOAD
Posted by Richard Henderson 1 year, 10 months ago
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~