Skip to content

Commit b255be4

Browse files
mrutland-armwilldeacon
authored andcommitted
arm64/fpsimd: Clarify sve_sync_*() functions
The sve_sync_{to,from}_fpsimd*() functions are intended to extract/insert the currently effective FPSIMD state of a task regardless of whether the task's state is saved in FPSIMD format or SVE format. Historically they were only used by ptrace, but sve_sync_to_fpsimd() is now used more widely, and sve_sync_from_fpsimd_zeropad() may be used more widely in future. When FPSIMD/SVE state tracking was changed across commits: baa8515 ("arm64/fpsimd: Track the saved FPSIMD state type separately to TIF_SVE") a0136be (arm64/fpsimd: Load FP state based on recorded data type") bbc6172 ("arm64/fpsimd: SME no longer requires SVE register state") 8c845e2 ("arm64/sve: Leave SVE enabled on syscall if we don't context switch") ... sve_sync_to_fpsimd() was updated to consider task->thread.fp_type rather than the task's TIF_SVE and PSTATE.SM, but (apparently due to an oversight) sve_sync_from_fpsimd_zeropad() was left as-is, leaving the two inconsistent. Due to this, sve_sync_from_fpsimd_zeropad() may copy state from task->thread.uw.fpsimd_state into task->thread.sve_state when task->thread.fp_type == FP_STATE_FPSIMD. This is redundant (but benign) as task->thread.uw.fpsimd_state is the effective state that will be restored, and task->thread.sve_state will not be consumed. For consistency, and to avoid the redundant work, it better for sve_sync_from_fpsimd_zeropad() to consider task->thread.fp_type alone, matching sve_sync_to_fpsimd(). The naming of both functions is somehat unfortunate, as it is unclear when and why they copy state. It would be better to describe them in terms of the effective state. Considering all of the above, clean this up: * Adjust sve_sync_from_fpsimd_zeropad() to consider task->thread.fp_type. * Update comments to clarify the intended semantics/usage. I've removed the description that task->thread.sve_state must have been allocated, as this is only necessary when task->thread.fp_type == FP_STATE_SVE, which itself implies that task->thread.sve_state must have been allocated. * Rename the functions to more clearly indicate when/why they copy state: - sve_sync_to_fpsimd() => fpsimd_sync_from_effective_state() - sve_sync_from_fpsimd_zeropad => fpsimd_sync_to_effective_state_zeropad() 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 316283f commit b255be4

File tree

4 files changed

+20
-26
lines changed

4 files changed

+20
-26
lines changed

