From: Will Deacon <will@kernel.org>
To: Yureka Lilian <yureka@cyberchaos.dev>
Cc: Catalin Marinas <catalin.marinas@arm.com>,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, asahi@lists.linux.dev,
Sasha Finkelstein <k@chaosmail.tech>
Subject: Re: [PATCH v2] arm64: errata: Handle Apple WFI State Loss
Date: Mon, 15 Jun 2026 16:02:13 +0100 [thread overview]
Message-ID: <ajAT9fWgOd9HY7ei@willie-the-truck> (raw)
In-Reply-To: <20260615-wfi-erratum-v2-1-59a73467f70d@cyberchaos.dev>
On Mon, Jun 15, 2026 at 02:21:36PM +0200, Yureka Lilian wrote:
> Apple Silicon CPUs can lose register state in WFI, leading to crashes
> in the idle loop early in the boot process.
> This applies to any previous Apple Silicon CPUs too, but is worked
> around by configuring the WFI mode in SYS_IMP_APL_CYC_OVRD sysreg
> during m1n1's chickens setup.
> This workaround no longer exists since M4.
>
> Add a workaround capability for replacing wfi and wfit with nop, and
> an erratum to enable it on the affected CPUs if the workaround using the
> sysreg is not already applied. Leave the decision whether the sysreg
> workaround can be used up to the earlier parts of the boot chain which
> already configure the Apple Silicon chicken bits.
>
> This alternative has to be applied in early boot, since otherwise some
> cores might enter the idle loop before apply_alternatives_all() is run.
>
> Reviewed-by: Sasha Finkelstein <k@chaosmail.tech>
> Signed-off-by: Yureka Lilian <yureka@cyberchaos.dev>
> ---
> Changes since v1:
> Restricted the erratum to EL2 only, since in EL1 we'd expect the
> hypervisor to trap WFI and handle the erratum.
>
> Tested on M4 and M4 Pro (which now sometimes nondeterministically
> crash later during boot).
> Successfully booted on M3 Max with the SYS_IMP_APL_CYC_OVRD
> workaround disabled in the bootloader, as well as A18 Pro (which,
> like M4 / M4 Pro, doesn't have SYS_IMP_APL_CYC_OVRD).
>
> There is probably a better place for the SYS_IMP_APL_CYC_OVRD
> defines, which I currently put in the middle of cpu_errata.c, but I
> wouldn't know where.
> ---
> arch/arm64/Kconfig | 12 ++++++++++++
> arch/arm64/include/asm/barrier.h | 19 ++++++++++++++++---
> arch/arm64/kernel/cpu_errata.c | 21 +++++++++++++++++++++
> arch/arm64/tools/cpucaps | 1 +
> 4 files changed, 50 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index b3afe0688919..8c8ff069856f 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -453,6 +453,18 @@ config AMPERE_ERRATUM_AC04_CPU_23
>
> If unsure, say Y.
>
> +config APPLE_ERRATUM_WFI_STATE
> + bool "Apple Silicon: WFI loses state"
> + default y
> + help
> + This option adds an alternative code sequence to work around some
> + Apple Silicon CPUs losing register state during wfi and wfit
> + instructions.
> +
> + As a workaround, the wfi and wfit instructions are replaced with nop
> + operations via the alternative framework if an affected CPU is
> + detected.
> +
> config ARM64_WORKAROUND_CLEAN_CACHE
> bool
>
> diff --git a/arch/arm64/include/asm/barrier.h b/arch/arm64/include/asm/barrier.h
> index 9495c4441a46..f72eddc7c434 100644
> --- a/arch/arm64/include/asm/barrier.h
> +++ b/arch/arm64/include/asm/barrier.h
> @@ -20,9 +20,22 @@
> #define wfe() asm volatile("wfe" : : : "memory")
> #define wfet(val) asm volatile("msr s0_3_c1_c0_0, %0" \
> : : "r" (val) : "memory")
> -#define wfi() asm volatile("wfi" : : : "memory")
> -#define wfit(val) asm volatile("msr s0_3_c1_c0_1, %0" \
> - : : "r" (val) : "memory")
> +#define wfi() \
> + do { \
> + asm volatile( \
> + ALTERNATIVE("wfi", \
> + "nop", \
> + ARM64_WORKAROUND_WFI_STATE) \
> + : : : "memory"); \
> + } while (0)
> +#define wfit(val) \
> + do { \
> + asm volatile( \
> + ALTERNATIVE("msr s0_3_c1_c0_1, %0", \
> + "nop", \
> + ARM64_WORKAROUND_WFI_STATE) \
> + : : "r" (val) : "memory"); \
> + } while (0)
How can you guarantee that we don't run one of these prior to patching?
I wonder if we're better off doing something like x86 and having an "idle="
cmdline option. which could choose between e.g. nop, wfe, wfi and yield, for
example? In fact, would wfe be a better choice than nop for you?
Will
next prev parent reply other threads:[~2026-06-15 15:02 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-15 12:21 [PATCH v2] arm64: errata: Handle Apple WFI State Loss Yureka Lilian
2026-06-15 12:59 ` Nick Chan
2026-06-15 15:02 ` Will Deacon [this message]
2026-06-15 15:27 ` Sven Peter
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ajAT9fWgOd9HY7ei@willie-the-truck \
--to=will@kernel.org \
--cc=asahi@lists.linux.dev \
--cc=catalin.marinas@arm.com \
--cc=k@chaosmail.tech \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=yureka@cyberchaos.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox