From 05fe0e436747357d21aa8fcfc392a44051a0a68f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 25 May 2024 16:44:33 +0200 Subject: [PATCH] 6.9-stable patches added patches: arm64-fpsimd-avoid-erroneous-elide-of-user-state-reload.patch series --- ...erroneous-elide-of-user-state-reload.patch | 123 ++++++++++++++++++ queue-6.9/series | 1 + 2 files changed, 124 insertions(+) create mode 100644 queue-6.9/arm64-fpsimd-avoid-erroneous-elide-of-user-state-reload.patch create mode 100644 queue-6.9/series diff --git a/queue-6.9/arm64-fpsimd-avoid-erroneous-elide-of-user-state-reload.patch b/queue-6.9/arm64-fpsimd-avoid-erroneous-elide-of-user-state-reload.patch new file mode 100644 index 00000000000..0482d721016 --- /dev/null +++ b/queue-6.9/arm64-fpsimd-avoid-erroneous-elide-of-user-state-reload.patch @@ -0,0 +1,123 @@ +From e92bee9f861b466c676f0200be3e46af7bc4ac6b Mon Sep 17 00:00:00 2001 +From: Ard Biesheuvel +Date: Wed, 22 May 2024 11:13:36 +0200 +Subject: arm64/fpsimd: Avoid erroneous elide of user state reload + +From: Ard Biesheuvel + +commit e92bee9f861b466c676f0200be3e46af7bc4ac6b upstream. + +TIF_FOREIGN_FPSTATE is a 'convenience' flag that should reflect whether +the current CPU holds the most recent user mode FP/SIMD state of the +current task. It combines two conditions: +- whether the current CPU's FP/SIMD state belongs to the task; +- whether that state is the most recent associated with the task (as a + task may have executed on other CPUs as well). + +When a task is scheduled in and TIF_KERNEL_FPSTATE is set, it means the +task was in a kernel mode NEON section when it was scheduled out, and so +the kernel mode FP/SIMD state is restored. Since this implies that the +current CPU is *not* holding the most recent user mode FP/SIMD state of +the current task, the TIF_FOREIGN_FPSTATE flag is set too, so that the +user mode FP/SIMD state is reloaded from memory when returning to +userland. + +However, the task may be scheduled out after completing the kernel mode +NEON section, but before returning to userland. When this happens, the +TIF_FOREIGN_FPSTATE flag will not be preserved, but will be set as usual +the next time the task is scheduled in, and will be based on the above +conditions. + +This means that, rather than setting TIF_FOREIGN_FPSTATE when scheduling +in a task with TIF_KERNEL_FPSTATE set, the underlying state should be +updated so that TIF_FOREIGN_FPSTATE will assume the expected value as a +result. + +So instead, call fpsimd_flush_cpu_state(), which takes care of this. + +Closes: https://lore.kernel.org/all/cb8822182231850108fa43e0446a4c7f@kernel.org +Reported-by: Johannes Nixdorf +Fixes: aefbab8e77eb ("arm64: fpsimd: Preserve/restore kernel mode NEON at context switch") +Cc: Mark Brown +Cc: Dave Martin +Cc: Janne Grunau +Cc: stable@vger.kernel.org +Signed-off-by: Ard Biesheuvel +Tested-by: Janne Grunau +Tested-by: Johannes Nixdorf +Reviewed-by: Mark Brown +Link: https://lore.kernel.org/r/20240522091335.335346-2-ardb+git@google.com +Signed-off-by: Will Deacon +Cc: Florian Klink +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm64/kernel/fpsimd.c | 44 ++++++++++++++++++++++---------------------- + 1 file changed, 22 insertions(+), 22 deletions(-) + +--- a/arch/arm64/kernel/fpsimd.c ++++ b/arch/arm64/kernel/fpsimd.c +@@ -1535,6 +1535,27 @@ static void fpsimd_save_kernel_state(str + task->thread.kernel_fpsimd_cpu = smp_processor_id(); + } + ++/* ++ * Invalidate any task's FPSIMD state that is present on this cpu. ++ * The FPSIMD context should be acquired with get_cpu_fpsimd_context() ++ * before calling this function. ++ */ ++static void fpsimd_flush_cpu_state(void) ++{ ++ WARN_ON(!system_supports_fpsimd()); ++ __this_cpu_write(fpsimd_last_state.st, NULL); ++ ++ /* ++ * Leaving streaming mode enabled will cause issues for any kernel ++ * NEON and leaving streaming mode or ZA enabled may increase power ++ * consumption. ++ */ ++ if (system_supports_sme()) ++ sme_smstop(); ++ ++ set_thread_flag(TIF_FOREIGN_FPSTATE); ++} ++ + void fpsimd_thread_switch(struct task_struct *next) + { + bool wrong_task, wrong_cpu; +@@ -1552,7 +1573,7 @@ void fpsimd_thread_switch(struct task_st + + if (test_tsk_thread_flag(next, TIF_KERNEL_FPSTATE)) { + fpsimd_load_kernel_state(next); +- set_tsk_thread_flag(next, TIF_FOREIGN_FPSTATE); ++ fpsimd_flush_cpu_state(); + } else { + /* + * Fix up TIF_FOREIGN_FPSTATE to correctly describe next's +@@ -1843,27 +1864,6 @@ void fpsimd_flush_task_state(struct task + } + + /* +- * Invalidate any task's FPSIMD state that is present on this cpu. +- * The FPSIMD context should be acquired with get_cpu_fpsimd_context() +- * before calling this function. +- */ +-static void fpsimd_flush_cpu_state(void) +-{ +- WARN_ON(!system_supports_fpsimd()); +- __this_cpu_write(fpsimd_last_state.st, NULL); +- +- /* +- * Leaving streaming mode enabled will cause issues for any kernel +- * NEON and leaving streaming mode or ZA enabled may increase power +- * consumption. +- */ +- if (system_supports_sme()) +- sme_smstop(); +- +- set_thread_flag(TIF_FOREIGN_FPSTATE); +-} +- +-/* + * Save the FPSIMD state to memory and invalidate cpu view. + * This function must be called with preemption disabled. + */ diff --git a/queue-6.9/series b/queue-6.9/series new file mode 100644 index 00000000000..71bf0447f0f --- /dev/null +++ b/queue-6.9/series @@ -0,0 +1 @@ +arm64-fpsimd-avoid-erroneous-elide-of-user-state-reload.patch -- 2.47.3