All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/2] arm64/signal: Fix handling of TPIDR2
@ 2023-06-22 13:39 ` Mark Brown
  0 siblings, 0 replies; 16+ messages in thread
From: Mark Brown @ 2023-06-22 13:39 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon, Shuah Khan, Szabolcs Nagy
  Cc: linux-arm-kernel, linux-kselftest, Mark Brown, stable

The restoring of TPIDR2 signal context has been broken since it was
merged, fix this and add a test case covering it.  This is a result of
TPIDR2 context management following a different flow to any of the other
state that we provide and the fact that we don't expose TPIDR (which
follows the same pattern) to signals.

Signed-off-by: Mark Brown <broonie@kernel.org>
---
Changes in v2:
- Added a feature check for SME to the new test.
- Link to v1: https://lore.kernel.org/r/20230621-arm64-fix-tpidr2-signal-restore-v1-0-b6d9e584d2ee@kernel.org

---
Mark Brown (2):
      arm64/signal: Restore TPIDR2 register rather than memory state
      kselftest/arm64: Add a test case for TPIDR2 restore

 arch/arm64/kernel/signal.c                         |  2 +-
 tools/testing/selftests/arm64/signal/.gitignore    |  2 +-
 .../arm64/signal/testcases/tpidr2_restore.c        | 86 ++++++++++++++++++++++
 3 files changed, 88 insertions(+), 2 deletions(-)
---
base-commit: 858fd168a95c5b9669aac8db6c14a9aeab446375
change-id: 20230621-arm64-fix-tpidr2-signal-restore-713d93798f99

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


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

* [PATCH v2 0/2] arm64/signal: Fix handling of TPIDR2
@ 2023-06-22 13:39 ` Mark Brown
  0 siblings, 0 replies; 16+ messages in thread
From: Mark Brown @ 2023-06-22 13:39 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon, Shuah Khan, Szabolcs Nagy
  Cc: linux-arm-kernel, linux-kselftest, Mark Brown, stable

The restoring of TPIDR2 signal context has been broken since it was
merged, fix this and add a test case covering it.  This is a result of
TPIDR2 context management following a different flow to any of the other
state that we provide and the fact that we don't expose TPIDR (which
follows the same pattern) to signals.

Signed-off-by: Mark Brown <broonie@kernel.org>
---
Changes in v2:
- Added a feature check for SME to the new test.
- Link to v1: https://lore.kernel.org/r/20230621-arm64-fix-tpidr2-signal-restore-v1-0-b6d9e584d2ee@kernel.org

---
Mark Brown (2):
      arm64/signal: Restore TPIDR2 register rather than memory state
      kselftest/arm64: Add a test case for TPIDR2 restore

 arch/arm64/kernel/signal.c                         |  2 +-
 tools/testing/selftests/arm64/signal/.gitignore    |  2 +-
 .../arm64/signal/testcases/tpidr2_restore.c        | 86 ++++++++++++++++++++++
 3 files changed, 88 insertions(+), 2 deletions(-)
---
base-commit: 858fd168a95c5b9669aac8db6c14a9aeab446375
change-id: 20230621-arm64-fix-tpidr2-signal-restore-713d93798f99

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] 16+ messages in thread

* [PATCH v2 1/2] arm64/signal: Restore TPIDR2 register rather than memory state
  2023-06-22 13:39 ` Mark Brown
@ 2023-06-22 13:39   ` Mark Brown
  -1 siblings, 0 replies; 16+ messages in thread
From: Mark Brown @ 2023-06-22 13:39 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon, Shuah Khan, Szabolcs Nagy
  Cc: linux-arm-kernel, linux-kselftest, Mark Brown, stable

Currently when restoring the TPIDR2 signal context we set the new value
from the signal frame in the thread data structure but not the register,
following the pattern for the rest of the data we are restoring. This does
not work in the case of TPIDR2, the register always has the value for the
current task. This means that either we return to userspace and ignore the
new value or we context switch and save the register value on top of the
newly restored value.

Load the value from the signal context into the register instead.

