arch: arm64: add early_param idle=<wfi|yield|nop>

Overriding the idle mechanism might be useful for debugging and performance
testing. Add a cmdline parameter for it, similar to the existing idle=
parameter already present for the x86 and ppc architectures.

It is also useful on platforms where the WFI instruction misbehaves,
such as Apple Silicon SoCs. Generally, a misbehaving instruction should
be treated as an erratum and patched using the alternatives framework.
However, in the Apple Silicon case we need more flexibility because it is
difficult to detect whether the erratum applies. For example, Linux VMs
inside macOS have the same MIDR and may even seem like they're running
in EL2 in the case of NV, but should continue using WFI (it's trapped and
handled correctly by the hypervisor there). Thus, we prefer to
let the m1n1 bootloader add the idle=nop parameter[1].

Link[1]: https://lore.kernel.org/all/99b69262-e54b-424e-baa2-96ef7013b87a@kernel.org/
Suggested-by: Will Deacon <will@kernel.org>
Signed-off-by: Yureka Lilian <yureka@cyberchaos.dev>
Signed-off-by: Will Deacon <will@kernel.org>
This commit is contained in:
Yureka Lilian 2026-08-04 19:23:15 +02:00 committed by Will Deacon
parent 2f6fc06126
commit d97afae6f1
2 changed files with 53 additions and 2 deletions

View File

@ -2236,6 +2236,29 @@ Kernel parameters
idle=nomwait: Disable mwait for CPU C-states
[ARM64,EARLY]
Format: idle=wfi, idle=yield, idle=nop
idle=wfi: Use the WFI (Wait For Interrupt) hint
instruction in the idle loop. This is the default and
allows the CPU to enter a low-power state until an
interrupt arrives.
idle=yield: Use the YIELD hint instruction instead of
WFI. CPUs supporting simultaneous multi-threading (SMT),
can continue executing another thread when the current
thread reaches the idle loop. This will make the CPUs
eat more power, but may be useful to get slightly better
performance in some applications, since the CPUs will
not enter a low-power state.
idle=nop: Do not execute any idle instruction in the
idle loop. This is useful on platforms where WFI
misbehaves, leading to system instability or loss of CPU
state. This will make the CPUs eat more power, but may
give slightly better performance in some applications,
since the CPUs will not enter a low-power state.
idxd.sva= [HW]
Format: <bool>
Allow force disabling of Shared Virtual Memory (SVA)

View File

@ -11,6 +11,29 @@
#include <asm/cpufeature.h>
#include <asm/sysreg.h>
enum {
ARM64_IDLE_WFI,
ARM64_IDLE_YIELD,
ARM64_IDLE_NOP,
} idle = ARM64_IDLE_WFI;
static int __init setup_idle(char *arg)
{
if (!arg)
return -1;
else if (!strcmp(arg, "wfi"))
idle = ARM64_IDLE_WFI;
else if (!strcmp(arg, "yield"))
idle = ARM64_IDLE_YIELD;
else if (!strcmp(arg, "nop"))
idle = ARM64_IDLE_NOP;
else
return -1;
return 0;
}
early_param("idle", setup_idle);
/*
* cpu_do_idle()
*
@ -26,8 +49,13 @@ void __cpuidle cpu_do_idle(void)
arm_cpuidle_save_irq_context(&context);
dsb(sy);
wfi();
if (likely(idle == ARM64_IDLE_WFI)) {
dsb(sy);
wfi();
} else if (idle == ARM64_IDLE_YIELD) {
dsb(sy);
asm volatile("yield" ::: "memory");
}
arm_cpuidle_restore_irq_context(&context);
}