arm64: fpsimd: Fold sve_init_regs() into do_sve_acc()
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>
This commit is contained in:
1 parent
afd7af2b56
commit
3efb6c7f22
1 file changed
+17
-31
+17
-31
@@ -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();
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user