Fixes: 39e54499280f ("arm64/signal: Include TPIDR2 in the signal context")
Signed-off-by: Mark Brown <broonie@kernel.org>
Cc: stable@vger.kernel.org
---
 arch/arm64/kernel/signal.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 2cfc810d0a5b..10b407672c42 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -398,7 +398,7 @@ static int restore_tpidr2_context(struct user_ctxs *user)
 
 	__get_user_error(tpidr2_el0, &user->tpidr2->tpidr2, err);
 	if (!err)
-		current->thread.tpidr2_el0 = tpidr2_el0;
+		write_sysreg_s(tpidr2_el0, SYS_TPIDR2_EL0);
 
 	return err;
 }

-- 
2.30.2


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

* [PATCH v2 1/2] arm64/signal: Restore TPIDR2 register rather than memory state
@ 2023-06-22 13:39   ` Mark Brown
  0 siblings, 0 replies; 16+ messages in thread
From: Mark Brown @ 2023-06-22 13:39 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon, Shuah Khan, Szabolcs Nagy
  Cc: linux-arm-kernel, linux-kselftest, Mark Brown, stable

Currently when restoring the TPIDR2 signal context we set the new value
from the signal frame in the thread data structure but not the register,
following the pattern for the rest of the data we are restoring. This does
not work in the case of TPIDR2, the register always has the value for the
current task. This means that either we return to userspace and ignore the
new value or we context switch and save the register value on top of the
newly restored value.

Load the value from the signal context into the register instead.

Fixes: 39e54499280f ("arm64/signal: Include TPIDR2 in the signal context")
Signed-off-by: Mark Brown <broonie@kernel.org>
Cc: stable@vger.kernel.org
---
 arch/arm64/kernel/signal.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 2cfc810d0a5b..10b407672c42 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -398,7 +398,7 @@ static int restore_tpidr2_context(struct user_ctxs *user)
 
 	__get_user_error(tpidr2_el0, &user->tpidr2->tpidr2, err);
 	if (!err)
-		current->thread.tpidr2_el0 = tpidr2_el0;
+		write_sysreg_s(tpidr2_el0, SYS_TPIDR2_EL0);
 
 	return err;
 }

-- 
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] 16+ messages in thread

* [PATCH v2 2/2] kselftest/arm64: Add a test case for TPIDR2 restore
  2023-06-22 13:39 ` Mark Brown
