aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2005-11-14 05:55:15 -0500
committerPaul Mackerras <paulus@samba.org>2005-11-14 19:11:32 -0500
commitcc657f53928997c65bf2409c45166c6ceee8d306 (patch)
tree247e16076381a947b4305bb6467acde1189f3918 /arch/powerpc/kernel
parent493f25ef4087395891c99fcfe2c72e62e293e89f (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')
-rw-r--r--arch/powerpc/kernel/signal_32.c7
-rw-r--r--arch/powerpc/kernel/signal_64.c6
2 files changed, 8 insertions, 5 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;
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index 58194e150711..1decf2785530 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -131,9 +131,6 @@ static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
131 131
132 flush_fp_to_thread(current); 132 flush_fp_to_thread(current);
133 133
134 /* Make sure signal doesn't get spurrious FP exceptions */
135 current->thread.fpscr.val = 0;
136
137#ifdef CONFIG_ALTIVEC 134#ifdef CONFIG_ALTIVEC
138 err |= __put_user(v_regs, &sc->v_regs); 135 err |= __put_user(v_regs, &sc->v_regs);
139 136
@@ -423,6 +420,9 @@ static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
423 if (err) 420 if (err)
424 goto badframe; 421 goto badframe;
425 422
423 /* Make sure signal handler doesn't get spurious FP exceptions */
424 current->thread.fpscr.val = 0;
425
426 /* Set up to return from userspace. */ 426 /* Set up to return from userspace. */
427 if (vdso64_rt_sigtramp && current->thread.vdso_base) { 427 if (vdso64_rt_sigtramp && current->thread.vdso_base) {
428 regs->link = current->thread.vdso_base + vdso64_rt_sigtramp; 428 regs->link = current->thread.vdso_base + vdso64_rt_sigtramp;