Skip to content

Commit 0423eed

Browse files
brooniewilldeacon
authored andcommitted
arm64/sve: Use accessor functions for vector lengths in thread_struct
In a system with SME there are parallel vector length controls for SVE and SME vectors which function in much the same way so it is desirable to share the code for handling them as much as possible. In order to prepare for doing this add a layer of accessor functions for the various VL related operations on tasks. Since almost all current interactions are actually via task->thread rather than directly with the thread_info the accessors use that. Accessors are provided for both generic and SVE specific usage, the generic accessors should be used for cases where register state is being manipulated since the registers are shared between streaming and regular SVE so we know that when SME support is implemented we will always have to be in the appropriate mode already and hence can generalise now. Since we are using task_struct and we don't want to cause widespread inclusion of sched.h the acessors are all out of line, it is hoped that none of the uses are in a sufficiently critical path for this to be an issue. Those that are most likely to present an issue are in the same translation unit so hopefully the compiler may be able to inline anyway. This is purely adding the layer of abstraction, additional work will be needed to support tasks using SME. Signed-off-by: Mark Brown <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Will Deacon <[email protected]>
1 parent 059613f commit 0423eed

File tree

5 files changed

+54
-23
lines changed

5 files changed

+54
-23
lines changed

arch/arm64/include/asm/fpsimd.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ static inline size_t sve_ffr_offset(int vl)
6262

6363
static inline void *sve_pffr(struct thread_struct *thread)
6464
{
65-
return (char *)thread->sve_state + sve_ffr_offset(thread->sve_vl);
65+
return (char *)thread->sve_state + sve_ffr_offset(thread_get_sve_vl(thread));
6666
}
6767

6868
extern void sve_save_state(void *state, u32 *pfpsr, int save_ffr);

arch/arm64/include/asm/processor.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,16 @@ struct thread_struct {
164164
u64 sctlr_user;
165165
};
166166

167+
static inline unsigned int thread_get_sve_vl(struct thread_struct *thread)
168+
{
169+
return thread->sve_vl;
170+
}
171+
172+
unsigned int task_get_sve_vl(const struct task_struct *task);
173+
void task_set_sve_vl(struct task_struct *task, unsigned long vl);
174+
unsigned int task_get_sve_vl_onexec(const struct task_struct *task);
175+
void task_set_sve_vl_onexec(struct task_struct *task, unsigned long vl);
176+
167177
#define SCTLR_USER_MASK \
168178
(SCTLR_ELx_ENIA | SCTLR_ELx_ENIB | SCTLR_ELx_ENDA | SCTLR_ELx_ENDB | \
169179
SCTLR_EL1_TCF0_MASK)

arch/arm64/kernel/fpsimd.c

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,26 @@ static void sve_free(struct task_struct *task)
228228
__sve_free(task);
229229
}
230230

