As other exit points, move SRR1 (MSR) into paca->tm_scratch, so, if
there is a TM Bad Thing in RFID, it is easy to understand what was the
SRR1 value being used.
Signed-off-by: Breno Leitao <leitao@debian.org>
---
arch/powerpc/kernel/entry_64.S | 4 ++++
1 file changed, 4 insertions(+)
Usually a TM Bad Thing exception is raised due to three different problems.
a) touching SPRs in an active transaction; b) using TM instruction with the
facility disabled and c) setting a wrong MSR/SRR1 at RFID.
The two initial cases are easy to identify by looking at the instructions.
The latter case is harder, because the MSR is masked after RFID, so, it is
very useful to look at the previous MSR (SRR1) before RFID as also the
current and masked MSR.
Since MSR is saved at paca just before RFID, this patch prints it if a TM
Bad thing happen, helping to understand what is the invalid TM transition
that is causing the exception.
Signed-off-by: Breno Leitao <leitao@debian.org>
---
arch/powerpc/kernel/traps.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
This is a new test case that creates a signal and starts a suspended
transaction inside the signal handler.
It returns from the signal handler with the CPU at suspended state, but
without setting user context MSR Transaction State (TS) field.
The kernel signal handler code should be able to handle this discrepancy
instead of crashing.
This code could be compiled and used to test 32 and 64-bits signal
handlers.
Signed-off-by: Breno Leitao <leitao@debian.org>
Signed-off-by: Gustavo Romero <redacted>
---
tools/testing/selftests/powerpc/tm/.gitignore | 1 +
tools/testing/selftests/powerpc/tm/Makefile | 2 +-
.../powerpc/tm/tm-signal-sigreturn-nt.c | 46 +++++++++++++++++++
3 files changed, 48 insertions(+), 1 deletion(-)
create mode 100644 tools/testing/selftests/powerpc/tm/tm-signal-sigreturn-nt.c
There is a TM Bad Thing bug that can be caused when you return from a
signal context in a suspended transaction but with ucontext MSR[TS] unset.
This forces regs->msr[TS] to be set at syscall entrance (since the CPU
state is transactional). It also calls treclaim() to flush the transaction
state, which is done based on the live (mfmsr) MSR state.
Since user context MSR[TS] is not set, then restore_tm_sigcontexts() is not
called, thus, not executing recheckpoint, keeping the CPU state as not
transactional. When calling rfid, SRR1 will have MSR[TS] set, but the CPU
state is non transactional, causing the TM Bad Thing with the following
stack:
[ 33.862316] Bad kernel stack pointer 3fffd9dce3e0 at c00000000000c47c
cpu 0x8: Vector: 700 (Program Check) at [c00000003ff7fd40]
pc: c00000000000c47c: fast_exception_return+0xac/0xb4
lr: 00003fff865f442c
sp: 3fffd9dce3e0
msr: 8000000102a03031
current = 0xc00000041f68b700
paca = 0xc00000000fb84800 softe: 0 irq_happened: 0x01
pid = 1721, comm = tm-signal-sigre
Linux version 4.9.0-3-powerpc64le (debian-kernel@lists.debian.org) (gcc version 6.3.0 20170516 (Debian 6.3.0-18) ) #1 SMP Debian 4.9.30-2+deb9u2 (2017-06-26)
WARNING: exception is not recoverable, can't continue
The same problem happens on 32-bits signal handler, and the fix is very
similar, if tm_recheckpoint() is not executed, then regs->msr[TS] should be
zeroed.
This patch also fixes a sparse warning related to lack of indentation when
CONFIG_PPC_TRANSACTIONAL_MEM is set.
Fixes: 2b0a576d15e0e ("powerpc: Add new transactional memory state to the signal context")
CC: Stable <redacted> # 3.10+
Signed-off-by: Breno Leitao <leitao@debian.org>
---
arch/powerpc/kernel/signal_32.c | 18 +++++++++++++-----
arch/powerpc/kernel/signal_64.c | 20 ++++++++++++++++----
2 files changed, 29 insertions(+), 9 deletions(-)
@@ -1140,11 +1140,11 @@ SYSCALL_DEFINE0(rt_sigreturn){structrt_sigframe__user*rt_sf;structpt_regs*regs=current_pt_regs();+inttm_restore=0;#ifdef CONFIG_PPC_TRANSACTIONAL_MEMstructucontext__user*uc_transact;unsignedlongmsr_hi;unsignedlongtmp;-inttm_restore=0;#endif/* Always make any pending restarted system calls return -EINTR */current->restart_block.fn=do_no_restart_syscall;
@@ -1192,11 +1192,19 @@ SYSCALL_DEFINE0(rt_sigreturn)gotobad;}}-if(!tm_restore)-/* Fall through, for non-TM restore */+if(!tm_restore){+/*+*Unsetregs->msrbecauseucontextMSRTSisnot+*set,andrecheckpointwasnotcalled.Thisavoid+*hittingaTMBadthingatRFID+*/+regs->msr&=~MSR_TS_MASK;+}+/* Fall through, for non-TM restore */#endif-if(do_setcontext(&rt_sf->uc,regs,1))-gotobad;+if(!tm_restore)+if(do_setcontext(&rt_sf->uc,regs,1))+gotobad;/**It'snotclearwhetherorwhyitisdesirabletosavethe
@@ -740,11 +740,23 @@ SYSCALL_DEFINE0(rt_sigreturn)&uc_transact->uc_mcontext))gotobadframe;}-else-/* Fall through, for non-TM restore */#endif-if(restore_sigcontext(current,NULL,1,&uc->uc_mcontext))-gotobadframe;+/* Fall through, for non-TM restore */+if(!MSR_TM_ACTIVE(msr)){+/*+*UnsetMSR[TS]onthethreadregssinceMSRfromuser+*contextdoesnothaveMSRactive,andrecheckpointwas+*notcalledsincerestore_tm_sigcontexts()wasnotcalled+*also.+*+*Ifnotunsettingit,thecodecanRFIDtouserspacewith+*MSR[TS]set,butwithoutCPUintheproperstate,+*causingaTMbadthing.+*/+current->thread.regs->msr&=~MSR_TS_MASK;+if(restore_sigcontext(current,NULL,1,&uc->uc_mcontext))+gotobadframe;+}if(restore_altstack(&uc->uc_stack))gotobadframe;
From: Michal Suchánek <hidden> Date: 2018-12-07 13:48:41
On Mon, 26 Nov 2018 18:12:00 -0200
Breno Leitao [off-list ref] wrote:
There is a TM Bad Thing bug that can be caused when you return from a
signal context in a suspended transaction but with ucontext MSR[TS] unset.
This forces regs->msr[TS] to be set at syscall entrance (since the CPU
state is transactional). It also calls treclaim() to flush the transaction
state, which is done based on the live (mfmsr) MSR state.
Since user context MSR[TS] is not set, then restore_tm_sigcontexts() is not
called, thus, not executing recheckpoint, keeping the CPU state as not
transactional. When calling rfid, SRR1 will have MSR[TS] set, but the CPU
state is non transactional, causing the TM Bad Thing with the following
stack:
Works for me on Linux 4.4 and 4.12
Tested-by: Michal Suchánek <redacted>
Thanks
From: Michael Ellerman <hidden> Date: 2018-12-23 13:36:54
On Mon, 2018-11-26 at 20:11:58 UTC, Breno Leitao wrote:
As other exit points, move SRR1 (MSR) into paca->tm_scratch, so, if
there is a TM Bad Thing in RFID, it is easy to understand what was the
SRR1 value being used.
Signed-off-by: Breno Leitao <leitao@debian.org>