Skip to content

Commit 30c43e7

Browse files
brooniectmarinas
authored andcommitted
arm64/sve: Generalise vector length configuration prctl() for SME
In preparation for adding SME support update the bulk of the implementation for the vector length configuration prctl() calls to be independent of vector type. Signed-off-by: Mark Brown <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Catalin Marinas <[email protected]>
1 parent 97bcbee commit 30c43e7

File tree

4 files changed

+34
-31
lines changed

4 files changed

+34
-31
lines changed

arch/arm64/include/asm/fpsimd.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ extern void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *state,
5151
extern void fpsimd_flush_task_state(struct task_struct *target);
5252
extern void fpsimd_save_and_flush_cpu_state(void);
5353

54-
/* Maximum VL that SVE VL-agnostic software can transparently support */
55-
#define SVE_VL_ARCH_MAX 0x100
54+
/* Maximum VL that SVE/SME VL-agnostic software can transparently support */
55+
#define VL_ARCH_MAX 0x100
5656

5757
/* Offset of FFR in the SVE register dump */
5858
static inline size_t sve_ffr_offset(int vl)
@@ -122,7 +122,7 @@ extern void fpsimd_sync_to_sve(struct task_struct *task);
122122
extern void sve_sync_to_fpsimd(struct task_struct *task);
123123
extern void sve_sync_from_fpsimd_zeropad(struct task_struct *task);
124124

125-
extern int sve_set_vector_length(struct task_struct *task,
125+
extern int vec_set_vector_length(struct task_struct *task, enum vec_type type,
126126
unsigned long vl, unsigned long flags);
127127

128128
extern int sve_set_current_vl(unsigned long arg);

arch/arm64/kernel/fpsimd.c

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,7 @@ void sve_sync_from_fpsimd_zeropad(struct task_struct *task)
632632
__fpsimd_to_sve(sst, fst, vq);
633633
}
634634