@ 2023-06-22 13:39   ` Mark Brown
  -1 siblings, 0 replies; 16+ messages in thread
From: Mark Brown @ 2023-06-22 13:39 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon, Shuah Khan, Szabolcs Nagy
  Cc: linux-arm-kernel, linux-kselftest, Mark Brown

Due to the fact that TPIDR2 is intended to be managed by libc we don't
currently test modifying it via the signal context since that might
disrupt libc's usage of it and cause instability. We can however test the
opposite case with less risk, modifying TPIDR2 in a signal handler and
making sure that the original value is restored after returning from the
signal handler. Add a test which does this.

Signed-off-by: Mark Brown <broonie@kernel.org>
---
 tools/testing/selftests/arm64/signal/.gitignore    |  2 +-
 .../arm64/signal/testcases/tpidr2_restore.c        | 86 ++++++++++++++++++++++
 2 files changed, 87 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/arm64/signal/.gitignore b/tools/testing/selftests/arm64/signal/.gitignore
index 8ab4c86837fd..839e3a252629 100644
--- a/tools/testing/selftests/arm64/signal/.gitignore
+++ b/tools/testing/selftests/arm64/signal/.gitignore
@@ -4,7 +4,7 @@ fake_sigreturn_*
 sme_*
 ssve_*
 sve_*
-tpidr2_siginfo
+tpidr2_*
 za_*
 zt_*
 !*.[ch]
diff --git a/tools/testing/selftests/arm64/signal/testcases/tpidr2_restore.c b/tools/testing/selftests/arm64/signal/testcases/tpidr2_restore.c
new file mode 100644
index 000000000000..f9a86c00c28c
--- /dev/null
+++ b/tools/testing/selftests/arm64/signal/testcases/tpidr2_restore.c
@@ -0,0 +1,86 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2023 ARM Limited
+ *
+ * Verify that the TPIDR2 register context in signal frames is restored.
+ */
+
+#include <signal.h>
+#include <ucontext.h>
+#include <sys/auxv.h>
+#include <sys/prctl.h>
+#include <unistd.h>
+#include <asm/sigcontext.h>
+
+#include "test_signals_utils.h"
+#include "testcases.h"
+
+#define SYS_TPIDR2 "S3_3_C13_C0_5"
+
+static uint64_t get_tpidr2(void)
+{
+	uint64_t val;
+
+	asm volatile (
+		"mrs	%0, " SYS_TPIDR2 "\n"
+		: "=r"(val)
+		:
+		: "cc");
+
+	return val;
+}
+
+static void set_tpidr2(uint64_t val)
+{
+	asm volatile (
+		"msr	" SYS_TPIDR2 ", %0\n"
+		:
+		: "r"(val)
+		: "cc");
+}
+
+
+static uint64_t initial_tpidr2;
+
+static bool save_tpidr2(struct tdescr *td)
+{
+	initial_tpidr2 = get_tpidr2();
+	fprintf(stderr, "Initial TPIDR2: %lx\n", initial_tpidr2);
+
+	return true;
+}
+
+static int modify_tpidr2(struct tdescr *td, siginfo_t *si, ucontext_t *uc)
+{
+	uint64_t my_tpidr2 = get_tpidr2();
+
+	my_tpidr2++;
+	fprintf(stderr, "Setting TPIDR2 to %lx\n", my_tpidr2);
+	set_tpidr2(my_tpidr2);
+
+	return 0;
+}
+
+static void check_tpidr2(struct tdescr *td)
+{
+	uint64_t tpidr2 = get_tpidr2();
+
+	td->pass = tpidr2 == initial_tpidr2;
+
+	if (td->pass)
+		fprintf(stderr, "TPIDR2 restored\n");
+	else
+		fprintf(stderr, "TPIDR2 was %lx but is now %lx\n",
+			initial_tpidr2, tpidr2);
+}
+
+struct tdescr tde = {
+	.name = "TPIDR2 restore",
+	.descr = "Validate that TPIDR2 is restored from the sigframe",
+	.feats_required = FEAT_SME,
+	.timeout = 3,
+	.sig_trig = SIGUSR1,
+	.init = save_tpidr2,
+	.run = modify_tpidr2,
+	.check_result = check_tpidr2,
+};

-- 
2.30.2


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

* [PATCH v2 2/2] kselftest/arm64: Add a test case for TPIDR2 restore
@ 2023-06-22 13:39   ` Mark Brown
  0 siblings, 0 replies; 16+ messages in thread
From: Mark Brown @ 2023-06-22 13:39 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon, Shuah Khan, Szabolcs Nagy
  Cc: linux-arm-kernel, linux-kselftest, Mark Brown

Due to the fact that TPIDR2 is intended to be managed by libc we don't
currently test modifying it via the signal context since that might
disrupt libc's usage of it and cause instability. We can however test the
opposite case with less risk, modifying TPIDR2 in a signal handler and
making sure that the original value is restored after returning from the
signal handler. Add a test which does this.

Signed-off-by: Mark Brown <broonie@kernel.org>
---
 tools/testing/selftests/arm64/signal/.gitignore    |  2 +-
 .../arm64/signal/testcases/tpidr2_restore.c        | 86 ++++++++++++++++++++++
 2 files changed, 87 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/arm64/signal/.gitignore b/tools/testing/selftests/arm64/signal/.gitignore
index 8ab4c86837fd..839e3a252629 100644
--- a/tools/testing/selftests/arm64/signal/.gitignore
+++ b/tools/testing/selftests/arm64/signal/.gitignore
@@ -4,7 +4,7 @@ fake_sigreturn_*
 sme_*
 ssve_*
 sve_*
-tpidr2_siginfo
+tpidr2_*
 za_*
 zt_*
 !*.[ch]