arch/arm64/include/asm/fpsimd.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,8 @@ struct vl_info {
198198

199199
extern void sve_alloc(struct task_struct *task, bool flush);
200200
extern void fpsimd_release_task(struct task_struct *task);
201-
extern void sve_sync_to_fpsimd(struct task_struct *task);
202-
extern void sve_sync_from_fpsimd_zeropad(struct task_struct *task);
201+
extern void fpsimd_sync_from_effective_state(struct task_struct *task);
202+
extern void fpsimd_sync_to_effective_state_zeropad(struct task_struct *task);
203203

204204
extern int vec_set_vector_length(struct task_struct *task, enum vec_type type,
205205
unsigned long vl, unsigned long flags);
@@ -299,8 +299,8 @@ size_t sve_state_size(struct task_struct const *task);
299299

300300
static inline void sve_alloc(struct task_struct *task, bool flush) { }
301301
static inline void fpsimd_release_task(struct task_struct *task) { }
302-
static inline void sve_sync_to_fpsimd(struct task_struct *task) { }
303-
static inline void sve_sync_from_fpsimd_zeropad(struct task_struct *task) { }
302+
static inline void fpsimd_sync_from_effective_state(struct task_struct *task) { }
303+
static inline void fpsimd_sync_to_effective_state_zeropad(struct task_struct *task) { }
304304

305305
static inline int sve_max_virtualisable_vl(void)
306306
{

arch/arm64/kernel/fpsimd.c

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -760,39 +760,33 @@ void sve_alloc(struct task_struct *task, bool flush)
760760
}
761761

762762
/*
763-
* Ensure that task->thread.uw.fpsimd_state is up to date with respect to
764-
* the user task, irrespective of whether SVE is in use or not.
763+
* Ensure that task->thread.uw.fpsimd_state is up to date with respect to the
764+
* task's currently effective FPSIMD/SVE state.
765765
*
766-
* This should only be called by ptrace. task must be non-runnable.
767-
* task->thread.sve_state must point to at least sve_state_size(task)
768-
* bytes of allocated kernel memory.
766+
* The task's FPSIMD/SVE/SME state must not be subject to concurrent
767+
* manipulation.
769768
*/
770-
void sve_sync_to_fpsimd(struct task_struct *task)
769+
void fpsimd_sync_from_effective_state(struct task_struct *task)
771770
{
772771
if (task->thread.fp_type == FP_STATE_SVE)
773772
sve_to_fpsimd(task);
774773
}
775774

776775
/*
777-
* Ensure that task->thread.sve_state is up to date with respect to
778-
* the task->thread.uw.fpsimd_state.
776+
* Ensure that the task's currently effective FPSIMD/SVE state is up to date
777+
* with respect to task->thread.uw.fpsimd_state, zeroing any effective
778+
* non-FPSIMD (S)SVE state.
779779
*
780-
* This should only be called by ptrace to merge new FPSIMD register
781-
* values into a task for which SVE is currently active.
782-
* task must be non-runnable.
783-
* task->thread.sve_state must point to at least sve_state_size(task)
784-
* bytes of allocated kernel memory.
785-
* task->thread.uw.fpsimd_state must already have been initialised with
786-
* the new FPSIMD register values to be merged in.
780+
* The task's FPSIMD/SVE/SME state must not be subject to concurrent
781+
* manipulation.
787782
*/
788-
void sve_sync_from_fpsimd_zeropad(struct task_struct *task)
783+
void fpsimd_sync_to_effective_state_zeropad(struct task_struct *task)
789784
{
790785
unsigned int vq;
791786
void *sst = task->thread.sve_state;
792787
struct user_fpsimd_state const *fst = &task->thread.uw.fpsimd_state;
793788

794-
if (!test_tsk_thread_flag(task, TIF_SVE) &&
795-
!thread_sm_enabled(&task->thread))
789+
if (task->thread.fp_type != FP_STATE_SVE)
796790
return;
797791

798792
vq = sve_vq_from_vl(thread_get_cur_vl(&task->thread));

arch/arm64/kernel/ptrace.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,7 @@ static int __fpr_get(struct task_struct *target,
594594
{
595595
struct user_fpsimd_state *uregs;
596596

597-
sve_sync_to_fpsimd(target);
597+
fpsimd_sync_from_effective_state(target);
598598

599599
uregs = &target->thread.uw.fpsimd_state;
600600

@@ -626,7 +626,7 @@ static int __fpr_set(struct task_struct *target,
626626
* Ensure target->thread.uw.fpsimd_state is up to date, so that a
627627
* short copyin can't resurrect stale data.
628628
*/
629-
sve_sync_to_fpsimd(target);
629+
fpsimd_sync_from_effective_state(target);
630630

631631
newstate = target->thread.uw.fpsimd_state;
632632

@@ -653,7 +653,7 @@ static int fpr_set(struct task_struct *target, const struct user_regset *regset,
653653
if (ret)
654654
return ret;
655655

656-
sve_sync_from_fpsimd_zeropad(target);
656+
fpsimd_sync_to_effective_state_zeropad(target);
657657
fpsimd_flush_task_state(target);
658658

659659
return ret;

arch/arm64/kernel/signal.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ static int preserve_fpsimd_context(struct fpsimd_context __user *ctx)
250250
&current->thread.uw.fpsimd_state;
251251
int err;
252252

253-
sve_sync_to_fpsimd(current);
253+
fpsimd_sync_from_effective_state(current);
254254

255255
/* copy the FP and status/control registers */
256256
err = __copy_to_user(ctx->vregs, fpsimd->vregs, sizeof(fpsimd->vregs));

0 commit comments

Comments
 (0)