FROMGIT: arm64/fpsimd: Add task_smstop_sm()
In a few places we want to transition a task from streaming mode to
non-streaming mode, e.g. signal delivery where we historically tried to
use an SMSTOP SM instruction.
Add a new helper to manipulate a task's state in the same way as an
SMSTOP SM instruction. I have not added a corresponding helper to
simulate the effects of SMSTART SM. Only ptrace transitions a task into
streaming mode, and ptrace has distinct semantics for such transitions.
Per ARM DDI 0487 L.a, section B1.4.6:
| RRSWFQ
| When the Effective value of PSTATE.SM is changed by any method from 0
| to 1, an entry to Streaming SVE mode is performed, and all implemented
| bits of Streaming SVE register state are set to zero.
| RKFRQZ
| When the Effective value of PSTATE.SM is changed by any method from 1
| to 0, an exit from Streaming SVE mode is performed, and in the
| newly-entered mode, all implemented bits of the SVE scalable vector
| registers, SVE predicate registers, and FFR, are set to zero.
Per ARM DDI 0487 L.a, section C5.2.9:
| On entry to or exit from Streaming SVE mode, FPMR is set to 0
Per ARM DDI 0487 L.a, section C5.2.10:
| On entry to or exit from Streaming SVE mode, FPSR.{IOC, DZC, OFC, UFC,
| IXC, IDC, QC} are set to 1 and the remaining bits are set to 0.
This means bits 0, 1, 2, 3, 4, 7, and 27 respectively, i.e. 0x0800009f
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Marc Zyngier <maz@kernel.org>
Cc: Mark Brown <broonie@kernel.org>
Cc: Will Deacon <will@kernel.org>
Link: https://lore.kernel.org/r/20250508132644.1395904-9-mark.rutland@arm.com
Signed-off-by: Will Deacon <will@kernel.org>
(cherry picked from commit 6ef1d778ce56c5bde1ac0a1f85fd9710efde6724
https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git
for-next/sme-fixes)
Bug: 393087661
Signed-off-by: Will Deacon <willdeacon@google.com>
Change-Id: I505fefc23f21109920ba985604efc98697b42b75
This commit is contained in:
committed by
Will Deacon
parent
73106ecef5
commit
f940d322b6
@@ -112,6 +112,8 @@ static inline bool thread_za_enabled(struct thread_struct *thread)
|
||||
return system_supports_sme() && (thread->svcr & SVCR_ZA_MASK);
|
||||
}
|
||||
|
||||
extern void task_smstop_sm(struct task_struct *task);
|
||||
|
||||
/* Maximum VL that SVE/SME VL-agnostic software can transparently support */
|
||||
#define VL_ARCH_MAX 0x100
|
||||
|
||||
|
||||
@@ -695,6 +695,28 @@ static inline void sve_to_fpsimd(struct task_struct *task)
|
||||
}
|
||||
}
|
||||
|
||||
static inline void __fpsimd_zero_vregs(struct user_fpsimd_state *fpsimd)
|
||||
{
|
||||
memset(&fpsimd->vregs, 0, sizeof(fpsimd->vregs));
|
||||
}
|
||||
|
||||
/*
|
||||
* Simulate the effects of an SMSTOP SM instruction.
|
||||
*/
|
||||
void task_smstop_sm(struct task_struct *task)
|
||||
{
|
||||
if (!thread_sm_enabled(&task->thread))
|
||||
return;
|
||||
|
||||
__fpsimd_zero_vregs(&task->thread.uw.fpsimd_state);
|
||||
task->thread.uw.fpsimd_state.fpsr = 0x0800009f;
|
||||
if (system_supports_fpmr())
|
||||
task->thread.uw.fpmr = 0;
|
||||
|
||||
task->thread.svcr &= ~SVCR_SM_MASK;
|
||||
task->thread.fp_type = FP_STATE_FPSIMD;
|
||||
}
|
||||
|
||||
void cpu_enable_fpmr(const struct arm64_cpu_capabilities *__always_unused p)
|
||||
{
|
||||
write_sysreg_s(read_sysreg_s(SYS_SCTLR_EL1) | SCTLR_EL1_EnFPM_MASK,
|
||||
|
||||
Reference in New Issue
Block a user