Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[linux.git] / arch / powerpc / kernel / process.c
index af064d28b36524c5ce9c8fc982a58eec65ebbfc7..31d021506d210e6b7cf1fa4136b1067f8163dc05 100644 (file)
@@ -610,6 +610,31 @@ out_and_saveregs:
        tm_save_sprs(thr);
 }
 
+extern void __tm_recheckpoint(struct thread_struct *thread,
+                             unsigned long orig_msr);
+
+void tm_recheckpoint(struct thread_struct *thread,
+                    unsigned long orig_msr)
+{
+       unsigned long flags;
+
+       /* We really can't be interrupted here as the TEXASR registers can't
+        * change and later in the trecheckpoint code, we have a userspace R1.
+        * So let's hard disable over this region.
+        */
+       local_irq_save(flags);
+       hard_irq_disable();
+
+       /* The TM SPRs are restored here, so that TEXASR.FS can be set
+        * before the trecheckpoint and no explosion occurs.
+        */
+       tm_restore_sprs(thread);
+
+       __tm_recheckpoint(thread, orig_msr);
+
+       local_irq_restore(flags);
+}
+
 static inline void tm_recheckpoint_new_task(struct task_struct *new)
 {
        unsigned long msr;
@@ -628,13 +653,10 @@ static inline void tm_recheckpoint_new_task(struct task_struct *new)
        if (!new->thread.regs)
                return;
 
-       /* The TM SPRs are restored here, so that TEXASR.FS can be set
-        * before the trecheckpoint and no explosion occurs.
-        */
-       tm_restore_sprs(&new->thread);
-
-       if (!MSR_TM_ACTIVE(new->thread.regs->msr))
+       if (!MSR_TM_ACTIVE(new->thread.regs->msr)){
+               tm_restore_sprs(&new->thread);
                return;
+       }
        msr = new->thread.tm_orig_msr;
        /* Recheckpoint to restore original checkpointed register state. */
        TM_DEBUG("*** tm_recheckpoint of pid %d "