diff --git a/tools/testing/selftests/arm64/signal/testcases/tpidr2_restore.c b/tools/testing/selftests/arm64/signal/testcases/tpidr2_restore.c
new file mode 100644
index 000000000000..f9a86c00c28c
--- /dev/null
+++ b/tools/testing/selftests/arm64/signal/testcases/tpidr2_restore.c
@@ -0,0 +1,86 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2023 ARM Limited
+ *
+ * Verify that the TPIDR2 register context in signal frames is restored.
+ */
+
+#include <signal.h>
+#include <ucontext.h>
+#include <sys/auxv.h>
+#include <sys/prctl.h>
+#include <unistd.h>
+#include <asm/sigcontext.h>
+
+#include "test_signals_utils.h"
+#include "testcases.h"
+
+#define SYS_TPIDR2 "S3_3_C13_C0_5"
+
+static uint64_t get_tpidr2(void)
+{
+	uint64_t val;
+
+	asm volatile (
+		"mrs	%0, " SYS_TPIDR2 "\n"
+		: "=r"(val)
+		:
+		: "cc");
+
+	return val;
+}
+
+static void set_tpidr2(uint64_t val)
+{
+	asm volatile (
+		"msr	" SYS_TPIDR2 ", %0\n"
+		:
+		: "r"(val)
+		: "cc");
+}
+
+
+static uint64_t initial_tpidr2;
+
+static bool save_tpidr2(struct tdescr *td)
+{
+	initial_tpidr2 = get_tpidr2();
+	fprintf(stderr, "Initial TPIDR2: %lx\n", initial_tpidr2);
+
+	return true;
+}
+
+static int modify_tpidr2(struct tdescr *td, siginfo_t *si, ucontext_t *uc)
+{
+	uint64_t my_tpidr2 = get_tpidr2();
+
+	my_tpidr2++;
+	fprintf(stderr, "Setting TPIDR2 to %lx\n", my_tpidr2);
+	set_tpidr2(my_tpidr2);
+
+	return 0;
+}
+
+static void check_tpidr2(struct tdescr *td)
+{
+	uint64_t tpidr2 = get_tpidr2();
+
+	td->pass = tpidr2 == initial_tpidr2;
+
+	if (td->pass)
+		fprintf(stderr, "TPIDR2 restored\n");
+	else
+		fprintf(stderr, "TPIDR2 was %lx but is now %lx\n",
+			initial_tpidr2, tpidr2);
+}
+
+struct tdescr tde = {
+	.name = "TPIDR2 restore",
+	.descr = "Validate that TPIDR2 is restored from the sigframe",
+	.feats_required = FEAT_SME,
+	.timeout = 3,
+	.sig_trig = SIGUSR1,
+	.init = save_tpidr2,
+	.run = modify_tpidr2,
+	.check_result = check_tpidr2,
+};

-- 
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] 16+ messages in thread

* Re: [PATCH v2 1/2] arm64/signal: Restore TPIDR2 register rather than memory state
  2023-06-22 13:39   ` Mark Brown
@ 2023-06-22 16:42     ` Catalin Marinas
  -1 siblings, 0 replies; 16+ messages in thread
From: Catalin Marinas @ 2023-06-22 16:42 UTC (permalink / raw)
  To: Mark Brown
  Cc: Will Deacon, Shuah Khan, Szabolcs Nagy, linux-arm-kernel,
	linux-kselftest, stable

On Thu, Jun 22, 2023 at 02:39:45PM +0100, Mark Brown wrote:
> Currently when restoring the TPIDR2 signal context we set the new value
> from the signal frame in the thread data structure but not the register,
> following the pattern for the rest of the data we are restoring. This does
> not work in the case of TPIDR2, the register always has the value for the
> current task. This means that either we return to userspace and ignore the
> new value or we context switch and save the register value on top of the
> newly restored value.
> 
> Load the value from the signal context into the register instead.
> 
> Fixes: 39e54499280f ("arm64/signal: Include TPIDR2 in the signal context")
> Signed-off-by: Mark Brown <broonie@kernel.org>
> Cc: stable@vger.kernel.org
> ---
>  arch/arm64/kernel/signal.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
> index 2cfc810d0a5b..10b407672c42 100644
> --- a/arch/arm64/kernel/signal.c
> +++ b/arch/arm64/kernel/signal.c
> @@ -398,7 +398,7 @@ static int restore_tpidr2_context(struct user_ctxs *user)
>  
>  	__get_user_error(tpidr2_el0, &user->tpidr2->tpidr2, err);
>  	if (!err)
> -		current->thread.tpidr2_el0 = tpidr2_el0;
> +		write_sysreg_s(tpidr2_el0, SYS_TPIDR2_EL0);

I guess the other way around may also be true - the libc sets tpidr2_el0
to something else and doesn't want the kernel to restore its original
value from sigcontext.

