diff options
author | Paul Mackerras <paulus@samba.org> | 2005-11-14 05:55:15 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2005-11-14 19:11:32 -0500 |
commit | cc657f53928997c65bf2409c45166c6ceee8d306 (patch) | |
tree | 247e16076381a947b4305bb6467acde1189f3918 /arch/powerpc/kernel/signal_32.c | |
parent | 493f25ef4087395891c99fcfe2c72e62e293e89f (diff) |
powerpc: Fix clearing of the FPSCR when invoking a signal handler
As pointed out by Gary Byers, we were clearing the image of the FPSCR
(floating point status and control register) in the thread_struct before
copying it to the user stack when invoking a signal. Thus the task
would see its FPSCR getting cleared when it took a signal.
While fixing it I noticed that our swapcontext system call was also
clearing FPSCR. It shouldn't, so I fixed that too.
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/kernel/signal_32.c')
-rw-r--r-- | arch/powerpc/kernel/signal_32.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 8bdf95b7e420..5a2eba60dd39 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c | |||
@@ -403,8 +403,6 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, | |||
403 | ELF_NFPREG * sizeof(double))) | 403 | ELF_NFPREG * sizeof(double))) |
404 | return 1; | 404 | return 1; |
405 | 405 | ||
406 | current->thread.fpscr.val = 0; /* turn off all fp exceptions */ | ||
407 | |||
408 | #ifdef CONFIG_ALTIVEC | 406 | #ifdef CONFIG_ALTIVEC |
409 | /* save altivec registers */ | 407 | /* save altivec registers */ |
410 | if (current->thread.used_vr) { | 408 | if (current->thread.used_vr) { |
@@ -818,6 +816,9 @@ static int handle_rt_signal(unsigned long sig, struct k_sigaction *ka, | |||
818 | goto badframe; | 816 | goto badframe; |
819 | regs->link = (unsigned long) frame->tramp; | 817 | regs->link = (unsigned long) frame->tramp; |
820 | } | 818 | } |
819 | |||
820 | current->thread.fpscr.val = 0; /* turn off all fp exceptions */ | ||
821 | |||
821 | if (put_user(regs->gpr[1], (u32 __user *)newsp)) | 822 | if (put_user(regs->gpr[1], (u32 __user *)newsp)) |
822 | goto badframe; | 823 | goto badframe; |
823 | regs->gpr[1] = newsp; | 824 | regs->gpr[1] = newsp; |
@@ -1097,6 +1098,8 @@ static int handle_signal(unsigned long sig, struct k_sigaction *ka, | |||
1097 | regs->link = (unsigned long) frame->mctx.tramp; | 1098 | regs->link = (unsigned long) frame->mctx.tramp; |
1098 | } | 1099 | } |
1099 | 1100 | ||
1101 | current->thread.fpscr.val = 0; /* turn off all fp exceptions */ | ||
1102 | |||
1100 | if (put_user(regs->gpr[1], (u32 __user *)newsp)) | 1103 | if (put_user(regs->gpr[1], (u32 __user *)newsp)) |
1101 | goto badframe; | 1104 | goto badframe; |
1102 | regs->gpr[1] = newsp; | 1105 | regs->gpr[1] = newsp; |