Skip to content

Commit e85d3e9

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: - A set of fixes for FPSIMD/SVE/SME state management (around signal handling and ptrace) where a task can be placed in an invalid state - __nocfi added to swsusp_arch_resume() to avoid a data abort on resuming from hibernate * tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: arm64: Set __nocfi on swsusp_arch_resume() arm64/fpsimd: signal: Fix restoration of SVE context arm64/fpsimd: signal: Allocate SSVE storage when restoring ZA arm64/fpsimd: ptrace: Fix SVE writes on !SME systems
2 parents 6d06443 + e2f8216 commit e85d3e9

3 files changed

Lines changed: 33 additions & 21 deletions

File tree

arch/arm64/kernel/hibernate.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ int swsusp_arch_suspend(void)
402402
* Memory allocated by get_safe_page() will be dealt with by the hibernate code,
403403
* we don't need to free it here.
404404
*/
405-
int swsusp_arch_resume(void)
405+
int __nocfi swsusp_arch_resume(void)
406406
{
407407
int rc;
408408
void *zero_page;

arch/arm64/kernel/ptrace.c

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -968,20 +968,18 @@ static int sve_set_common(struct task_struct *target,
968968
vq = sve_vq_from_vl(task_get_vl(target, type));
969969

970970
/* Enter/exit streaming mode */
971-
if (system_supports_sme()) {
972-
switch (type) {
973-
case ARM64_VEC_SVE:
974-
target->thread.svcr &= ~SVCR_SM_MASK;
975-
set_tsk_thread_flag(target, TIF_SVE);
976-
break;
977-
case ARM64_VEC_SME:
978-
target->thread.svcr |= SVCR_SM_MASK;
979-
set_tsk_thread_flag(target, TIF_SME);
980-
break;
981-
default:
982-
WARN_ON_ONCE(1);
983-
return -EINVAL;
984-
}
971+
switch (type) {
972+
case ARM64_VEC_SVE:
973+
target->thread.svcr &= ~SVCR_SM_MASK;
974+
set_tsk_thread_flag(target, TIF_SVE);
975+
break;
976+
case ARM64_VEC_SME:
977+
target->thread.svcr |= SVCR_SM_MASK;
978+
set_tsk_thread_flag(target, TIF_SME);
979+
break;
980+
default:
981+
WARN_ON_ONCE(1);
982+
return -EINVAL;
985983
}
986984

987985
/* Always zero V regs, FPSR, and FPCR */

arch/arm64/kernel/signal.c

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -449,25 +449,35 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user)
449449
if (user->sve_size < SVE_SIG_CONTEXT_SIZE(vq))
450450
return -EINVAL;
451451

452+
if (sm) {
453+
sme_alloc(current, false);
454+
if (!current->thread.sme_state)
455+
return -ENOMEM;
456+
}
457+
452458
sve_alloc(current, true);
453459
if (!current->thread.sve_state) {
454460
clear_thread_flag(TIF_SVE);
455461
return -ENOMEM;
456462
}
457463

464+
if (sm) {
465+
current->thread.svcr |= SVCR_SM_MASK;
466+
set_thread_flag(TIF_SME);
467+
} else {
468+
current->thread.svcr &= ~SVCR_SM_MASK;
469+
set_thread_flag(TIF_SVE);
470+
}
471+
472+
current->thread.fp_type = FP_STATE_SVE;
473+
458474
err = __copy_from_user(current->thread.sve_state,
459475
(char __user const *)user->sve +
460476
SVE_SIG_REGS_OFFSET,
461477
SVE_SIG_REGS_SIZE(vq));
462478
if (err)
463479
return -EFAULT;
464480

465-
if (flags & SVE_SIG_FLAG_SM)
466-
current->thread.svcr |= SVCR_SM_MASK;
467-
else
468-
set_thread_flag(TIF_SVE);
469-
current->thread.fp_type = FP_STATE_SVE;
470-
471481
err = read_fpsimd_context(&fpsimd, user);
472482
if (err)
473483
return err;
@@ -576,6 +586,10 @@ static int restore_za_context(struct user_ctxs *user)
576586
if (user->za_size < ZA_SIG_CONTEXT_SIZE(vq))
577587
return -EINVAL;
578588

589+
sve_alloc(current, false);
590+
if (!current->thread.sve_state)
591+
return -ENOMEM;
592+
579593
sme_alloc(current, true);
580594
if (!current->thread.sme_state) {
581595
current->thread.svcr &= ~SVCR_ZA_MASK;

0 commit comments

Comments
 (0)