Since every kernel entrance is calling TM_KERNEL_ENTRY, it is not
expected to arrive at this point with a suspended transaction.

If that is the case, cause a warning and reclaim the current thread in
order to avoid a TM Bad Thing.

Signed-off-by: Breno Leitao <lei...@debian.org>
---
 arch/powerpc/kernel/process.c | 7 +++----
 arch/powerpc/kernel/signal.c  | 2 +-
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 73872f751b33..849591bf0881 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1752,11 +1752,10 @@ void start_thread(struct pt_regs *regs, unsigned long 
start, unsigned long sp)
 
 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
        /*
-        * Clear any transactional state, we're exec()ing. The cause is
-        * not important as there will never be a recheckpoint so it's not
-        * user visible.
+        * It is a bug if the transaction was not reclaimed until this
+        * point. Warn us and try to workaround it calling tm_reclaim().
         */
-       if (MSR_TM_SUSPENDED(mfmsr()))
+       if (WARN_ON(MSR_TM_SUSPENDED(mfmsr())))
                tm_reclaim_current(0);
 #endif
 
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index b3e8db376ecd..cbaccc2be0fb 100644
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -203,7 +203,7 @@ unsigned long get_tm_stackpointer(struct task_struct *tsk)
 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
        BUG_ON(tsk != current);
 
-       if (MSR_TM_ACTIVE(tsk->thread.regs->msr)) {
+       if (WARN_ON(MSR_TM_ACTIVE(mfmsr()))) {
                tm_reclaim_current(TM_CAUSE_SIGNAL);
                if (MSR_TM_TRANSACTIONAL(tsk->thread.regs->msr))
                        return tsk->thread.ckpt_regs.gpr[1];
-- 
2.19.0

Reply via email to