diff mbox series

[v2,2/4] arm64/signal: Flush FPSIMD register state when disabling streaming mode

Message ID 20220815132834.229769-3-broonie@kernel.org (mailing list archive)
State New, archived
Headers show
Series arm64/sme: SME related fixes | expand

Commit Message

Mark Brown Aug. 15, 2022, 1:28 p.m. UTC
When handling a signal delivered to a context with streaming mode enabled
we will disable streaming mode for the signal handler, when doing so we
should also flush the saved FPSIMD register state like exiting streaming
mode in the hardware would do so that if that state is reloaded we get the
same behaviour. Without this we will reload whatever the last FPSIMD state
that was saved for the task was.

Fixes: 40a8e87bb3285 ("arm64/sme: Disable ZA and streaming mode when handling signals")
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 arch/arm64/kernel/signal.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

Comments

Catalin Marinas Aug. 17, 2022, 2:09 p.m. UTC | #1
On Mon, Aug 15, 2022 at 02:28:32PM +0100, Mark Brown wrote:
> When handling a signal delivered to a context with streaming mode enabled
> we will disable streaming mode for the signal handler, when doing so we
> should also flush the saved FPSIMD register state like exiting streaming
> mode in the hardware would do so that if that state is reloaded we get the
> same behaviour. Without this we will reload whatever the last FPSIMD state
> that was saved for the task was.
> 
> Fixes: 40a8e87bb3285 ("arm64/sme: Disable ZA and streaming mode when handling signals")
> Signed-off-by: Mark Brown <broonie@kernel.org>

Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
diff mbox series

Patch

diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index a410c980e50e..0c227f57def5 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -926,6 +926,16 @@  static void setup_return(struct pt_regs *regs, struct k_sigaction *ka,
 
 	/* Signal handlers are invoked with ZA and streaming mode disabled */
 	if (system_supports_sme()) {
+		/*
+		 * If we were in streaming mode the saved register
+		 * state was SVE but we will exit SM and use the
+		 * FPSIMD register state - flush the saved FPSIMD
+		 * register state in case it gets loaded.
+		 */
+		if (current->thread.svcr & SVCR_SM_MASK)
+			memset(&current->thread.uw.fpsimd_state, 0,
+			       sizeof(current->thread.uw.fpsimd_state));
+
 		current->thread.svcr &= ~(SVCR_ZA_MASK |
 					  SVCR_SM_MASK);
 		sme_smstop();