aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/kernel/signal_64.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index c83c115858c1..b2c002993d78 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -452,9 +452,20 @@ static long restore_tm_sigcontexts(struct task_struct *tsk,
452 if (MSR_TM_RESV(msr)) 452 if (MSR_TM_RESV(msr))
453 return -EINVAL; 453 return -EINVAL;
454 454
455 /* pull in MSR TM from user context */ 455 /* pull in MSR TS bits from user context */
456 regs->msr = (regs->msr & ~MSR_TS_MASK) | (msr & MSR_TS_MASK); 456 regs->msr = (regs->msr & ~MSR_TS_MASK) | (msr & MSR_TS_MASK);
457 457
458 /*
459 * Ensure that TM is enabled in regs->msr before we leave the signal
460 * handler. It could be the case that (a) user disabled the TM bit
461 * through the manipulation of the MSR bits in uc_mcontext or (b) the
462 * TM bit was disabled because a sufficient number of context switches
463 * happened whilst in the signal handler and load_tm overflowed,
464 * disabling the TM bit. In either case we can end up with an illegal
465 * TM state leading to a TM Bad Thing when we return to userspace.
466 */
467 regs->msr |= MSR_TM;
468
458 /* pull in MSR LE from user context */ 469 /* pull in MSR LE from user context */
459 regs->msr = (regs->msr & ~MSR_LE) | (msr & MSR_LE); 470 regs->msr = (regs->msr & ~MSR_LE) | (msr & MSR_LE);
460 471