Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cc657f53 authored by Paul Mackerras's avatar Paul Mackerras
Browse files

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: default avatarPaul Mackerras <paulus@samba.org>
parent 493f25ef
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -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) {
@@ -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;
@@ -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;
+3 −3
Original line number Diff line number Diff line
@@ -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);

@@ -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;