635-
int sve_set_vector_length(struct task_struct *task,
635+
int vec_set_vector_length(struct task_struct *task, enum vec_type type,
636636
unsigned long vl, unsigned long flags)
637637
{
638638
if (flags & ~(unsigned long)(PR_SVE_VL_INHERIT |
@@ -643,33 +643,35 @@ int sve_set_vector_length(struct task_struct *task,
643643
return -EINVAL;
644644

645645
/*
646-
* Clamp to the maximum vector length that VL-agnostic SVE code can
647-
* work with. A flag may be assigned in the future to allow setting
648-
* of larger vector lengths without confusing older software.
646+
* Clamp to the maximum vector length that VL-agnostic code
647+
* can work with. A flag may be assigned in the future to
648+
* allow setting of larger vector lengths without confusing
649+
* older software.
649650
*/
650-
if (vl > SVE_VL_ARCH_MAX)
651-
vl = SVE_VL_ARCH_MAX;
651+
if (vl > VL_ARCH_MAX)
652+
vl = VL_ARCH_MAX;
652653

653-
vl = find_supported_vector_length(ARM64_VEC_SVE, vl);
654+
vl = find_supported_vector_length(type, vl);
654655

655656
if (flags & (PR_SVE_VL_INHERIT |
656657
PR_SVE_SET_VL_ONEXEC))
657-
task_set_sve_vl_onexec(task, vl);
658+
task_set_vl_onexec(task, type, vl);
658659
else
659660
/* Reset VL to system default on next exec: */
660-
task_set_sve_vl_onexec(task, 0);
661+
task_set_vl_onexec(task, type, 0);
661662

662663
/* Only actually set the VL if not deferred: */
663664
if (flags & PR_SVE_SET_VL_ONEXEC)
664665
goto out;
665666

666-
if (vl == task_get_sve_vl(task))
667+
if (vl == task_get_vl(task, type))
667668
goto out;
668669

669670
/*
670671
* To ensure the FPSIMD bits of the SVE vector registers are preserved,
671672
* write any live register state back to task_struct, and convert to a
672-
* non-SVE thread.
673+
* regular FPSIMD thread. Since the vector length can only be changed
674+
* with a syscall we can't be in streaming mode while reconfiguring.
673675
*/
674676
if (task == current) {
675677
get_cpu_fpsimd_context();
@@ -690,31 +692,32 @@ int sve_set_vector_length(struct task_struct *task,
690692
*/
691693
sve_free(task);
692694

693-
task_set_sve_vl(task, vl);
695+
task_set_vl(task, type, vl);
694696

695697
out:
696-
update_tsk_thread_flag(task, TIF_SVE_VL_INHERIT,
698+
update_tsk_thread_flag(task, vec_vl_inherit_flag(type),
697699
flags & PR_SVE_VL_INHERIT);
698700

699701
return 0;
700702
}
701703

702704
/*
703705
* Encode the current vector length and flags for return.
704-
* This is only required for prctl(): ptrace has separate fields
706+
* This is only required for prctl(): ptrace has separate fields.
707+
* SVE and SME use the same bits for _ONEXEC and _INHERIT.
705708
*
706-
* flags are as for sve_set_vector_length().
709+
* flags are as for vec_set_vector_length().
707710
*/
708-
static int sve_prctl_status(unsigned long flags)
711+
static int vec_prctl_status(enum vec_type type, unsigned long flags)
709712
{
710713
int ret;
711714

712715
if (flags & PR_SVE_SET_VL_ONEXEC)
713-
ret = task_get_sve_vl_onexec(current);
716+
ret = task_get_vl_onexec(current, type);
714717
else
715-
ret = task_get_sve_vl(current);
718+
ret = task_get_vl(current, type);
716719

717-
if (test_thread_flag(TIF_SVE_VL_INHERIT))
720+
if (test_thread_flag(vec_vl_inherit_flag(type)))
718721
ret |= PR_SVE_VL_INHERIT;
719722

720723
return ret;
@@ -732,11 +735,11 @@ int sve_set_current_vl(unsigned long arg)
732735
if (!system_supports_sve() || is_compat_task())
733736
return -EINVAL;
734737

735-
ret = sve_set_vector_length(current, vl, flags);
738+
ret = vec_set_vector_length(current, ARM64_VEC_SVE, vl, flags);
736739
if (ret)
737740
return ret;
738741

739-
return sve_prctl_status(flags);
742+
return vec_prctl_status(ARM64_VEC_SVE, flags);
740743
}
741744

742745
/* PR_SVE_GET_VL */
@@ -745,7 +748,7 @@ int sve_get_current_vl(void)
745748
if (!system_supports_sve() || is_compat_task())
746749
return -EINVAL;
747750

748-
return sve_prctl_status(0);
751+
return vec_prctl_status(ARM64_VEC_SVE, 0);
749752
}
750753

751754
static void vec_probe_vqs(struct vl_info *info,

arch/arm64/kernel/ptrace.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -812,9 +812,9 @@ static int sve_set(struct task_struct *target,
812812

813813
/*
814814
* Apart from SVE_PT_REGS_MASK, all SVE_PT_* flags are consumed by
815-
* sve_set_vector_length(), which will also validate them for us:
815+
* vec_set_vector_length(), which will also validate them for us:
816816
*/
817-
ret = sve_set_vector_length(target, header.vl,
817+
ret = vec_set_vector_length(target, ARM64_VEC_SVE, header.vl,
818818
((unsigned long)header.flags & ~SVE_PT_REGS_MASK) << 16);
819819
if (ret)
820820
goto out;

arch/arm64/kvm/reset.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,10 @@ int kvm_arm_init_sve(void)
5252
* The get_sve_reg()/set_sve_reg() ioctl interface will need
5353
* to be extended with multiple register slice support in
5454
* order to support vector lengths greater than
55-
* SVE_VL_ARCH_MAX:
55+
* VL_ARCH_MAX:
5656
*/
57-
if (WARN_ON(kvm_sve_max_vl > SVE_VL_ARCH_MAX))
58-
kvm_sve_max_vl = SVE_VL_ARCH_MAX;
57+
if (WARN_ON(kvm_sve_max_vl > VL_ARCH_MAX))
58+
kvm_sve_max_vl = VL_ARCH_MAX;
5959

6060
/*
6161
* Don't even try to make use of vector lengths that
@@ -103,7 +103,7 @@ static int kvm_vcpu_finalize_sve(struct kvm_vcpu *vcpu)
103103
* set_sve_vls(). Double-check here just to be sure:
104104
*/
105105
if (WARN_ON(!sve_vl_valid(vl) || vl > sve_max_virtualisable_vl() ||
106-
vl > SVE_VL_ARCH_MAX))
106+
vl > VL_ARCH_MAX))
107107
return -EIO;
108108

109109
buf = kzalloc(SVE_SIG_REGS_SIZE(sve_vq_from_vl(vl)), GFP_KERNEL_ACCOUNT);

0 commit comments

Comments
 (0)