[PATCH] arm64/sme: Disable TIF_SME when loading state

From: Mark Brown

Date: Fri Jul 10 2026 - 13:25:27 EST


Normally once we have enabled SME access for a userspace task there is no
real overhead from leaving it on, unless userspace has enabled either
streaming mode or ZA there is no additional state to load and save beyond
SVCR. For systems affected by Arm erratum #4193714 this is not the case,
we must issue additional IPIs to CPUs running tasks using SME to ensure
visibility of memory accesses.

Mitigate this by disabling TIF_SME when we load the floating point state
for a task that does not have streaming mode or ZA enabled. These tasks
will then run with SME traps enabled until the next time that they
attempt to use SME or we load SME state via signal return or ptrace,
allowing them to avoid the overhead of enabling the erratum workaround.
CPUs are only added to the set of CPUs that require IPIs while in user
mode so will not be in it while the floating point state is being
loaded.

I have not directly verified the performance impact of this on affected
systems with practical workloads, hopefully users with such systems can
assess the impact and confirm if there is any benefit or not. Tasks that
use SME intermittently will experience additional SME access traps but
will not cause additional IPIs while SME has been disabled.

Signed-off-by: Mark Brown <broonie@xxxxxxxxxx>
---
arch/arm64/kernel/fpsimd.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 25dc5afe9ba0..7974dad5ea17 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -204,6 +204,10 @@ static inline void sme_free(struct task_struct *t) { }

#endif

+#ifdef CONFIG_ARM64_ERRATUM_4193714
+static cpumask_t sme_dvmsync_cpus;
+#endif
+
static void fpsimd_bind_task_to_cpu(void);

/*
@@ -404,6 +408,13 @@ static void task_fpsimd_load(void)
if (system_supports_sme()) {
unsigned long sme_vl = task_get_sme_vl(current);

+#ifdef CONFIG_ARM64_ERRATUM_4193714
+ if (alternative_has_cap_unlikely(ARM64_WORKAROUND_4193714) &&
+ cpumask_test_cpu(smp_processor_id(), &sme_dvmsync_cpus) &&
+ current->thread.svcr == 0)
+ clear_thread_flag(TIF_SME);
+#endif
+
/* Ensure VL is set up for restoring data */
if (test_thread_flag(TIF_SME)) {
unsigned long vq = sve_vq_from_vl(sme_vl);
@@ -1354,7 +1365,6 @@ void do_sve_acc(unsigned long esr, struct pt_regs *regs)
/*
* SME/CME erratum handling.
*/
-static cpumask_t sme_dvmsync_cpus;

/*
* These helpers are only called from non-preemptible contexts, so

---
base-commit: 8cdeaa50eae8dad34885515f62559ee83e7e8dda
change-id: 20260709-arm64-disable-sme-c5a361a1ebdb

Best regards,
--
Mark Brown <broonie@xxxxxxxxxx>