|
|
@@ -551,6 +551,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
|