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.