Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/2] arm64/sme: Fix handling of traps on resume
@ 2024-02-03 13:00 Mark Brown
  2024-02-03 13:00 ` [PATCH v2 1/2] arm64/sme: Restore SMCR on exit from suspend Mark Brown
  2024-02-03 13:00 ` [PATCH v2 2/2] arm64/sme: Restore SMCR_EL1.EZT0 " Mark Brown
  0 siblings, 2 replies; 5+ messages in thread
From: Mark Brown @ 2024-02-03 13:00 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon
  Cc: Dave Martin, Jackson Cooper-Driver, linux-arm-kernel,
	linux-kernel, Mark Brown

The fast model was recently changed to reset system registers to 0 on
resume, exposing the fact that for SME we do not restore the
configuration of traps for extensions that add state.  Fix this.

Signed-off-by: Mark Brown <broonie@kernel.org>
---
Changes in v2:
- Also reinitialise SMPRI_EL1.
- Link to v1: https://lore.kernel.org/r/20240130-arm64-sme-resume-v1-0-0e60ebba18df@kernel.org

---
Mark Brown (2):
      arm64/sme: Restore SMCR on exit from suspend
      arm64/sme: Restore SMCR_EL1.EZT0 on exit from suspend

 arch/arm64/include/asm/fpsimd.h |  2 ++
 arch/arm64/kernel/fpsimd.c      | 16 ++++++++++++++++
 arch/arm64/kernel/suspend.c     |  3 +++
 3 files changed, 21 insertions(+)
---
base-commit: 41bccc98fb7931d63d03f326a746ac4d429c1dd3
change-id: 20240129-arm64-sme-resume-3266150292b6

Best regards,
-- 
Mark Brown <broonie@kernel.org>


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v2 1/2] arm64/sme: Restore SMCR on exit from suspend
  2024-02-03 13:00 [PATCH v2 0/2] arm64/sme: Fix handling of traps on resume Mark Brown
@ 2024-02-03 13:00 ` Mark Brown
  2024-02-09 16:46   ` Will Deacon
  2024-02-03 13:00 ` [PATCH v2 2/2] arm64/sme: Restore SMCR_EL1.EZT0 " Mark Brown
  1 sibling, 1 reply; 5+ messages in thread
From: Mark Brown @ 2024-02-03 13:00 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon
  Cc: Dave Martin, Jackson Cooper-Driver, linux-arm-kernel,
	linux-kernel, Mark Brown

The fields in SMCR_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>
---
 arch/arm64/include/asm/fpsimd.h |  2 ++
 arch/arm64/kernel/fpsimd.c      | 14 ++++++++++++++
 arch/arm64/kernel/suspend.c     |  3 +++
 3 files changed, 19 insertions(+)

diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index 50e5f25d3024..7780d343ef08 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -386,6 +386,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
@@ -421,6 +422,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 sme_state_size(struct task_struct const *task)
 {
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index a5dc6f764195..8d2a5824d5d3 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -1311,6 +1311,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)
diff --git a/arch/arm64/kernel/suspend.c b/arch/arm64/kernel/suspend.c
index eca4d0435211..eaaff94329cd 100644
--- a/arch/arm64/kernel/suspend.c
+++ b/arch/arm64/kernel/suspend.c
@@ -12,6 +12,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>
@@ -80,6 +81,8 @@ void notrace __cpu_suspend_exit(void)
 	 */
 	spectre_v4_enable_mitigation(NULL);
 
+	sme_suspend_exit();
+
 	/* Restore additional feature-specific configuration */
 	ptrauth_suspend_exit();
 }

-- 
2.30.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v2 2/2] arm64/sme: Restore SMCR_EL1.EZT0 on exit from suspend
  2024-02-03 13:00 [PATCH v2 0/2] arm64/sme: Fix handling of traps on resume Mark Brown
  2024-02-03 13:00 ` [PATCH v2 1/2] arm64/sme: Restore SMCR on exit from suspend Mark Brown
