diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2006-05-15 21:56:55 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2006-05-15 21:56:55 +0000 |
commit | 4e41010bb42a7c0b1fde0a955cf4a983f908616b (patch) | |
tree | 94c7a59a3526fe7a9fda13cf0ca1fb6ed9b4e274 /sys | |
parent | a5f4ccf8d04f4afebd15e361c302fee0c0cfc5d8 (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.c | 14 |
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; |