Skip to content

Commit e0cb0f2

Browse files
mrutland-armwilldeacon
authored andcommitted
arm64/fpsimd: Consistently preserve FPSIMD state during clone()
In arch_dup_task_struct() we try to ensure that the child task inherits the FPSIMD state of its parent, but this depends on the parent task's saved state being in FPSIMD format, which is not always the case. Consequently the child task may inherit stale FPSIMD state in some cases. This can happen when the parent's state has been modified by ptrace since syscall entry, as writes to the NT_ARM_SVE regset may save state in SVE format. This has been possible since commit: bc0ee47 ("arm64/sve: Core task context handling") More recently it has been possible for a task's FPSIMD/SVE state to be saved before lazy discarding was guaranteed to occur, in which case preemption could cause the effective FPSIMD state to be saved in SVE format non-deterministically. This has been possible since commit: f130ac0 ("arm64: syscall: unmask DAIF earlier for SVCs") Fix this by saving the parent task's effective FPSIMD state into FPSIMD format before copying the task_struct. As this requires modifying the parent's fpsimd_state, we must save+flush the state to avoid racing with concurrent manipulation. Similar issues exist when the parent has streaming mode state, and will be addressed by subsequent patches. Fixes: bc0ee47 ("arm64/sve: Core task context handling") Fixes: f130ac0 ("arm64: syscall: unmask DAIF earlier for SVCs") Signed-off-by: Mark Rutland <[email protected]> Cc: Catalin Marinas <[email protected]> Cc: Marc Zyngier <[email protected]> Cc: Mark Brown <[email protected]> Cc: Will Deacon <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Will Deacon <[email protected]>
1 parent 8d61eef commit e0cb0f2

File tree

1 file changed

+8
-1
lines changed

1 file changed

+8
-1
lines changed

arch/arm64/kernel/process.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,14 @@ void arch_release_task_struct(struct task_struct *tsk)
344344

345345
int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
346346
{
347-
fpsimd_preserve_current_state();
347+
/*
348+
* The current/src task's FPSIMD state may or may not be live, and may
349+
* have been altered by ptrace after entry to the kernel. Save the
350+
* effective FPSIMD state so that this will be copied into dst.
351+
*/
352+
fpsimd_save_and_flush_current_state();
353+
fpsimd_sync_from_effective_state(src);
354+
348355
*dst = *src;
349356

350357
/*

0 commit comments

Comments
 (0)