For tpidr_el0 we don't bother with sigcontext, not sure what the use for
tpidr2_el0 in signals is. If we assume the context saved is only
informative (like esr), we can simply ignore restoring it from the
signal stack.

I guess we need to ask Szabolcs what his preference is. The current code
is wrong either way since current->thread.tpidr2_el0 would be overridden
at thread switch.

-- 
Catalin

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

* Re: [PATCH v2 1/2] arm64/signal: Restore TPIDR2 register rather than memory state
@ 2023-06-22 16:42     ` Catalin Marinas
  0 siblings, 0 replies; 16+ messages in thread
From: Catalin Marinas @ 2023-06-22 16:42 UTC (permalink / raw)
  To: Mark Brown
  Cc: Will Deacon, Shuah Khan, Szabolcs Nagy, linux-arm-kernel,
	linux-kselftest, stable

On Thu, Jun 22, 2023 at 02:39:45PM +0100, Mark Brown wrote:
> Currently when restoring the TPIDR2 signal context we set the new value
> from the signal frame in the thread data structure but not the register,
> following the pattern for the rest of the data we are restoring. This does
> not work in the case of TPIDR2, the register always has the value for the
> current task. This means that either we return to userspace and ignore the
> new value or we context switch and save the register value on top of the
> newly restored value.
> 
> Load the value from the signal context into the register instead.
> 
> Fixes: 39e54499280f ("arm64/signal: Include TPIDR2 in the signal context")
> Signed-off-by: Mark Brown <broonie@kernel.org>
> Cc: stable@vger.kernel.org
> ---
>  arch/arm64/kernel/signal.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
> index 2cfc810d0a5b..10b407672c42 100644
> --- a/arch/arm64/kernel/signal.c
> +++ b/arch/arm64/kernel/signal.c
> @@ -398,7 +398,7 @@ static int restore_tpidr2_context(struct user_ctxs *user)
>  
>  	__get_user_error(tpidr2_el0, &user->tpidr2->tpidr2, err);
>  	if (!err)
> -		current->thread.tpidr2_el0 = tpidr2_el0;
> +		write_sysreg_s(tpidr2_el0, SYS_TPIDR2_EL0);

I guess the other way around may also be true - the libc sets tpidr2_el0
to something else and doesn't want the kernel to restore its original
value from sigcontext.

For tpidr_el0 we don't bother with sigcontext, not sure what the use for
tpidr2_el0 in signals is. If we assume the context saved is only
informative (like esr), we can simply ignore restoring it from the
signal stack.

I guess we need to ask Szabolcs what his preference is. The current code
is wrong either way since current->thread.tpidr2_el0 would be overridden
at thread switch.

-- 
Catalin

_______________________________________________
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] 16+ messages in thread

* Re: [PATCH v2 1/2] arm64/signal: Restore TPIDR2 register rather than memory state
  2023-06-22 16:42     ` Catalin Marinas
@ 2023-06-22 17:11       ` Mark Brown
  -1 siblings, 0 replies; 16+ messages in thread
From: Mark Brown @ 2023-06-22 17:11 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Will Deacon, Shuah Khan, Szabolcs Nagy, linux-arm-kernel,
	linux-kselftest, stable

[-- Attachment #1: Type: text/plain, Size: 1205 bytes --]

On Thu, Jun 22, 2023 at 05:42:54PM +0100, Catalin Marinas wrote:
> On Thu, Jun 22, 2023 at 02:39:45PM +0100, Mark Brown wrote:

> > -		current->thread.tpidr2_el0 = tpidr2_el0;
> > +		write_sysreg_s(tpidr2_el0, SYS_TPIDR2_EL0);

> I guess the other way around may also be true - the libc sets tpidr2_el0
> to something else and doesn't want the kernel to restore its original
> value from sigcontext.

> For tpidr_el0 we don't bother with sigcontext, not sure what the use for
> tpidr2_el0 in signals is. If we assume the context saved is only
> informative (like esr), we can simply ignore restoring it from the
> signal stack.

TPIDR2 is intended to go along with the thread stack, it's intended to
be used to allow lazy save of the (rather large) ZA register state when
a called function needs it rather than forcing it to be caller saved.
TPIDR2 is used to point to memory allocated for managing this process,
something that provides a new value should be making a deliberate
decision to do so and editing the stack frame.

> I guess we need to ask Szabolcs what his preference is. The current code
> is wrong either way since current->thread.tpidr2_el0 would be overridden
> at thread switch.

Right.

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

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

* Re: [PATCH v2 1/2] arm64/signal: Restore TPIDR2 register rather than memory state
@ 2023-06-22 17:11       ` Mark Brown
  0 siblings, 0 replies; 16+ messages in thread