@ 2024-02-03 13:00 ` Mark Brown
  1 sibling, 0 replies; 5+ messages in thread
From: Mark Brown @ 2024-02-03 13:00 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon
  Cc: Dave Martin, Jackson Cooper-Driver, linux-arm-kernel,
	linux-kernel, Mark Brown

The fields in SMCR_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. Do so for SMCR_EL1.EZT0.

Fixes: d4913eee152d (arm64/sme: Add basic enumeration for SME2)
Reported-by: Jackson Cooper-Driver <Jackson.Cooper-Driver@arm.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 arch/arm64/kernel/fpsimd.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 8d2a5824d5d3..7a7c056f0647 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -1320,6 +1320,8 @@ void sme_suspend_exit(void)
 
 	if (system_supports_fa64())
 		smcr |= SMCR_ELx_FA64;
+	if (system_supports_sme2())
+		smcr |= SMCR_ELx_EZT0;
 
 	write_sysreg_s(smcr, SYS_SMCR_EL1);
 	write_sysreg_s(0, SYS_SMPRI_EL1);

-- 
2.30.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v2 1/2] arm64/sme: Restore SMCR on exit from suspend
  2024-02-03 13:00 ` [PATCH v2 1/2] arm64/sme: Restore SMCR on exit from suspend Mark Brown
@ 2024-02-09 16:46   ` Will Deacon
  2024-02-09 17:25     ` Mark Brown
  0 siblings, 1 reply; 5+ messages in thread
From: Will Deacon @ 2024-02-09 16:46 UTC (permalink / raw)
  To: Mark Brown
  Cc: Catalin Marinas, Dave Martin, Jackson Cooper-Driver,
	linux-arm-kernel, linux-kernel

On Sat, Feb 03, 2024 at 01:00:40PM +0000, Mark Brown wrote:
> The fields in SMCR_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>
> ---
>  arch/arm64/include/asm/fpsimd.h |  2 ++
>  arch/arm64/kernel/fpsimd.c      | 14 ++++++++++++++
>  arch/arm64/kernel/suspend.c     |  3 +++
>  3 files changed, 19 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
> index 50e5f25d3024..7780d343ef08 100644
> --- a/arch/arm64/include/asm/fpsimd.h
> +++ b/arch/arm64/include/asm/fpsimd.h
> @@ -386,6 +386,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
> @@ -421,6 +422,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 sme_state_size(struct task_struct const *task)
>  {
> diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
> index a5dc6f764195..8d2a5824d5d3 100644
> --- a/arch/arm64/kernel/fpsimd.c
> +++ b/arch/arm64/kernel/fpsimd.c
> @@ -1311,6 +1311,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);
> +}

Looking at the other places where we touch SMCR_EL1, it looks like we
always use a read-modify-write sequence. However, doesn't that mean we
inherit a bunch of unknown bits on cold boot? I'm basically wondering
whether we should be initialising these registers to a well-known value
earlier in the CPU init path, a bit like we do for the EL2 variants.

Will

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v2 1/2] arm64/sme: Restore SMCR on exit from suspend
  2024-02-09 16:46   ` Will Deacon
@ 2024-02-09 17:25     ` Mark Brown
  0 siblings, 0 replies; 5+ messages in thread
From: Mark Brown @ 2024-02-09 17:25 UTC (permalink / raw)
  To: Will Deacon
  Cc: Catalin Marinas, Dave Martin, Jackson Cooper-Driver,
	linux-arm-kernel, linux-kernel


[-- Attachment #1.1: Type: text/plain, Size: 582 bytes --]

On Fri, Feb 09, 2024 at 04:46:48PM +0000, Will Deacon wrote:

> Looking at the other places where we touch SMCR_EL1, it looks like we
> always use a read-modify-write sequence. However, doesn't that mean we
> inherit a bunch of unknown bits on cold boot? I'm basically wondering
> whether we should be initialising these registers to a well-known value
> earlier in the CPU init path, a bit like we do for the EL2 variants.

That'd be safer from a future proofing point of view, yes - we've got a
similar pattern with ZCR as well from the looks of it.  I'll send a
separate series.

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2024-02-09 17:26 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-02-03 13:00 [PATCH v2 0/2] arm64/sme: Fix handling of traps on resume Mark Brown
2024-02-03 13:00 ` [PATCH v2 1/2] arm64/sme: Restore SMCR on exit from suspend Mark Brown
2024-02-09 16:46   ` Will Deacon
2024-02-09 17:25     ` Mark Brown
2024-02-03 13:00 ` [PATCH v2 2/2] arm64/sme: Restore SMCR_EL1.EZT0 " Mark Brown

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox