Skip to content

Commit

Permalink
powerpc: Fix clearing of the FPSCR when invoking a signal handler
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Paul Mackerras committed Nov 15, 2005
1 parent 493f25e commit cc657f5
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 5 deletions.
7 changes: 5 additions & 2 deletions arch/powerpc/kernel/signal_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -403,8 +403,6 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
ELF_NFPREG * sizeof(double)))
return 1;

current->thread.fpscr.val = 0; /* turn off all fp exceptions */

#ifdef CONFIG_ALTIVEC
/* save altivec registers */
if (current->thread.used_vr) {
Expand Down Expand Up @@ -818,6 +816,9 @@ static int handle_rt_signal(unsigned long sig, struct k_sigaction *ka,
goto badframe;
regs->link = (unsigned long) frame->tramp;
}

current->thread.fpscr.val = 0; /* turn off all fp exceptions */

if (put_user(regs->gpr[1], (u32 __user *)newsp))
goto badframe;
regs->gpr[1] = newsp;
Expand Down Expand Up @@ -1097,6 +1098,8 @@ static int handle_signal(unsigned long sig, struct k_sigaction *ka,
regs->link = (unsigned long) frame->mctx.tramp;
}

current->thread.fpscr.val = 0; /* turn off all fp exceptions */

if (put_user(regs->gpr[1], (u32 __user *)newsp))
goto badframe;
regs->gpr[1] = newsp;
Expand Down
6 changes: 3 additions & 3 deletions arch/powerpc/kernel/signal_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,6 @@ static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,

flush_fp_to_thread(current);

/* Make sure signal doesn't get spurrious FP exceptions */
current->thread.fpscr.val = 0;

#ifdef CONFIG_ALTIVEC
err |= __put_user(v_regs, &sc->v_regs);

Expand Down Expand Up @@ -423,6 +420,9 @@ static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
if (err)
goto badframe;

/* Make sure signal handler doesn't get spurious FP exceptions */
current->thread.fpscr.val = 0;

/* Set up to return from userspace. */
if (vdso64_rt_sigtramp && current->thread.vdso_base) {
regs->link = current->thread.vdso_base + vdso64_rt_sigtramp;
Expand Down

0 comments on commit cc657f5

Please sign in to comment.