--- /dev/null
+From 265e60a170d0a0ecfc2d20490134ed2c48dd45ab Mon Sep 17 00:00:00 2001
+From: Cyril Bur <cyrilbur@gmail.com>
+Date: Thu, 17 Aug 2017 20:42:26 +1000
+Subject: powerpc/64s: Use emergency stack for kernel TM Bad Thing program checks
+
+From: Cyril Bur <cyrilbur@gmail.com>
+
+commit 265e60a170d0a0ecfc2d20490134ed2c48dd45ab upstream.
+
+When using transactional memory (TM), the CPU can be in one of six
+states as far as TM is concerned, encoded in the Machine State
+Register (MSR). Certain state transitions are illegal and if attempted
+trigger a "TM Bad Thing" type program check exception.
+
+If we ever hit one of these exceptions it's treated as a bug, ie. we
+oops, and kill the process and/or panic, depending on configuration.
+
+One case where we can trigger a TM Bad Thing, is when returning to
+userspace after a system call or interrupt, using RFID. When this
+happens the CPU first restores the user register state, in particular
+r1 (the stack pointer) and then attempts to update the MSR. However
+the MSR update is not allowed and so we take the program check with
+the user register state, but the kernel MSR.
+
+This tricks the exception entry code into thinking we have a bad
+kernel stack pointer, because the MSR says we're coming from the
+kernel, but r1 is pointing to userspace.
+
+To avoid this we instead always switch to the emergency stack if we
+take a TM Bad Thing from the kernel. That way none of the user
+register values are used, other than for printing in the oops message.
+
+This is the fix for CVE-2017-1000255.
+
+Fixes: 5d176f751ee3 ("powerpc: tm: Enable transactional memory (TM) lazily for userspace")
+Signed-off-by: Cyril Bur <cyrilbur@gmail.com>
+[mpe: Rewrite change log & comments, tweak asm slightly]
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/kernel/exceptions-64s.S | 24 +++++++++++++++++++++++-
+ 1 file changed, 23 insertions(+), 1 deletion(-)
+
+--- a/arch/powerpc/kernel/exceptions-64s.S
++++ b/arch/powerpc/kernel/exceptions-64s.S
+@@ -764,7 +764,29 @@ EXC_REAL(program_check, 0x700, 0x800)
+ EXC_VIRT(program_check, 0x4700, 0x4800, 0x700)
+ TRAMP_KVM(PACA_EXGEN, 0x700)
+ EXC_COMMON_BEGIN(program_check_common)
+- EXCEPTION_PROLOG_COMMON(0x700, PACA_EXGEN)
++ /*
++ * It's possible to receive a TM Bad Thing type program check with
++ * userspace register values (in particular r1), but with SRR1 reporting
++ * that we came from the kernel. Normally that would confuse the bad
++ * stack logic, and we would report a bad kernel stack pointer. Instead
++ * we switch to the emergency stack if we're taking a TM Bad Thing from
++ * the kernel.
++ */
++ li r10,MSR_PR /* Build a mask of MSR_PR .. */
++ oris r10,r10,0x200000@h /* .. and SRR1_PROGTM */
++ and r10,r10,r12 /* Mask SRR1 with that. */
++ srdi r10,r10,8 /* Shift it so we can compare */
++ cmpldi r10,(0x200000 >> 8) /* .. with an immediate. */
++ bne 1f /* If != go to normal path. */
++
++ /* SRR1 had PR=0 and SRR1_PROGTM=1, so use the emergency stack */
++ andi. r10,r12,MSR_PR; /* Set CR0 correctly for label */
++ /* 3 in EXCEPTION_PROLOG_COMMON */
++ mr r10,r1 /* Save r1 */
++ ld r1,PACAEMERGSP(r13) /* Use emergency stack */
++ subi r1,r1,INT_FRAME_SIZE /* alloc stack frame */
++ b 3f /* Jump into the macro !! */
++1: EXCEPTION_PROLOG_COMMON(0x700, PACA_EXGEN)
+ bl save_nvgprs
+ RECONCILE_IRQ_STATE(r10, r11)
+ addi r3,r1,STACK_FRAME_OVERHEAD
--- /dev/null
+From 044215d145a7a8a60ffa8fdc859d110a795fa6ea Mon Sep 17 00:00:00 2001
+From: Gustavo Romero <gromero@linux.vnet.ibm.com>
+Date: Tue, 22 Aug 2017 17:20:09 -0400
+Subject: powerpc/tm: Fix illegal TM state in signal handler
+
+From: Gustavo Romero <gromero@linux.vnet.ibm.com>
+
+commit 044215d145a7a8a60ffa8fdc859d110a795fa6ea upstream.
+
+Currently it's possible that on returning from the signal handler
+through the restore_tm_sigcontexts() code path (e.g. from a signal
+caught due to a `trap` instruction executed in the middle of an HTM
+block, or a deliberately constructed sigframe) an illegal TM state
+(like TS=10 TM=0, i.e. "T0") is set in SRR1 and when `rfid` sets
+implicitly the MSR register from SRR1 register on return to userspace
+it causes a TM Bad Thing exception.
+
+That illegal state can be set (a) by a malicious user that disables
+the TM bit by tweaking the bits in uc_mcontext before returning from
+the signal handler or (b) by a sufficient number of context switches
+occurring such that the load_tm counter overflows and TM is disabled
+whilst in the signal handler.
+
+This commit fixes the illegal TM state by ensuring that TM bit is
+always enabled before we return from restore_tm_sigcontexts(). A small
+comment correction is made as well.
+
+Fixes: 5d176f751ee3 ("powerpc: tm: Enable transactional memory (TM) lazily for userspace")
+Signed-off-by: Gustavo Romero <gromero@linux.vnet.ibm.com>
+Signed-off-by: Breno Leitao <leitao@debian.org>
+Signed-off-by: Cyril Bur <cyrilbur@gmail.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/kernel/signal_64.c | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+--- a/arch/powerpc/kernel/signal_64.c
++++ b/arch/powerpc/kernel/signal_64.c
+@@ -452,9 +452,20 @@ static long restore_tm_sigcontexts(struc
+ if (MSR_TM_RESV(msr))
+ return -EINVAL;
+
+- /* pull in MSR TM from user context */
++ /* pull in MSR TS bits from user context */
+ regs->msr = (regs->msr & ~MSR_TS_MASK) | (msr & MSR_TS_MASK);
+
++ /*
++ * Ensure that TM is enabled in regs->msr before we leave the signal
++ * handler. It could be the case that (a) user disabled the TM bit
++ * through the manipulation of the MSR bits in uc_mcontext or (b) the
++ * TM bit was disabled because a sufficient number of context switches
++ * happened whilst in the signal handler and load_tm overflowed,
++ * disabling the TM bit. In either case we can end up with an illegal
++ * TM state leading to a TM Bad Thing when we return to userspace.
++ */
++ regs->msr |= MSR_TM;
++
+ /* pull in MSR LE from user context */
+ regs->msr = (regs->msr & ~MSR_LE) | (msr & MSR_LE);
+