mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-31 12:52:29 -04:00
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>
This commit is contained in:
committed by
Will Deacon
parent
c9223b6162
commit
77345ef704
@@ -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))
|
|||||||
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))
|
|||||||
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))
|
|||||||
RCU_NONIDLE(__cpu_suspend_exit());
|
RCU_NONIDLE(__cpu_suspend_exit());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
arm_cpuidle_restore_irq_context(&context);
|
||||||
|
|
||||||
unpause_graph_tracing();
|
unpause_graph_tracing();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
Reference in New Issue
Block a user