From: Mark Brown @ 2023-06-22 17:11 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Will Deacon, Shuah Khan, Szabolcs Nagy, linux-arm-kernel,
	linux-kselftest, stable


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

On Thu, Jun 22, 2023 at 05:42:54PM +0100, Catalin Marinas wrote:
> On Thu, Jun 22, 2023 at 02:39:45PM +0100, Mark Brown wrote:

> > -		current->thread.tpidr2_el0 = tpidr2_el0;
> > +		write_sysreg_s(tpidr2_el0, SYS_TPIDR2_EL0);

> I guess the other way around may also be true - the libc sets tpidr2_el0
> to something else and doesn't want the kernel to restore its original
> value from sigcontext.

> For tpidr_el0 we don't bother with sigcontext, not sure what the use for
> tpidr2_el0 in signals is. If we assume the context saved is only
> informative (like esr), we can simply ignore restoring it from the
> signal stack.

TPIDR2 is intended to go along with the thread stack, it's intended to
be used to allow lazy save of the (rather large) ZA register state when
a called function needs it rather than forcing it to be caller saved.
TPIDR2 is used to point to memory allocated for managing this process,
something that provides a new value should be making a deliberate
decision to do so and editing the stack frame.

> I guess we need to ask Szabolcs what his preference is. The current code
> is wrong either way since current->thread.tpidr2_el0 would be overridden
> at thread switch.

Right.

[-- 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] 16+ messages in thread

* Re: [PATCH v2 1/2] arm64/signal: Restore TPIDR2 register rather than memory state
  2023-06-22 17:11       ` Mark Brown
@ 2023-06-23 17:28         ` Catalin Marinas
  -1 siblings, 0 replies; 16+ messages in thread
From: Catalin Marinas @ 2023-06-23 17:28 UTC (permalink / raw)
  To: Mark Brown
  Cc: Will Deacon, Shuah Khan, Szabolcs Nagy, linux-arm-kernel,
	linux-kselftest, stable

On Thu, Jun 22, 2023 at 06:11:20PM +0100, Mark Brown wrote:
> On Thu, Jun 22, 2023 at 05:42:54PM +0100, Catalin Marinas wrote:
> > On Thu, Jun 22, 2023 at 02:39:45PM +0100, Mark Brown wrote:
> 
> > > -		current->thread.tpidr2_el0 = tpidr2_el0;
> > > +		write_sysreg_s(tpidr2_el0, SYS_TPIDR2_EL0);
> 
> > I guess the other way around may also be true - the libc sets tpidr2_el0
> > to something else and doesn't want the kernel to restore its original
> > value from sigcontext.
> 
> > For tpidr_el0 we don't bother with sigcontext, not sure what the use for
> > tpidr2_el0 in signals is. If we assume the context saved is only
> > informative (like esr), we can simply ignore restoring it from the
> > signal stack.
> 
> TPIDR2 is intended to go along with the thread stack, it's intended to
> be used to allow lazy save of the (rather large) ZA register state when
> a called function needs it rather than forcing it to be caller saved.
> TPIDR2 is used to point to memory allocated for managing this process,
> something that provides a new value should be making a deliberate
> decision to do so and editing the stack frame.

OK, so if the signal handler invokes a function that touches the ZA
state, it may use TPIDR2 for lazy saving in any callee. In this case we
need to restore the original TPIDR2 of the interrupted context on
sigreturn.

So I convinced myself this is the only option that makes sense ;). I'll
queue the patches.

-- 
Catalin

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