231+
unsigned int task_get_sve_vl(const struct task_struct *task)
232+
{
233+
return task->thread.sve_vl;
234+
}
235+
236+
void task_set_sve_vl(struct task_struct *task, unsigned long vl)
237+
{
238+
task->thread.sve_vl = vl;
239+
}
240+
241+
unsigned int task_get_sve_vl_onexec(const struct task_struct *task)
242+
{
243+
return task->thread.sve_vl_onexec;
244+
}
245+
246+
void task_set_sve_vl_onexec(struct task_struct *task, unsigned long vl)
247+
{
248+
task->thread.sve_vl_onexec = vl;
249+
}
250+
231251
/*
232252
* TIF_SVE controls whether a task can use SVE without trapping while
233253
* in userspace, and also the way a task's FPSIMD/SVE state is stored
@@ -290,7 +310,7 @@ static void task_fpsimd_load(void)
290310
if (IS_ENABLED(CONFIG_ARM64_SVE) && test_thread_flag(TIF_SVE))
291311
sve_load_state(sve_pffr(&current->thread),
292312
&current->thread.uw.fpsimd_state.fpsr, true,
293-
sve_vq_from_vl(current->thread.sve_vl) - 1);
313+
sve_vq_from_vl(task_get_sve_vl(current)) - 1);
294314
else
295315
fpsimd_load_state(&current->thread.uw.fpsimd_state);
296316
}
@@ -458,7 +478,7 @@ static void fpsimd_to_sve(struct task_struct *task)
458478
if (!system_supports_sve())
459479
return;
460480

461-
vq = sve_vq_from_vl(task->thread.sve_vl);
481+
vq = sve_vq_from_vl(task_get_sve_vl(task));
462482
__fpsimd_to_sve(sst, fst, vq);
463483
}
464484

@@ -484,7 +504,7 @@ static void sve_to_fpsimd(struct task_struct *task)
484504
if (!system_supports_sve())
485505
return;
486506

487-
vq = sve_vq_from_vl(task->thread.sve_vl);
507+
vq = sve_vq_from_vl(task_get_sve_vl(task));
488508
for (i = 0; i < SVE_NUM_ZREGS; ++i) {
489509
p = (__uint128_t const *)ZREG(sst, vq, i);
490510
fst->vregs[i] = arm64_le128_to_cpu(*p);
@@ -499,7 +519,7 @@ static void sve_to_fpsimd(struct task_struct *task)
499519
*/
500520
static size_t sve_state_size(struct task_struct const *task)
501521
{
502-
return SVE_SIG_REGS_SIZE(sve_vq_from_vl(task->thread.sve_vl));
522+
return SVE_SIG_REGS_SIZE(sve_vq_from_vl(task_get_sve_vl(task)));
503523
}
504524

505525
/*
@@ -574,7 +594,7 @@ void sve_sync_from_fpsimd_zeropad(struct task_struct *task)
574594
if (!test_tsk_thread_flag(task, TIF_SVE))
575595
return;
576596

577-
vq = sve_vq_from_vl(task->thread.sve_vl);
597+
vq = sve_vq_from_vl(task_get_sve_vl(task));
578598

579599
memset(sst, 0, SVE_SIG_REGS_SIZE(vq));
580600
__fpsimd_to_sve(sst, fst, vq);
@@ -602,16 +622,16 @@ int sve_set_vector_length(struct task_struct *task,
602622

603623
if (flags & (PR_SVE_VL_INHERIT |
604624
PR_SVE_SET_VL_ONEXEC))
605-
task->thread.sve_vl_onexec = vl;
625+
task_set_sve_vl_onexec(task, vl);
606626
else
607627
/* Reset VL to system default on next exec: */
608-
task->thread.sve_vl_onexec = 0;
628+
task_set_sve_vl_onexec(task, 0);
609629

610630
/* Only actually set the VL if not deferred: */
611631
if (flags & PR_SVE_SET_VL_ONEXEC)
612632
goto out;
613633

614-
if (vl == task->thread.sve_vl)
634+
if (vl == task_get_sve_vl(task))
615635
goto out;
616636

617637
/*
@@ -638,7 +658,7 @@ int sve_set_vector_length(struct task_struct *task,
638658
*/
639659
sve_free(task);
640660

641-
task->thread.sve_vl = vl;
661+
task_set_sve_vl(task, vl);
642662

