summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkettenis <kettenis@openbsd.org>2006-05-15 21:56:54 +0000
committerkettenis <kettenis@openbsd.org>2006-05-15 21:56:54 +0000
commitf9660d04d6bb227605e1da379d25843e174ac3ba (patch)
tree025ff855fd845c8f3a1ea61e8ada10946d2b6930
parentSprinkle bus_space_barrier()s after LANCE register writes, as already done (diff)
downloadwireguard-openbsd-f9660d04d6bb227605e1da379d25843e174ac3ba.tar.xz
wireguard-openbsd-f9660d04d6bb227605e1da379d25843e174ac3ba.zip
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@
-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;