* Re: [PATCH v2 1/2] arm64/signal: Restore TPIDR2 register rather than memory state
@ 2023-06-23 17:28         ` Catalin Marinas
  0 siblings, 0 replies; 16+ messages in thread
From: Catalin Marinas @ 2023-06-23 17:28 UTC (permalink / raw)
  To: Mark Brown
  Cc: Will Deacon, Shuah Khan, Szabolcs Nagy, linux-arm-kernel,
	linux-kselftest, stable

On Thu, Jun 22, 2023 at 06:11:20PM +0100, Mark Brown wrote:
> On Thu, Jun 22, 2023 at 05:42:54PM +0100, Catalin Marinas wrote:
> > On Thu, Jun 22, 2023 at 02:39:45PM +0100, Mark Brown wrote:
> 
> > > -		current->thread.tpidr2_el0 = tpidr2_el0;
> > > +		write_sysreg_s(tpidr2_el0, SYS_TPIDR2_EL0);
> 
> > I guess the other way around may also be true - the libc sets tpidr2_el0
> > to something else and doesn't want the kernel to restore its original
> > value from sigcontext.
> 
> > For tpidr_el0 we don't bother with sigcontext, not sure what the use for
> > tpidr2_el0 in signals is. If we assume the context saved is only
> > informative (like esr), we can simply ignore restoring it from the
> > signal stack.
> 
> TPIDR2 is intended to go along with the thread stack, it's intended to
> be used to allow lazy save of the (rather large) ZA register state when
> a called function needs it rather than forcing it to be caller saved.
> TPIDR2 is used to point to memory allocated for managing this process,
> something that provides a new value should be making a deliberate
> decision to do so and editing the stack frame.

OK, so if the signal handler invokes a function that touches the ZA
state, it may use TPIDR2 for lazy saving in any callee. In this case we
need to restore the original TPIDR2 of the interrupted context on
sigreturn.

So I convinced myself this is the only option that makes sense ;). I'll
queue the patches.

-- 
Catalin

_______________________________________________
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] 16+ messages in thread

* Re: [PATCH v2 0/2] arm64/signal: Fix handling of TPIDR2
  2023-06-22 13:39 ` Mark Brown
@ 2023-06-23 17:37   ` Catalin Marinas
  -1 siblings, 0 replies; 16+ messages in thread
From: Catalin Marinas @ 2023-06-23 17:37 UTC (permalink / raw)
  To: Will Deacon, Shuah Khan, Szabolcs Nagy, Mark Brown
  Cc: linux-arm-kernel, linux-kselftest, stable

On Thu, 22 Jun 2023 14:39:44 +0100, Mark Brown wrote:
> The restoring of TPIDR2 signal context has been broken since it was
> merged, fix this and add a test case covering it.  This is a result of
> TPIDR2 context management following a different flow to any of the other
> state that we provide and the fact that we don't expose TPIDR (which
> follows the same pattern) to signals.
> 
> 
> [...]

Applied to arm64 (for-next/tpidr2-fix), thanks!

[1/2] arm64/signal: Restore TPIDR2 register rather than memory state
      https://git.kernel.org/arm64/c/616cb2f4b141
[2/2] kselftest/arm64: Add a test case for TPIDR2 restore
      https://git.kernel.org/arm64/c/f7a5d72edc52

-- 
Catalin


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

* Re: [PATCH v2 0/2] arm64/signal: Fix handling of TPIDR2
@ 2023-06-23 17:37   ` Catalin Marinas
  0 siblings, 0 replies; 16+ messages in thread
From: Catalin Marinas @ 2023-06-23 17:37 UTC (permalink / raw)
  To: Will Deacon, Shuah Khan, Szabolcs Nagy, Mark Brown
  Cc: linux-arm-kernel, linux-kselftest, stable

On Thu, 22 Jun 2023 14:39:44 +0100, Mark Brown wrote:
> The restoring of TPIDR2 signal context has been broken since it was
> merged, fix this and add a test case covering it.  This is a result of
> TPIDR2 context management following a different flow to any of the other
> state that we provide and the fact that we don't expose TPIDR (which
> follows the same pattern) to signals.
> 
> 
> [...]

Applied to arm64 (for-next/tpidr2-fix), thanks!

[1/2] arm64/signal: Restore TPIDR2 register rather than memory state
      https://git.kernel.org/arm64/c/616cb2f4b141
[2/2] kselftest/arm64: Add a test case for TPIDR2 restore
      https://git.kernel.org/arm64/c/f7a5d72edc52

