summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2006-05-15 21:56:55 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2006-05-15 21:56:55 +0000
commit4e41010bb42a7c0b1fde0a955cf4a983f908616b (patch)
tree94c7a59a3526fe7a9fda13cf0ca1fb6ed9b4e274 /sys
parenta5f4ccf8d04f4afebd15e361c302fee0c0cfc5d8 (diff)
Fix SIGFPE handling. The code doing an ADVANCE after calling trapsignal(),
which made is skip the first instruction of the signal trampoline in certain cases. That in turn truly hosed the stack. ok miod@, jason@
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/sparc64/sparc64/trap.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/sys/arch/sparc64/sparc64/trap.c b/sys/arch/sparc64/sparc64/trap.c
index e83de626ae7..15a00ab5ff1 100644
--- a/sys/arch/sparc64/sparc64/trap.c
+++ b/sys/arch/sparc64/sparc64/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.40 2006/02/05 19:53:34 kettenis Exp $ */
+/* $OpenBSD: trap.c,v 1.41 2006/05/15 21:56:54 kettenis Exp $ */
/* $NetBSD: trap.c,v 1.73 2001/08/09 01:03:01 eeh Exp $ */
/*
@@ -685,13 +685,17 @@ badtrap:
savefpstate(p->p_md.md_fpstate);
fpproc = NULL;
/* tf->tf_psr &= ~PSR_EF; */ /* share_fpu will do this */
- if (p->p_md.md_fpstate->fs_qsize == 0) {
+ if (type == T_FP_OTHER && p->p_md.md_fpstate->fs_qsize == 0) {
+ /*
+ * Push the faulting instruction on the queue;
+ * we might need to emulate it.
+ */
copyin((caddr_t)pc, &p->p_md.md_fpstate->fs_queue[0].fq_instr, sizeof(int));
+ p->p_md.md_fpstate->fs_queue[0].fq_addr = (int *)pc;
p->p_md.md_fpstate->fs_qsize = 1;
- fpu_cleanup(p, p->p_md.md_fpstate);
ADVANCE;
- } else
- fpu_cleanup(p, p->p_md.md_fpstate);
+ }
+ fpu_cleanup(p, p->p_md.md_fpstate);
/* fpu_cleanup posts signals if needed */
#if 0 /* ??? really never??? */
ADVANCE;