Skip to content

Commit 128a749

Browse files
mrutland-armctmarinas
authored andcommitted
arm64/fpsimd: ptrace: Fix SVE writes on !SME systems
When SVE is supported but SME is not supported, a ptrace write to the NT_ARM_SVE regset can place the tracee into an invalid state where (non-streaming) SVE register data is stored in FP_STATE_SVE format but TIF_SVE is clear. This can result in a later warning from fpsimd_restore_current_state(), e.g. WARNING: CPU: 0 PID: 7214 at arch/arm64/kernel/fpsimd.c:383 fpsimd_restore_current_state+0x50c/0x748 When this happens, fpsimd_restore_current_state() will set TIF_SVE, placing the task into the correct state. This occurs before any other check of TIF_SVE can possibly occur, as other checks of TIF_SVE only happen while the FPSIMD/SVE/SME state is live. Thus, aside from the warning, there is no functional issue. This bug was introduced during rework to error handling in commit: 9f8bf71 ("arm64/fpsimd: ptrace: Gracefully handle errors") ... where the setting of TIF_SVE was moved into a block which is only executed when system_supports_sme() is true. Fix this by removing the system_supports_sme() check. This ensures that TIF_SVE is set for (SVE-formatted) writes to NT_ARM_SVE, at the cost of unconditionally manipulating the tracee's saved svcr value. The manipulation of svcr is benign and inexpensive, and we already do similar elsewhere (e.g. during signal handling), so I don't think it's worth guarding this with system_supports_sme() checks. Aside from the above, there is no functional change. The 'type' argument to sve_set_common() is only set to ARM64_VEC_SME (in ssve_set())) when system_supports_sme(), so the ARM64_VEC_SME case in the switch statement is still unreachable when !system_supports_sme(). When CONFIG_ARM64_SME=n, the only caller of sve_set_common() is sve_set(), and the compiler can constant-fold for the case where type is ARM64_VEC_SVE, removing the logic for other cases. Reported-by: syzbot+d4ab35af21e99d07ce67@syzkaller.appspotmail.com Fixes: 9f8bf71 ("arm64/fpsimd: ptrace: Gracefully handle errors") Signed-off-by: Mark Rutland <mark.rutland@arm.com> Cc: <stable@vger.kernel.org> Cc: Mark Brown <broonie@kernel.org> Cc: Will Deacon <will@kernel.org> Reviewed-by: Mark Brown <broonie@kernel.org> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
1 parent b9f5c38 commit 128a749

1 file changed

Lines changed: 12 additions & 14 deletions

File tree

arch/arm64/kernel/ptrace.c

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -968,20 +968,18 @@ static int sve_set_common(struct task_struct *target,
968968
vq = sve_vq_from_vl(task_get_vl(target, type));
969969

970970
/* Enter/exit streaming mode */
971-
if (system_supports_sme()) {
972-
switch (type) {
973-
case ARM64_VEC_SVE:
974-
target->thread.svcr &= ~SVCR_SM_MASK;
975-
set_tsk_thread_flag(target, TIF_SVE);
976-
break;
977-
case ARM64_VEC_SME:
978-
target->thread.svcr |= SVCR_SM_MASK;
979-
set_tsk_thread_flag(target, TIF_SME);
980-
break;
981-
default:
982-
WARN_ON_ONCE(1);
983-
return -EINVAL;
984-
}
971+
switch (type) {
972+
case ARM64_VEC_SVE:
973+
target->thread.svcr &= ~SVCR_SM_MASK;
974+
set_tsk_thread_flag(target, TIF_SVE);
975+
break;
976+
case ARM64_VEC_SME:
977+
target->thread.svcr |= SVCR_SM_MASK;
978+
set_tsk_thread_flag(target, TIF_SME);
979+
break;
980+
default:
981+
WARN_ON_ONCE(1);
982+
return -EINVAL;
985983
}
986984

987985
/* Always zero V regs, FPSR, and FPCR */

0 commit comments

Comments
 (0)