Skip to content

Commit 5838a15

Browse files
brooniewilldeacon
authored andcommitted
arm64/sve: Track vector lengths for tasks in an array
As for SVE we will track a per task SME vector length for tasks. Convert the existing storage for the vector length into an array and update fpsimd_flush_task() to initialise this in a function. Signed-off-by: Mark Brown <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Will Deacon <[email protected]>
1 parent ddc806b commit 5838a15

File tree

3 files changed

+95
-48
lines changed

3 files changed

+95
-48
lines changed

arch/arm64/include/asm/processor.h

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,8 @@ struct thread_struct {
152152

153153
unsigned int fpsimd_cpu;
154154
void *sve_state; /* SVE registers, if any */
155-
unsigned int sve_vl; /* SVE vector length */
156-
unsigned int sve_vl_onexec; /* SVE vl after next exec */
155+
unsigned int vl[ARM64_VEC_MAX]; /* vector length */
156+
unsigned int vl_onexec[ARM64_VEC_MAX]; /* vl after next exec */
157157
unsigned long fault_address; /* fault info */
158158
unsigned long fault_code; /* ESR_EL1 value */
159159
struct debug_info debug; /* debugging */
@@ -169,15 +169,45 @@ struct thread_struct {
169169
u64 sctlr_user;
170170
};
171171

172+
static inline unsigned int thread_get_vl(struct thread_struct *thread,
173+
enum vec_type type)
174+
{
175+
return thread->vl[type];
176+
}
177+
172178
static inline unsigned int thread_get_sve_vl(struct thread_struct *thread)
173179
{
174-
return thread->sve_vl;
180+
return thread_get_vl(thread, ARM64_VEC_SVE);
181+
}
182+
183+
unsigned int task_get_vl(const struct task_struct *task, enum vec_type type);
184+
void task_set_vl(struct task_struct *task, enum vec_type type,
185+
unsigned long vl);
186+
void task_set_vl_onexec(struct task_struct *task, enum vec_type type,
187+
unsigned long vl);
188+
unsigned int task_get_vl_onexec(const struct task_struct *task,
189+
enum vec_type type);
190+
191+
static inline unsigned int task_get_sve_vl(const struct task_struct *task)
192+
{
193+
return task_get_vl(task, ARM64_VEC_SVE);
175194
}
176195

177-
unsigned int task_get_sve_vl(const struct task_struct *task);
178-
void task_set_sve_vl(struct task_struct *task, unsigned long vl);
179-
unsigned int task_get_sve_vl_onexec(const struct task_struct *task);
180-
void task_set_sve_vl_onexec(struct task_struct *task, unsigned long vl);
196+
static inline void task_set_sve_vl(struct task_struct *task, unsigned long vl)
197+
{
198+
task_set_vl(task, ARM64_VEC_SVE, vl);
199+
}
200+
201+
static inline unsigned int task_get_sve_vl_onexec(const struct task_struct *task)
202+
{
203+
return task_get_vl_onexec(task, ARM64_VEC_SVE);
204+
}
205+
206+
static inline void task_set_sve_vl_onexec(struct task_struct *task,
207+
unsigned long vl)
208+
{
209+
task_set_vl_onexec(task, ARM64_VEC_SVE, vl);
210+
}
181211

182212
#define SCTLR_USER_MASK \
183213
(SCTLR_ELx_ENIA | SCTLR_ELx_ENIB | SCTLR_ELx_ENDA | SCTLR_ELx_ENDB | \

arch/arm64/include/asm/thread_info.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ int arch_dup_task_struct(struct task_struct *dst,
7878
#define TIF_SINGLESTEP 21
7979
#define TIF_32BIT 22 /* 32bit process */
8080
#define TIF_SVE 23 /* Scalable Vector Extension in use */
81-
#define TIF_SVE_VL_INHERIT 24 /* Inherit sve_vl_onexec across exec */
81+
#define TIF_SVE_VL_INHERIT 24 /* Inherit SVE vl_onexec across exec */
8282
#define TIF_SSBD 25 /* Wants SSB mitigation */
8383
#define TIF_TAGGED_ADDR 26 /* Allow tagged user addresses */
8484

arch/arm64/kernel/fpsimd.c

Lines changed: 57 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,17 @@ __ro_after_init struct vl_info vl_info[ARM64_VEC_MAX] = {
133133
#endif
134134
};
135135

136+
static unsigned int vec_vl_inherit_flag(enum vec_type type)
137+
{
138+
switch (type) {
139+
case ARM64_VEC_SVE:
140+
return TIF_SVE_VL_INHERIT;
141+
default:
142+
WARN_ON_ONCE(1);
143+
return 0;
144+
}
145+
}
146+
136147
struct vl_config {
137148
int __default_vl; /* Default VL for tasks */
138149
};
@@ -239,24 +250,27 @@ static void sve_free(struct task_struct *task)
239250
__sve_free(task);
240251
}
241252

242-
unsigned int task_get_sve_vl(const struct task_struct *task)
253+
unsigned int task_get_vl(const struct task_struct *task, enum vec_type type)
243254
{
244-
return task->thread.sve_vl;
255+
return task->thread.vl[type];
245256
}
246257

247-
void task_set_sve_vl(struct task_struct *task, unsigned long vl)
258+
void task_set_vl(struct task_struct *task, enum vec_type type,
259+
unsigned long vl)
248260
{
249-
task->thread.sve_vl = vl;
261+
task->thread.vl[type] = vl;
250262
}
251263

252-
unsigned int task_get_sve_vl_onexec(const struct task_struct *task)
264+
unsigned int task_get_vl_onexec(const struct task_struct *task,
265+
enum vec_type type)
253266
{
254-
return task->thread.sve_vl_onexec;
267+
return task->thread.vl_onexec[type];
255268
}
256269

257-
void task_set_sve_vl_onexec(struct task_struct *task, unsigned long vl)
270+
void task_set_vl_onexec(struct task_struct *task, enum vec_type type,
271+
unsigned long vl)
258272
{
259-
task->thread.sve_vl_onexec = vl;
273+
task->thread.vl_onexec[type] = vl;
260274
}
261275

262276
/*
@@ -1074,10 +1088,43 @@ void fpsimd_thread_switch(struct task_struct *next)
10741088
__put_cpu_fpsimd_context();
10751089
}
10761090

1077-
void fpsimd_flush_thread(void)
1091+
static void fpsimd_flush_thread_vl(enum vec_type type)
10781092
{
10791093
int vl, supported_vl;
10801094

1095+
/*
1096+
* Reset the task vector length as required. This is where we
1097+
* ensure that all user tasks have a valid vector length
1098+
* configured: no kernel task can become a user task without
1099+
* an exec and hence a call to this function. By the time the
1100+
* first call to this function is made, all early hardware
1101+
* probing is complete, so __sve_default_vl should be valid.
1102+
* If a bug causes this to go wrong, we make some noise and
1103+
* try to fudge thread.sve_vl to a safe value here.
1104+
*/
1105+
vl = task_get_vl_onexec(current, type);
1106+
if (!vl)
1107+
vl = get_default_vl(type);
1108+
1109+
if (WARN_ON(!sve_vl_valid(vl)))
1110+
vl = SVE_VL_MIN;
1111+
1112+
supported_vl = find_supported_vector_length(type, vl);
1113+
if (WARN_ON(supported_vl != vl))
1114+
vl = supported_vl;
1115+
1116+
task_set_vl(current, type, vl);
1117+
1118+
/*
1119+
* If the task is not set to inherit, ensure that the vector
1120+
* length will be reset by a subsequent exec:
1121+
*/
1122+
if (!test_thread_flag(vec_vl_inherit_flag(type)))
1123+
task_set_vl_onexec(current, type, 0);
1124+
}
1125+
1126+
void fpsimd_flush_thread(void)
1127+
{
10811128
if (!system_supports_fpsimd())
10821129
return;
10831130

@@ -1090,37 +1137,7 @@ void fpsimd_flush_thread(void)
10901137
if (system_supports_sve()) {
10911138
clear_thread_flag(TIF_SVE);
10921139
sve_free(current);
1093-
1094-
/*
1095-
* Reset the task vector length as required.
1096-
* This is where we ensure that all user tasks have a valid
1097-
* vector length configured: no kernel task can become a user
1098-
* task without an exec and hence a call to this function.
1099-
* By the time the first call to this function is made, all
1100-
* early hardware probing is complete, so __sve_default_vl
1101-
* should be valid.
1102-
* If a bug causes this to go wrong, we make some noise and
1103-
* try to fudge thread.sve_vl to a safe value here.
1104-
*/
1105-
vl = task_get_sve_vl_onexec(current);
1106-
if (!vl)
1107-
vl = get_sve_default_vl();
1108-
1109-
if (WARN_ON(!sve_vl_valid(vl)))
1110-
vl = SVE_VL_MIN;
1111-
1112-
supported_vl = find_supported_vector_length(ARM64_VEC_SVE, vl);
1113-
if (WARN_ON(supported_vl != vl))
1114-
vl = supported_vl;
1115-
1116-
task_set_sve_vl(current, vl);
1117-
1118-
/*
1119-
* If the task is not set to inherit, ensure that the vector
1120-
* length will be reset by a subsequent exec:
1121-
*/
1122-
if (!test_thread_flag(TIF_SVE_VL_INHERIT))
1123-
task_set_sve_vl_onexec(current, 0);
1140+
fpsimd_flush_thread_vl(ARM64_VEC_SVE);
11241141
}
11251142

11261143
put_cpu_fpsimd_context();

0 commit comments

Comments
 (0)