-- 
Catalin


_______________________________________________
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] 16+ messages in thread

* Re: [PATCH v2 1/2] arm64/signal: Restore TPIDR2 register rather than memory state
  2023-06-23 17:28         ` Catalin Marinas
@ 2023-06-23 18:22           ` Mark Brown
  -1 siblings, 0 replies; 16+ messages in thread
From: Mark Brown @ 2023-06-23 18:22 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Will Deacon, Shuah Khan, Szabolcs Nagy, linux-arm-kernel,
	linux-kselftest, stable

[-- Attachment #1: Type: text/plain, Size: 1013 bytes --]

On Fri, Jun 23, 2023 at 06:28:12PM +0100, Catalin Marinas wrote:
> On Thu, Jun 22, 2023 at 06:11:20PM +0100, Mark Brown wrote:

> > TPIDR2 is intended to go along with the thread stack, it's intended to
> > be used to allow lazy save of the (rather large) ZA register state when
> > a called function needs it rather than forcing it to be caller saved.
> > TPIDR2 is used to point to memory allocated for managing this process,
> > something that provides a new value should be making a deliberate
> > decision to do so and editing the stack frame.

> OK, so if the signal handler invokes a function that touches the ZA
> state, it may use TPIDR2 for lazy saving in any callee. In this case we
> need to restore the original TPIDR2 of the interrupted context on
> sigreturn.

Yeah, or if something tries to sigreturn to a previously saved context
which had live TPIDR2 state things might end up unfortunate.

> So I convinced myself this is the only option that makes sense ;). I'll
> queue the patches.

Thanks.

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

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

* Re: [PATCH v2 1/2] arm64/signal: Restore TPIDR2 register rather than memory state
@ 2023-06-23 18:22           ` Mark Brown
  0 siblings, 0 replies; 16+ messages in thread
From: Mark Brown @ 2023-06-23 18:22 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Will Deacon, Shuah Khan, Szabolcs Nagy, linux-arm-kernel,
	linux-kselftest, stable


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

On Fri, Jun 23, 2023 at 06:28:12PM +0100, Catalin Marinas wrote:
> On Thu, Jun 22, 2023 at 06:11:20PM +0100, Mark Brown wrote:

> > TPIDR2 is intended to go along with the thread stack, it's intended to
> > be used to allow lazy save of the (rather large) ZA register state when
> > a called function needs it rather than forcing it to be caller saved.
> > TPIDR2 is used to point to memory allocated for managing this process,
> > something that provides a new value should be making a deliberate
> > decision to do so and editing the stack frame.

> OK, so if the signal handler invokes a function that touches the ZA
> state, it may use TPIDR2 for lazy saving in any callee. In this case we
> need to restore the original TPIDR2 of the interrupted context on
> sigreturn.

Yeah, or if something tries to sigreturn to a previously saved context
which had live TPIDR2 state things might end up unfortunate.

> So I convinced myself this is the only option that makes sense ;). I'll
> queue the patches.

Thanks.

[-- 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] 16+ messages in thread

end of thread, other threads:[~2023-06-23 18:23 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-22 13:39 [PATCH v2 0/2] arm64/signal: Fix handling of TPIDR2 Mark Brown
2023-06-22 13:39 ` Mark Brown
2023-06-22 13:39 ` [PATCH v2 1/2] arm64/signal: Restore TPIDR2 register rather than memory state Mark Brown
2023-06-22 13:39   ` Mark Brown
2023-06-22 16:42   ` Catalin Marinas
2023-06-22 16:42     ` Catalin Marinas
2023-06-22 17:11     ` Mark Brown
2023-06-22 17:11       ` Mark Brown
2023-06-23 17:28       ` Catalin Marinas
2023-06-23 17:28         ` Catalin Marinas
2023-06-23 18:22         ` Mark Brown
2023-06-23 18:22           ` Mark Brown
2023-06-22 13:39 ` [PATCH v2 2/2] kselftest/arm64: Add a test case for TPIDR2 restore Mark Brown
2023-06-22 13:39   ` Mark Brown
2023-06-23 17:37 ` [PATCH v2 0/2] arm64/signal: Fix handling of TPIDR2 Catalin Marinas
2023-06-23 17:37   ` Catalin Marinas

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.