643663
out:
644664
update_tsk_thread_flag(task, TIF_SVE_VL_INHERIT,
@@ -658,9 +678,9 @@ static int sve_prctl_status(unsigned long flags)
658678
int ret;
659679

660680
if (flags & PR_SVE_SET_VL_ONEXEC)
661-
ret = current->thread.sve_vl_onexec;
681+
ret = task_get_sve_vl_onexec(current);
662682
else
663-
ret = current->thread.sve_vl;
683+
ret = task_get_sve_vl(current);
664684

665685
if (test_thread_flag(TIF_SVE_VL_INHERIT))
666686
ret |= PR_SVE_VL_INHERIT;
@@ -960,7 +980,7 @@ void do_sve_acc(unsigned int esr, struct pt_regs *regs)
960980
*/
961981
if (!test_thread_flag(TIF_FOREIGN_FPSTATE)) {
962982
unsigned long vq_minus_one =
963-
sve_vq_from_vl(current->thread.sve_vl) - 1;
983+
sve_vq_from_vl(task_get_sve_vl(current)) - 1;
964984
sve_set_vq(vq_minus_one);
965985
sve_flush_live(true, vq_minus_one);
966986
fpsimd_bind_task_to_cpu();
@@ -1060,8 +1080,9 @@ void fpsimd_flush_thread(void)
10601080
* If a bug causes this to go wrong, we make some noise and
10611081
* try to fudge thread.sve_vl to a safe value here.
10621082
*/
1063-
vl = current->thread.sve_vl_onexec ?
1064-
current->thread.sve_vl_onexec : get_sve_default_vl();
1083+
vl = task_get_sve_vl_onexec(current);
1084+
if (!vl)
1085+
vl = get_sve_default_vl();
10651086

10661087
if (WARN_ON(!sve_vl_valid(vl)))
10671088
vl = SVE_VL_MIN;
@@ -1070,14 +1091,14 @@ void fpsimd_flush_thread(void)
10701091
if (WARN_ON(supported_vl != vl))
10711092
vl = supported_vl;
10721093

1073-
current->thread.sve_vl = vl;
1094+
task_set_sve_vl(current, vl);
10741095

10751096
/*
10761097
* If the task is not set to inherit, ensure that the vector
10771098
* length will be reset by a subsequent exec:
10781099
*/
10791100
if (!test_thread_flag(TIF_SVE_VL_INHERIT))
1080-
current->thread.sve_vl_onexec = 0;
1101+
task_set_sve_vl_onexec(current, 0);
10811102
}
10821103

10831104
put_cpu_fpsimd_context();
@@ -1122,7 +1143,7 @@ static void fpsimd_bind_task_to_cpu(void)
11221143
WARN_ON(!system_supports_fpsimd());
11231144
last->st = &current->thread.uw.fpsimd_state;
11241145
last->sve_state = current->thread.sve_state;
1125-
last->sve_vl = current->thread.sve_vl;
1146+
last->sve_vl = task_get_sve_vl(current);
11261147
current->thread.fpsimd_cpu = smp_processor_id();
11271148

11281149
if (system_supports_sve()) {

arch/arm64/kernel/ptrace.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -725,7 +725,7 @@ static void sve_init_header_from_task(struct user_sve_header *header,
725725
if (test_tsk_thread_flag(target, TIF_SVE_VL_INHERIT))
726726
header->flags |= SVE_PT_VL_INHERIT;
727727

728-
header->vl = target->thread.sve_vl;
728+
header->vl = task_get_sve_vl(target);
729729
vq = sve_vq_from_vl(header->vl);
730730

731731
header->max_vl = sve_max_vl;
@@ -820,7 +820,7 @@ static int sve_set(struct task_struct *target,
820820
goto out;
821821

822822
/* Actual VL set may be less than the user asked for: */
823-
vq = sve_vq_from_vl(target->thread.sve_vl);
823+
vq = sve_vq_from_vl(task_get_sve_vl(target));
824824

825825
/* Registers: FPSIMD-only case */
826826

arch/arm64/kernel/signal.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ static int preserve_sve_context(struct sve_context __user *ctx)
227227
{
228228
int err = 0;
229229
u16 reserved[ARRAY_SIZE(ctx->__reserved)];
230-
unsigned int vl = current->thread.sve_vl;
230+
unsigned int vl = task_get_sve_vl(current);
231231
unsigned int vq = 0;
232232

233233
if (test_thread_flag(TIF_SVE))
@@ -266,7 +266,7 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user)
266266
if (__copy_from_user(&sve, user->sve, sizeof(sve)))
267267
return -EFAULT;
268268

269-
if (sve.vl != current->thread.sve_vl)
269+
if (sve.vl != task_get_sve_vl(current))
270270
return -EINVAL;
271271

272272
if (sve.head.size <= sizeof(*user->sve)) {
@@ -597,7 +597,7 @@ static int setup_sigframe_layout(struct rt_sigframe_user_layout *user,
597597
int vl = sve_max_vl;
598598

599599
if (!add_all)
600-
vl = current->thread.sve_vl;
600+
vl = task_get_sve_vl(current);
601601

602602
vq = sve_vq_from_vl(vl);
603603
}

0 commit comments

Comments
 (0)