Skip to content

Commit 9533864

Browse files
brooniewilldeacon
authored andcommitted
arm64/sme: Restore SME registers on exit from suspend
The fields in SMCR_EL1 and SMPRI_EL1 reset to an architecturally UNKNOWN value. Since we do not otherwise manage the traps configured in this register at runtime we need to reconfigure them after a suspend in case nothing else was kind enough to preserve them for us. The vector length will be restored as part of restoring the SME state for the next SME using task. Fixes: a1f4ccd ("arm64/sme: Provide Kconfig for SME") Reported-by: Jackson Cooper-Driver <Jackson.Cooper-Driver@arm.com> Signed-off-by: Mark Brown <broonie@kernel.org> Link: https://lore.kernel.org/r/20240213-arm64-sme-resume-v3-1-17e05e493471@kernel.org Signed-off-by: Will Deacon <will@kernel.org>
1 parent a6b3eb3 commit 9533864

File tree

3 files changed

+19
-0
lines changed

3 files changed

+19
-0
lines changed

arch/arm64/include/asm/fpsimd.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,7 @@ extern void sme_alloc(struct task_struct *task, bool flush);
386386
extern unsigned int sme_get_vl(void);
387387
extern int sme_set_current_vl(unsigned long arg);
388388
extern int sme_get_current_vl(void);
389+
extern void sme_suspend_exit(void);
389390

390391
/*
391392
* Return how many bytes of memory are required to store the full SME
@@ -421,6 +422,7 @@ static inline int sme_max_vl(void) { return 0; }
421422
static inline int sme_max_virtualisable_vl(void) { return 0; }
422423
static inline int sme_set_current_vl(unsigned long arg) { return -EINVAL; }
423424
static inline int sme_get_current_vl(void) { return -EINVAL; }
425+
static inline void sme_suspend_exit(void) { }
424426

425427
static inline size_t sme_state_size(struct task_struct const *task)
426428
{

arch/arm64/kernel/fpsimd.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1311,6 +1311,20 @@ void __init sme_setup(void)
13111311
get_sme_default_vl());
13121312
}
13131313

1314+
void sme_suspend_exit(void)
1315+
{
1316+
u64 smcr = 0;
1317+
1318+
if (!system_supports_sme())
1319+
return;
1320+
1321+
if (system_supports_fa64())
1322+
smcr |= SMCR_ELx_FA64;
1323+
1324+
write_sysreg_s(smcr, SYS_SMCR_EL1);
1325+
write_sysreg_s(0, SYS_SMPRI_EL1);
1326+
}
1327+
13141328
#endif /* CONFIG_ARM64_SME */
13151329

13161330
static void sve_init_regs(void)

arch/arm64/kernel/suspend.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <asm/daifflags.h>
1313
#include <asm/debug-monitors.h>
1414
#include <asm/exec.h>
15+
#include <asm/fpsimd.h>
1516
#include <asm/mte.h>
1617
#include <asm/memory.h>
1718
#include <asm/mmu_context.h>
@@ -80,6 +81,8 @@ void notrace __cpu_suspend_exit(void)
8081
*/
8182
spectre_v4_enable_mitigation(NULL);
8283

84+
sme_suspend_exit();
85+
8386
/* Restore additional feature-specific configuration */
8487
ptrauth_suspend_exit();
8588
}

0 commit comments

Comments
 (0)