--- arch/powerpc/kernel/process.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 674f75c56172..6ce41ee62b24 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -1079,6 +1079,12 @@ static inline void __switch_to_tm(struct task_struct *prev, if (!MSR_TM_ACTIVE(prev->thread.regs->msr) && prev->thread.load_tm == 0) prev->thread.regs->msr &= ~MSR_TM; } + + /* + * Now that we're reclaiming on kernel entry, we should never + * get here still with user checkpointed state on the CPU + */ + BUG_ON(MSR_TM_ACTIVE(mfmsr())); } /* @@ -1326,7 +1332,17 @@ struct task_struct *__switch_to(struct task_struct *prev, } if (current_thread_info()->task->thread.regs) { - restore_math(current_thread_info()->task->thread.regs); + /* + * Calling this now has reloaded the live state, which + * gets overwritten with the checkpointed state right + * before the trecheckpoint. BUT the MSR still has + * that the live state is on the CPU, which it isn't. + * + * restore_math(current_thread_info()->task->thread.regs); + * Therefore: + */ + if (!MSR_TM_ACTIVE(current_thread_info()->task->thread.regs->msr)) + restore_math(current_thread_info()->task->thread.regs); /* * The copy-paste buffer can only store into foreign real -- 2.16.2