Skip to content

Commit 77345ef

Browse files
Marc Zyngierwilldeacon
authored andcommitted
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: Marc Zyngier <maz@kernel.org> Reviewed-by: Sudeep Holla <sudeep.holla@arm.com> Link: https://lore.kernel.org/r/20210615111227.2454465-5-maz@kernel.org Signed-off-by: Will Deacon <will@kernel.org>
1 parent c9223b6 commit 77345ef

1 file changed

Lines changed: 11 additions & 1 deletion

File tree

arch/arm64/kernel/suspend.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <asm/alternative.h>
88
#include <asm/cacheflush.h>
99
#include <asm/cpufeature.h>
10+
#include <asm/cpuidle.h>
1011
#include <asm/daifflags.h>
1112
#include <asm/debug-monitors.h>
1213
#include <asm/exec.h>
@@ -91,6 +92,7 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
9192
int ret = 0;
9293
unsigned long flags;
9394
struct sleep_stack_data state;
95+
struct arm_cpuidle_irq_context context;
9496

9597
/* Report any MTE async fault before going to suspend */
9698
mte_suspend_enter();
@@ -103,12 +105,18 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
103105
flags = local_daif_save();
104106

105107
/*
106-
* Function graph tracer state gets incosistent when the kernel
108+
* Function graph tracer state gets inconsistent when the kernel
107109
* calls functions that never return (aka suspend finishers) hence
108110
* disable graph tracing during their execution.
109111
*/
110112
pause_graph_tracing();
111113

114+
/*
115+
* Switch to using DAIF.IF instead of PMR in order to reliably
116+
* resume if we're using pseudo-NMIs.
117+
*/
118+
arm_cpuidle_save_irq_context(&context);
119+
112120
if (__cpu_suspend_enter(&state)) {
113121
/* Call the suspend finisher */
114122
ret = fn(arg);
@@ -126,6 +134,8 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
126134
RCU_NONIDLE(__cpu_suspend_exit());
127135
}
128136

137+
arm_cpuidle_restore_irq_context(&context);
138+
129139
unpause_graph_tracing();
130140

131141
/*

0 commit comments

Comments
 (0)