Skip to content

Commit d4ddefe

Browse files
committed
Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
Pull arm64 fixes from Catalin Marinas: "Two more SME fixes related to ptrace(): ensure that the SME is properly set up for the target thread and that the thread sees the ZT registers set via ptrace" * tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: arm64/ptrace: Ensure that the task sees ZT writes on first use arm64/ptrace: Ensure that SME is set up for target when writing SSVE state
2 parents 3e13eee + 2f43f54 commit d4ddefe

File tree

4 files changed

+23
-9
lines changed

4 files changed

+23
-9
lines changed

arch/arm64/include/asm/fpsimd.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ static inline int sme_max_virtualisable_vl(void)
356356
return vec_max_virtualisable_vl(ARM64_VEC_SME);
357357
}
358358

359-
extern void sme_alloc(struct task_struct *task);
359+
extern void sme_alloc(struct task_struct *task, bool flush);
360360
extern unsigned int sme_get_vl(void);
361361
extern int sme_set_current_vl(unsigned long arg);
362362
extern int sme_get_current_vl(void);
@@ -388,7 +388,7 @@ static inline void sme_smstart_sm(void) { }
388388
static inline void sme_smstop_sm(void) { }
389389
static inline void sme_smstop(void) { }
390390

391-
static inline void sme_alloc(struct task_struct *task) { }
391+
static inline void sme_alloc(struct task_struct *task, bool flush) { }
392392
static inline void sme_setup(void) { }
393393
static inline unsigned int sme_get_vl(void) { return 0; }
394394
static inline int sme_max_vl(void) { return 0; }

arch/arm64/kernel/fpsimd.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1285,9 +1285,9 @@ void fpsimd_release_task(struct task_struct *dead_task)
12851285
* the interest of testability and predictability, the architecture
12861286
* guarantees that when ZA is enabled it will be zeroed.
12871287
*/
1288-
void sme_alloc(struct task_struct *task)
1288+
void sme_alloc(struct task_struct *task, bool flush)
12891289
{
1290-
if (task->thread.sme_state) {
1290+
if (task->thread.sme_state && flush) {
12911291
memset(task->thread.sme_state, 0, sme_state_size(task));
12921292
return;
12931293
}
@@ -1515,7 +1515,7 @@ void do_sme_acc(unsigned long esr, struct pt_regs *regs)
15151515
}
15161516

15171517
sve_alloc(current, false);
1518-
sme_alloc(current);
1518+
sme_alloc(current, true);
15191519
if (!current->thread.sve_state || !current->thread.sme_state) {
15201520
force_sig(SIGKILL);
15211521
return;

arch/arm64/kernel/ptrace.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -881,6 +881,13 @@ static int sve_set_common(struct task_struct *target,
881881
break;
882882
case ARM64_VEC_SME:
883883
target->thread.svcr |= SVCR_SM_MASK;
884+
885+
/*
886+
* Disable traps and ensure there is SME storage but
887+
* preserve any currently set values in ZA/ZT.
888+
*/
889+
sme_alloc(target, false);
890+
set_tsk_thread_flag(target, TIF_SME);
884891
break;
885892
default:
886893
WARN_ON_ONCE(1);
@@ -1100,7 +1107,7 @@ static int za_set(struct task_struct *target,
11001107
}
11011108

11021109
/* Allocate/reinit ZA storage */
1103-
sme_alloc(target);
1110+
sme_alloc(target, true);
11041111
if (!target->thread.sme_state) {
11051112
ret = -ENOMEM;
11061113
goto out;
@@ -1170,17 +1177,24 @@ static int zt_set(struct task_struct *target,
11701177
if (!system_supports_sme2())
11711178
return -EINVAL;
11721179

1180+
/* Ensure SVE storage in case this is first use of SME */
1181+
sve_alloc(target, false);
1182+
if (!target->thread.sve_state)
1183+
return -ENOMEM;
1184+
11731185
if (!thread_za_enabled(&target->thread)) {
1174-
sme_alloc(target);
1186+
sme_alloc(target, true);
11751187
if (!target->thread.sme_state)
11761188
return -ENOMEM;
11771189
}
11781190

11791191
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
11801192
thread_zt_state(&target->thread),
11811193
0, ZT_SIG_REG_BYTES);
1182-
if (ret == 0)
1194+
if (ret == 0) {
11831195
target->thread.svcr |= SVCR_ZA_MASK;
1196+
set_tsk_thread_flag(target, TIF_SME);
1197+
}
11841198

11851199
fpsimd_flush_task_state(target);
11861200

arch/arm64/kernel/signal.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,7 @@ static int restore_za_context(struct user_ctxs *user)
475475
fpsimd_flush_task_state(current);
476476
/* From now, fpsimd_thread_switch() won't touch thread.sve_state */
477477

478-
sme_alloc(current);
478+
sme_alloc(current, true);
479479
if (!current->thread.sme_state) {
480480
current->thread.svcr &= ~SVCR_ZA_MASK;
481481
clear_thread_flag(TIF_SME);

0 commit comments

Comments
 (0)