diff mbox series

PM: hibernate: Add error handling for syscore_suspend()

Message ID 20250119143205.2103-1-vulab@iscas.ac.cn (mailing list archive)
State Queued
Delegated to: Rafael Wysocki
Headers show
Series PM: hibernate: Add error handling for syscore_suspend() | expand

Commit Message

Wentao Liang Jan. 19, 2025, 2:32 p.m. UTC
In hibernation_platform_enter(), the code did not check the
return value of syscore_suspend(), potentially leading to a
situation where syscore_resume() would be called even if
syscore_suspend() failed. This could cause unpredictable
behavior or system instability.

This commit modifies the suspend/resume sequence to properly
handle errors returned by syscore_suspend(). If an error occurs
during the suspend process, the code now jumps to 'Enable_irqs'
label, skipping the resume call, and only enabling interrupts
after setting the system state to SYSTEM_RUNNING.

Fixes: 40dc166cb5dd ("PM / Core: Introduce struct syscore_ops for core subsystems PM")
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
---
 kernel/power/hibernate.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

Comments

Rafael J. Wysocki Jan. 23, 2025, 8:15 p.m. UTC | #1
On Sun, Jan 19, 2025 at 3:39 PM Wentao Liang <vulab@iscas.ac.cn> wrote:
>
> In hibernation_platform_enter(), the code did not check the
> return value of syscore_suspend(), potentially leading to a
> situation where syscore_resume() would be called even if
> syscore_suspend() failed. This could cause unpredictable
> behavior or system instability.
>
> This commit modifies the suspend/resume sequence to properly
> handle errors returned by syscore_suspend(). If an error occurs
> during the suspend process, the code now jumps to 'Enable_irqs'
> label, skipping the resume call, and only enabling interrupts
> after setting the system state to SYSTEM_RUNNING.
>
> Fixes: 40dc166cb5dd ("PM / Core: Introduce struct syscore_ops for core subsystems PM")
> Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
> ---
>  kernel/power/hibernate.c | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
> index 1f87aa01ba44..8e5702811732 100644
> --- a/kernel/power/hibernate.c
> +++ b/kernel/power/hibernate.c
> @@ -608,7 +608,11 @@ int hibernation_platform_enter(void)
>
>         local_irq_disable();
>         system_state = SYSTEM_SUSPEND;
> -       syscore_suspend();
> +
> +       error = syscore_suspend();
> +       if (error)
> +               goto Enable_irqs;
> +
>         if (pm_wakeup_pending()) {
>                 error = -EAGAIN;
>                 goto Power_up;
> @@ -620,6 +624,7 @@ int hibernation_platform_enter(void)
>
>   Power_up:
>         syscore_resume();
> + Enable_irqs:
>         system_state = SYSTEM_RUNNING;
>         local_irq_enable();
>
> --

Applied (with some edits in the changelog) as 6.14-rc material, thanks!
diff mbox series

Patch

diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
index 1f87aa01ba44..8e5702811732 100644
--- a/kernel/power/hibernate.c
+++ b/kernel/power/hibernate.c
@@ -608,7 +608,11 @@  int hibernation_platform_enter(void)
 
 	local_irq_disable();
 	system_state = SYSTEM_SUSPEND;
-	syscore_suspend();
+
+	error = syscore_suspend();
+	if (error)
+		goto Enable_irqs;
+
 	if (pm_wakeup_pending()) {
 		error = -EAGAIN;
 		goto Power_up;
@@ -620,6 +624,7 @@  int hibernation_platform_enter(void)
 
  Power_up:
 	syscore_resume();
+ Enable_irqs:
 	system_state = SYSTEM_RUNNING;
 	local_irq_enable();