aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/cpu/sh2a/fpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/kernel/cpu/sh2a/fpu.c')
-rw-r--r--arch/sh/kernel/cpu/sh2a/fpu.c27
1 files changed, 16 insertions, 11 deletions
diff --git a/arch/sh/kernel/cpu/sh2a/fpu.c b/arch/sh/kernel/cpu/sh2a/fpu.c
index 6df2fb98eb30..d395ce5740e7 100644
--- a/arch/sh/kernel/cpu/sh2a/fpu.c
+++ b/arch/sh/kernel/cpu/sh2a/fpu.c
@@ -25,14 +25,12 @@
25 25
26/* 26/*
27 * Save FPU registers onto task structure. 27 * Save FPU registers onto task structure.
28 * Assume called with FPU enabled (SR.FD=0).
29 */ 28 */
30void 29void
31save_fpu(struct task_struct *tsk, struct pt_regs *regs) 30save_fpu(struct task_struct *tsk)
32{ 31{
33 unsigned long dummy; 32 unsigned long dummy;
34 33
35 clear_tsk_thread_flag(tsk, TIF_USEDFPU);
36 enable_fpu(); 34 enable_fpu();
37 asm volatile("sts.l fpul, @-%0\n\t" 35 asm volatile("sts.l fpul, @-%0\n\t"
38 "sts.l fpscr, @-%0\n\t" 36 "sts.l fpscr, @-%0\n\t"
@@ -60,7 +58,6 @@ save_fpu(struct task_struct *tsk, struct pt_regs *regs)
60 : "memory"); 58 : "memory");
61 59
62 disable_fpu(); 60 disable_fpu();
63 release_fpu(regs);
64} 61}
65 62
66static void 63static void
@@ -598,31 +595,31 @@ BUILD_TRAP_HANDLER(fpu_error)
598 struct task_struct *tsk = current; 595 struct task_struct *tsk = current;
599 TRAP_HANDLER_DECL; 596 TRAP_HANDLER_DECL;
600 597
601 save_fpu(tsk, regs); 598 __unlazy_fpu(tsk, regs);
602 if (ieee_fpe_handler(regs)) { 599 if (ieee_fpe_handler(regs)) {
603 tsk->thread.fpu.hard.fpscr &= 600 tsk->thread.fpu.hard.fpscr &=
604 ~(FPSCR_CAUSE_MASK | FPSCR_FLAG_MASK); 601 ~(FPSCR_CAUSE_MASK | FPSCR_FLAG_MASK);
605 grab_fpu(regs); 602 grab_fpu(regs);
606 restore_fpu(tsk); 603 restore_fpu(tsk);
607 set_tsk_thread_flag(tsk, TIF_USEDFPU); 604 task_thread_info(tsk)->status |= TS_USEDFPU;
608 return; 605 return;
609 } 606 }
610 607
611 force_sig(SIGFPE, tsk); 608 force_sig(SIGFPE, tsk);
612} 609}
613 610
614BUILD_TRAP_HANDLER(fpu_state_restore) 611void fpu_state_restore(struct pt_regs *regs)
615{ 612{
616 struct task_struct *tsk = current; 613 struct task_struct *tsk = current;
617 TRAP_HANDLER_DECL;
618 614
619 grab_fpu(regs); 615 grab_fpu(regs);
620 if (!user_mode(regs)) { 616 if (unlikely(!user_mode(regs))) {
621 printk(KERN_ERR "BUG: FPU is used in kernel mode.\n"); 617 printk(KERN_ERR "BUG: FPU is used in kernel mode.\n");
618 BUG();
622 return; 619 return;
623 } 620 }
624 621
625 if (used_math()) { 622 if (likely(used_math())) {
626 /* Using the FPU again. */ 623 /* Using the FPU again. */
627 restore_fpu(tsk); 624 restore_fpu(tsk);
628 } else { 625 } else {
@@ -630,5 +627,13 @@ BUILD_TRAP_HANDLER(fpu_state_restore)
630 fpu_init(); 627 fpu_init();
631 set_used_math(); 628 set_used_math();
632 } 629 }
633 set_tsk_thread_flag(tsk, TIF_USEDFPU); 630 task_thread_info(tsk)->status |= TS_USEDFPU;
631 tsk->fpu_counter++;
632}
633
634BUILD_TRAP_HANDLER(fpu_state_restore)
635{
636 TRAP_HANDLER_DECL;
637
638 fpu_state_restore(regs);
634} 639}