]> git.hungrycats.org Git - linux/commitdiff
arm64/sme: Restore SME registers on exit from suspend
authorMark Brown <broonie@kernel.org>
Tue, 13 Feb 2024 23:06:32 +0000 (23:06 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 1 Mar 2024 12:26:37 +0000 (13:26 +0100)
[ Upstream commit 9533864816fb4a6207c63b7a98396351ce1a9fae ]

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: a1f4ccd25cc2 ("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>
Signed-off-by: Sasha Levin <sashal@kernel.org>
arch/arm64/include/asm/fpsimd.h
arch/arm64/kernel/fpsimd.c
arch/arm64/kernel/suspend.c

index d720b6f7e5f9c6383b29c25ee21b05137da8951a..da18413712c04875d81afe94d5700f1e33261b6a 100644 (file)
@@ -343,6 +343,7 @@ extern void sme_alloc(struct task_struct *task, bool flush);
 extern unsigned int sme_get_vl(void);
 extern int sme_set_current_vl(unsigned long arg);
 extern int sme_get_current_vl(void);
+extern void sme_suspend_exit(void);
 
 /*
  * Return how many bytes of memory are required to store the full SME
@@ -372,6 +373,7 @@ static inline int sme_max_vl(void) { return 0; }
 static inline int sme_max_virtualisable_vl(void) { return 0; }
 static inline int sme_set_current_vl(unsigned long arg) { return -EINVAL; }
 static inline int sme_get_current_vl(void) { return -EINVAL; }
+static inline void sme_suspend_exit(void) { }
 
 static inline size_t za_state_size(struct task_struct const *task)
 {
index 8c226d79abdfceabbf43f9c167b6926a0a6cf4ce..59b5a16bab5d6b24d4539ca9d12677f536ba86e4 100644 (file)
@@ -1347,6 +1347,20 @@ void __init sme_setup(void)
                get_sme_default_vl());
 }
 
+void sme_suspend_exit(void)
+{
+       u64 smcr = 0;
+
+       if (!system_supports_sme())
+               return;
+
+       if (system_supports_fa64())
+               smcr |= SMCR_ELx_FA64;
+
+       write_sysreg_s(smcr, SYS_SMCR_EL1);
+       write_sysreg_s(0, SYS_SMPRI_EL1);
+}
+
 #endif /* CONFIG_ARM64_SME */
 
 static void sve_init_regs(void)
index 8b02d310838f92404c7d61a1083ffa8398194d20..064d996cc55b24b62ffe0f49e9f3af5188fef105 100644 (file)
@@ -11,6 +11,7 @@
 #include <asm/daifflags.h>
 #include <asm/debug-monitors.h>
 #include <asm/exec.h>
+#include <asm/fpsimd.h>
 #include <asm/mte.h>
 #include <asm/memory.h>
 #include <asm/mmu_context.h>
@@ -77,6 +78,8 @@ void notrace __cpu_suspend_exit(void)
         */
        spectre_v4_enable_mitigation(NULL);
 
+       sme_suspend_exit();
+
        /* Restore additional feature-specific configuration */
        ptrauth_suspend_exit();
 }