[SRU][J:linux-bluefield][PATCH v1 5/7] arm64: fpsimd: Implement lazy restore for kernel mode FPSIMD
Stav Aviram
saviram at nvidia.com
Thu Aug 7 13:33:23 UTC 2025
From: Ard Biesheuvel <ardb at kernel.org>
BugLink: https://bugs.launchpad.net/bugs/2119457
Now that kernel mode FPSIMD state is context switched along with other
task state, we can enable the existing logic that keeps track of which
task's FPSIMD state the CPU is holding in its registers. If it is the
context of the task that we are switching to, we can elide the reload of
the FPSIMD state from memory.
Note that we also need to check whether the FPSIMD state on this CPU is
the most recent: if a task gets migrated away and back again, the state
in memory may be more recent than the state in the CPU. So add another
CPU id field to task_struct to keep track of this. (We could reuse the
existing CPU id field used for user mode context, but that might result
in user state to be discarded unnecessarily, given that two distinct
CPUs could be holding the most recent user mode state and the most
recent kernel mode state)
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
Reviewed-by: Mark Brown <broonie at kernel.org>
Acked-by: Mark Rutland <mark.rutland at arm.com>
Link: https://lore.kernel.org/r/20231208113218.3001940-9-ardb@google.com
Signed-off-by: Will Deacon <will at kernel.org>
(cherry picked from commit 2632e25217696712681dd1f3ecc0d71624ea3b23)
Signed-off-by: Stav Aviram <saviram at nvidia.com>
---
arch/arm64/include/asm/processor.h | 1 +
arch/arm64/kernel/fpsimd.c | 18 ++++++++++++++++++
2 files changed, 19 insertions(+)
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index cd6d0ae2184c..e221ecaa5f26 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -161,6 +161,7 @@ struct thread_struct {
struct debug_info debug; /* debugging */
struct user_fpsimd_state kernel_fpsimd_state;
+ unsigned int kernel_fpsimd_cpu;
#ifdef CONFIG_ARM64_PTR_AUTH
struct ptrauth_keys_user keys_user;
#ifdef CONFIG_ARM64_PTR_AUTH_KERNEL
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index c966d070d78f..dfda0972d1c1 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -1018,12 +1018,30 @@ void do_fpsimd_exc(unsigned long esr, struct pt_regs *regs)
static void fpsimd_load_kernel_state(struct task_struct *task)
{
+ struct cpu_fp_state *last = this_cpu_ptr(&fpsimd_last_state);
+
+ /*
+ * Elide the load if this CPU holds the most recent kernel mode
+ * FPSIMD context of the current task.
+ */
+ if (last->st == &task->thread.kernel_fpsimd_state &&
+ task->thread.kernel_fpsimd_cpu == smp_processor_id())
+ return;
+
fpsimd_load_state(&task->thread.kernel_fpsimd_state);
}
static void fpsimd_save_kernel_state(struct task_struct *task)
{
+ struct cpu_fp_state cpu_fp_state = {
+ .st = &task->thread.kernel_fpsimd_state,
+ .to_save = FP_STATE_FPSIMD,
+ };
+
fpsimd_save_state(&task->thread.kernel_fpsimd_state);
+ fpsimd_bind_state_to_cpu(&cpu_fp_state);
+
+ task->thread.kernel_fpsimd_cpu = smp_processor_id();
}
void fpsimd_thread_switch(struct task_struct *next)
--
2.34.1
More information about the kernel-team
mailing list