Skip to content

Commit a0136be

Browse files
brooniewilldeacon
authored andcommitted
arm64/fpsimd: Load FP state based on recorded data type
Now that we are recording the type of floating point register state we are saving when we write the register state out to memory we can use that information when we load from memory to decide which format to load, bringing TIF_SVE into line with what we saved rather than relying on TIF_SVE to determine what to load. The SME state details are already recorded directly in the saved SVCR and handled based on the information there. Since we are not changing any of the save paths there should be no functional change from this patch, further patches will make use of this to optimise and clarify the code. Signed-off-by: Mark Brown <[email protected]> Reviewed-by: Catalin Marinas <[email protected]> Reviewed-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Will Deacon <[email protected]>
1 parent 62021cc commit a0136be

File tree

1 file changed

+32
-8
lines changed

1 file changed

+32
-8
lines changed

arch/arm64/kernel/fpsimd.c

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -395,11 +395,37 @@ static void task_fpsimd_load(void)
395395
WARN_ON(!system_supports_fpsimd());
396396
WARN_ON(!have_cpu_fpsimd_context());
397397

398-
/* Check if we should restore SVE first */
399-
if (IS_ENABLED(CONFIG_ARM64_SVE) && test_thread_flag(TIF_SVE)) {
400-
sve_set_vq(sve_vq_from_vl(task_get_sve_vl(current)) - 1);
401-
restore_sve_regs = true;
402-
restore_ffr = true;
398+
if (system_supports_sve()) {
399+
switch (current->thread.fp_type) {
400+
case FP_STATE_FPSIMD:
401+
/* Stop tracking SVE for this task until next use. */
402+
if (test_and_clear_thread_flag(TIF_SVE))
403+
sve_user_disable();
404+
break;
405+
case FP_STATE_SVE:
406+
if (!thread_sm_enabled(&current->thread) &&
407+
!WARN_ON_ONCE(!test_and_set_thread_flag(TIF_SVE)))
408+
sve_user_enable();
409+
410+
if (test_thread_flag(TIF_SVE))
411+
sve_set_vq(sve_vq_from_vl(task_get_sve_vl(current)) - 1);
412+
413+
restore_sve_regs = true;
414+
restore_ffr = true;
415+
break;
416+
default:
417+
/*
418+
* This indicates either a bug in
419+
* fpsimd_save() or memory corruption, we
420+
* should always record an explicit format
421+
* when we save. We always at least have the
422+
* memory allocated for FPSMID registers so
423+
* try that and hope for the best.
424+
*/
425+
WARN_ON_ONCE(1);
426+
clear_thread_flag(TIF_SVE);
427+
break;
428+
}
403429
}
404430

405431
/* Restore SME, override SVE register configuration if needed */
@@ -415,10 +441,8 @@ static void task_fpsimd_load(void)
415441
if (thread_za_enabled(&current->thread))
416442
za_load_state(current->thread.za_state);
417443

418-
if (thread_sm_enabled(&current->thread)) {
419-
restore_sve_regs = true;
444+
if (thread_sm_enabled(&current->thread))
420445
restore_ffr = system_supports_fa64();
421-
}
422446
}
423447

424448
if (restore_sve_regs) {

0 commit comments

Comments
 (0)