diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/kernel/process.c | 34 | ||||
-rw-r--r-- | arch/powerpc/kernel/signal_32.c | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/signal_64.c | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/tm.S | 2 |
4 files changed, 33 insertions, 7 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 " |
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index a67e00aa3caa..4e47db686b5d 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c | |||
@@ -881,6 +881,8 @@ static long restore_tm_user_regs(struct pt_regs *regs, | |||
881 | * transactional versions should be loaded. | 881 | * transactional versions should be loaded. |
882 | */ | 882 | */ |
883 | tm_enable(); | 883 | tm_enable(); |
884 | /* Make sure the transaction is marked as failed */ | ||
885 | current->thread.tm_texasr |= TEXASR_FS; | ||
884 | /* This loads the checkpointed FP/VEC state, if used */ | 886 | /* This loads the checkpointed FP/VEC state, if used */ |
885 | tm_recheckpoint(¤t->thread, msr); | 887 | tm_recheckpoint(¤t->thread, msr); |
886 | /* Get the top half of the MSR */ | 888 | /* Get the top half of the MSR */ |
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index 8d253c29649b..d501dc4dc3e6 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c | |||
@@ -527,6 +527,8 @@ static long restore_tm_sigcontexts(struct pt_regs *regs, | |||
527 | } | 527 | } |
528 | #endif | 528 | #endif |
529 | tm_enable(); | 529 | tm_enable(); |
530 | /* Make sure the transaction is marked as failed */ | ||
531 | current->thread.tm_texasr |= TEXASR_FS; | ||
530 | /* This loads the checkpointed FP/VEC state, if used */ | 532 | /* This loads the checkpointed FP/VEC state, if used */ |
531 | tm_recheckpoint(¤t->thread, msr); | 533 | tm_recheckpoint(¤t->thread, msr); |
532 | 534 | ||
diff --git a/arch/powerpc/kernel/tm.S b/arch/powerpc/kernel/tm.S index ef47bcbd4352..03567c05950a 100644 --- a/arch/powerpc/kernel/tm.S +++ b/arch/powerpc/kernel/tm.S | |||
@@ -307,7 +307,7 @@ dont_backup_fp: | |||
307 | * Call with IRQs off, stacks get all out of sync for | 307 | * Call with IRQs off, stacks get all out of sync for |
308 | * some periods in here! | 308 | * some periods in here! |
309 | */ | 309 | */ |
310 | _GLOBAL(tm_recheckpoint) | 310 | _GLOBAL(__tm_recheckpoint) |
311 | mfcr r5 | 311 | mfcr r5 |
312 | mflr r0 | 312 | mflr r0 |
313 | stw r5, 8(r1) | 313 | stw r5, 8(r1) |