]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
arm64: fpsimd: Fold sve_init_regs() into do_sve_acc()
authorMark Rutland <mark.rutland@arm.com>
Wed, 3 Jun 2026 11:06:17 +0000 (12:06 +0100)
committerWill Deacon <will@kernel.org>
Wed, 3 Jun 2026 15:50:48 +0000 (16:50 +0100)
For historical reasons, do_sve_acc() is structurally different from
do_sme_acc(), and the logic to convert the task from FPSIMD to SVE is
out-of-line in sve_init_regs(). We only use sve_init_regs() within
do_sve_acc(), so it's not necessary for this to be a separate function.

Fold sve_init_regs() into do_sve_acc(), and simplify the associated
comments. This makes do_sve_acc() structurally similar to do_sme_acc(),
making it easier to see similarities and differences.

There should be no functional change as a result of this patch.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: Mark Brown <broonie@kernel.org>
Reviewed-by: Vladimir Murzin <vladimir.murzin@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Fuad Tabba <tabba@google.com>
Cc: James Morse <james.morse@arm.com>
Cc: Marc Zyngier <maz@kernel.org>
Cc: Oliver Upton <oupton@kernel.org>
Cc: Will Deacon <will@kernel.org>
Signed-off-by: Will Deacon <will@kernel.org>
arch/arm64/kernel/fpsimd.c

index 60a45d600b460a6cb104c4228ca426f8a72d1005..a8395cb303344122c143c79789ffb2eb83d540a3 100644 (file)
@@ -1293,31 +1293,6 @@ void sme_suspend_exit(void)
 
 #endif /* CONFIG_ARM64_SME */
 
-static void sve_init_regs(void)
-{
-       /*
-        * Convert the FPSIMD state to SVE, zeroing all the state that
-        * is not shared with FPSIMD. If (as is likely) the current
-        * state is live in the registers then do this there and
-        * update our metadata for the current task including
-        * disabling the trap, otherwise update our in-memory copy.
-        * We are guaranteed to not be in streaming mode, we can only
-        * take a SVE trap when not in streaming mode and we can't be
-        * in streaming mode when taking a SME trap.
-        */
-       if (!test_thread_flag(TIF_FOREIGN_FPSTATE)) {
-               unsigned long vq_minus_one =
-                       sve_vq_from_vl(task_get_sve_vl(current)) - 1;
-               sve_set_vq(vq_minus_one);
-               sve_flush_live(true, vq_minus_one);
-               fpsimd_bind_task_to_cpu();
-       } else {
-               fpsimd_to_sve(current);
-               current->thread.fp_type = FP_STATE_SVE;
-               fpsimd_flush_task_state(current);
-       }
-}
-
 /*
  * Trapped SVE access
  *
@@ -1349,13 +1324,24 @@ void do_sve_acc(unsigned long esr, struct pt_regs *regs)
                WARN_ON(1); /* SVE access shouldn't have trapped */
 
        /*
-        * Even if the task can have used streaming mode we can only
-        * generate SVE access traps in normal SVE mode and
-        * transitioning out of streaming mode may discard any
-        * streaming mode state.  Always clear the high bits to avoid
-        * any potential errors tracking what is properly initialised.
+        * Convert the FPSIMD state to SVE. Stale SVE state can be present in
+        * registers or memory, so we must zero all state that is not shared
+        * with FPSIMD.
+        *
+        * SVE traps cannot be taken from streaming mode, so there cannot be
+        * any effective streaming mode SVE state.
         */
-       sve_init_regs();
+       if (!test_thread_flag(TIF_FOREIGN_FPSTATE)) {
+               unsigned long vq_minus_one =
+                       sve_vq_from_vl(task_get_sve_vl(current)) - 1;
+               sve_set_vq(vq_minus_one);
+               sve_flush_live(true, vq_minus_one);
+               fpsimd_bind_task_to_cpu();
+       } else {
+               fpsimd_to_sve(current);
+               current->thread.fp_type = FP_STATE_SVE;
+               fpsimd_flush_task_state(current);
+       }
 
        put_cpu_fpsimd_context();
 }