summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/process.c
diff options
context:
space:
mode:
authorMichael Ellerman <mpe@ellerman.id.au>2015-12-14 20:40:32 +1100
committerMichael Ellerman <mpe@ellerman.id.au>2015-12-14 20:40:32 +1100
commit1901d8bb45c3b82335c48e6232871f72ad10ed95 (patch)
tree8e386d105cec283147bd56e716de69299cc54fbc /arch/powerpc/kernel/process.c
parent801c0b2c4db3a33d56b3e19240df7b897e5bbfbc (diff)
parent7f821fc9c77a9b01fe7b1d6e72717b33d8d64142 (diff)
downloadlinux-1901d8bb45c3b82335c48e6232871f72ad10ed95.tar.gz
linux-1901d8bb45c3b82335c48e6232871f72ad10ed95.tar.bz2
linux-1901d8bb45c3b82335c48e6232871f72ad10ed95.zip
Merge tag 'powerpc-4.4-3' into next
Merge the two TM fixes we merged in 4.4. We are about to merge selftests for these, and without the fixes the selftests will oops. powerpc fixes for 4.4 #2 - tm: Block signal return from setting invalid MSR state from Michael Neuling - tm: Check for already reclaimed tasks from Michael Neuling
Diffstat (limited to 'arch/powerpc/kernel/process.c')
-rw-r--r--arch/powerpc/kernel/process.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index ab9373bfabda..dccc87e8fee5 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -640,6 +640,24 @@ static void tm_reclaim_thread(struct thread_struct *thr,
msr_diff &= MSR_FP | MSR_VEC | MSR_VSX | MSR_FE0 | MSR_FE1;
}
+ /*
+ * Use the current MSR TM suspended bit to track if we have
+ * checkpointed state outstanding.
+ * On signal delivery, we'd normally reclaim the checkpointed
+ * state to obtain stack pointer (see:get_tm_stackpointer()).
+ * This will then directly return to userspace without going
+ * through __switch_to(). However, if the stack frame is bad,
+ * we need to exit this thread which calls __switch_to() which
+ * will again attempt to reclaim the already saved tm state.
+ * Hence we need to check that we've not already reclaimed
+ * this state.
+ * We do this using the current MSR, rather tracking it in
+ * some specific thread_struct bit, as it has the additional
+ * benifit of checking for a potential TM bad thing exception.
+ */
+ if (!MSR_TM_SUSPENDED(mfmsr()))
+ return;
+
tm_reclaim(thr, thr->regs->msr, cause);
/* Having done the reclaim, we now have the checkpointed