Skip to content

Commit

Permalink
powerpc/tm: Fix restoration of MSR on 32bit signal return
Browse files Browse the repository at this point in the history
Currently we clear out the MSR TM bits on signal return assuming that the
signal should never return to an active transaction.

This is bogus as the user may do this.  It's most likely the transaction will
be doomed due to a treclaim but that's a problem for the HW not the kernel.

The current code is a legacy of earlier kernel implementations which did
software rollback of active transactions in the kernel.  That code has now gone
but we didn't correctly fix up this part of the signals code which still makes
the assumption that it must be returning to a suspended transaction.

This pulls out both MSR TM bits from the user supplied context rather than just
setting TM suspend.  We pull out only the bits needed to ensure the user can't
do anything dangerous to the MSR.

Signed-off-by: Michael Neuling <mikey@neuling.org>
cc: stable@vger.kernel.org (v3.9+)
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
  • Loading branch information
Michael Neuling authored and Benjamin Herrenschmidt committed Jun 20, 2013
1 parent fee5545 commit 2c27a18
Showing 1 changed file with 6 additions and 3 deletions.
9 changes: 6 additions & 3 deletions arch/powerpc/kernel/signal_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -754,7 +754,7 @@ static long restore_tm_user_regs(struct pt_regs *regs,
struct mcontext __user *tm_sr)
{
long err;
unsigned long msr;
unsigned long msr, msr_hi;
#ifdef CONFIG_VSX
int i;
#endif
Expand Down Expand Up @@ -859,8 +859,11 @@ static long restore_tm_user_regs(struct pt_regs *regs,
tm_enable();
/* This loads the checkpointed FP/VEC state, if used */
tm_recheckpoint(&current->thread, msr);
/* The task has moved into TM state S, so ensure MSR reflects this */
regs->msr = (regs->msr & ~MSR_TS_MASK) | MSR_TS_S;
/* Get the top half of the MSR */
if (__get_user(msr_hi, &tm_sr->mc_gregs[PT_MSR]))
return 1;
/* Pull in MSR TM from user context */
regs->msr = (regs->msr & ~MSR_TS_MASK) | ((msr_hi<<32) & MSR_TS_MASK);

/* This loads the speculative FP/VEC state, if used */
if (msr & MSR_FP) {
Expand Down

0 comments on commit 2c27a18

Please sign in to comment.