diff options
Diffstat (limited to 'arch/powerpc/kernel/process.c')
-rw-r--r-- | arch/powerpc/kernel/process.c | 34 |
1 files changed, 28 insertions, 6 deletions
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index af064d28b365..31d021506d21 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c | |||
@@ -610,6 +610,31 @@ out_and_saveregs: | |||
610 | tm_save_sprs(thr); | 610 | tm_save_sprs(thr); |
611 | } | 611 | } |
612 | 612 | ||
613 | extern void __tm_recheckpoint(struct thread_struct *thread, | ||
614 | unsigned long orig_msr); | ||
615 | |||
616 | void tm_recheckpoint(struct thread_struct *thread, | ||
617 | unsigned long orig_msr) | ||
618 | { | ||
619 | unsigned long flags; | ||
620 | |||
621 | /* We really can't be interrupted here as the TEXASR registers can't | ||
622 | * change and later in the trecheckpoint code, we have a userspace R1. | ||
623 | * So let's hard disable over this region. | ||
624 | */ | ||
625 | local_irq_save(flags); | ||
626 | hard_irq_disable(); | ||
627 | |||
628 | /* The TM SPRs are restored here, so that TEXASR.FS can be set | ||
629 | * before the trecheckpoint and no explosion occurs. | ||
630 | */ | ||
631 | tm_restore_sprs(thread); | ||
632 | |||
633 | __tm_recheckpoint(thread, orig_msr); | ||
634 | |||
635 | local_irq_restore(flags); | ||
636 | } | ||
637 | |||
613 | static inline void tm_recheckpoint_new_task(struct task_struct *new) | 638 | static inline void tm_recheckpoint_new_task(struct task_struct *new) |
614 | { | 639 | { |
615 | unsigned long msr; | 640 | unsigned long msr; |
@@ -628,13 +653,10 @@ static inline void tm_recheckpoint_new_task(struct task_struct *new) | |||
628 | if (!new->thread.regs) | 653 | if (!new->thread.regs) |
629 | return; | 654 | return; |
630 | 655 | ||
631 | /* The TM SPRs are restored here, so that TEXASR.FS can be set | 656 | if (!MSR_TM_ACTIVE(new->thread.regs->msr)){ |
632 | * before the trecheckpoint and no explosion occurs. | 657 | tm_restore_sprs(&new->thread); |
633 | */ | ||
634 | tm_restore_sprs(&new->thread); | ||
635 | |||
636 | if (!MSR_TM_ACTIVE(new->thread.regs->msr)) | ||
637 | return; | 658 | return; |
659 | } | ||
638 | msr = new->thread.tm_orig_msr; | 660 | msr = new->thread.tm_orig_msr; |
639 | /* Recheckpoint to restore original checkpointed register state. */ | 661 | /* Recheckpoint to restore original checkpointed register state. */ |
640 | TM_DEBUG("*** tm_recheckpoint of pid %d " | 662 | TM_DEBUG("*** tm_recheckpoint of pid %d " |