Commit 77345ef7 authored by Marc Zyngier's avatar Marc Zyngier Committed by Will Deacon

arm64: suspend: Use cpuidle context helpers in cpu_suspend()

Use cpuidle context helpers to switch to using DAIF.IF instead
of PMR to mask interrupts, ensuring that we suspend with
interrupts being able to reach the CPU interface.
Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
Reviewed-by: default avatarSudeep Holla <sudeep.holla@arm.com>
Link: https://lore.kernel.org/r/20210615111227.2454465-5-maz@kernel.orgSigned-off-by: default avatarWill Deacon <will@kernel.org>
parent c9223b61
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <asm/alternative.h> #include <asm/alternative.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/cpufeature.h> #include <asm/cpufeature.h>
#include <asm/cpuidle.h>
#include <asm/daifflags.h> #include <asm/daifflags.h>
#include <asm/debug-monitors.h> #include <asm/debug-monitors.h>
#include <asm/exec.h> #include <asm/exec.h>
...@@ -91,6 +92,7 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long)) ...@@ -91,6 +92,7 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
int ret = 0; int ret = 0;
unsigned long flags; unsigned long flags;
struct sleep_stack_data state; struct sleep_stack_data state;
struct arm_cpuidle_irq_context context;
/* Report any MTE async fault before going to suspend */ /* Report any MTE async fault before going to suspend */
mte_suspend_enter(); mte_suspend_enter();
...@@ -103,12 +105,18 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long)) ...@@ -103,12 +105,18 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
flags = local_daif_save(); flags = local_daif_save();
/* /*
* Function graph tracer state gets incosistent when the kernel * Function graph tracer state gets inconsistent when the kernel
* calls functions that never return (aka suspend finishers) hence * calls functions that never return (aka suspend finishers) hence
* disable graph tracing during their execution. * disable graph tracing during their execution.
*/ */
pause_graph_tracing(); pause_graph_tracing();
/*
* Switch to using DAIF.IF instead of PMR in order to reliably
* resume if we're using pseudo-NMIs.
*/
arm_cpuidle_save_irq_context(&context);
if (__cpu_suspend_enter(&state)) { if (__cpu_suspend_enter(&state)) {
/* Call the suspend finisher */ /* Call the suspend finisher */
ret = fn(arg); ret = fn(arg);
...@@ -126,6 +134,8 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long)) ...@@ -126,6 +134,8 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
RCU_NONIDLE(__cpu_suspend_exit()); RCU_NONIDLE(__cpu_suspend_exit());
} }
arm_cpuidle_restore_irq_context(&context);
unpause_graph_tracing(); unpause_graph_tracing();
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment