Simplify fpu_cleanup() by having it return a code to indicate that a SIGFPE
is to be posted; let trap() deal with constructing the siginfo structure.
This commit is contained in:
parent
c298ea9fc9
commit
46166f9be5
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: fpu.c,v 1.22 2003/10/06 07:10:41 pk Exp $ */
|
||||
/* $NetBSD: fpu.c,v 1.23 2003/10/12 19:48:52 pk Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
|
@ -41,7 +41,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.22 2003/10/06 07:10:41 pk Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.23 2003/10/12 19:48:52 pk Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/proc.h>
|
||||
|
@ -126,7 +126,7 @@ extern struct emul emul_sunos;
|
|||
* nor FBfcc instructions. Experiments with `crashme' prove that
|
||||
* unknown FPops do enter the queue, however.
|
||||
*/
|
||||
void
|
||||
int
|
||||
fpu_cleanup(l, fs)
|
||||
struct lwp *l;
|
||||
#ifndef SUN4U
|
||||
|
@ -140,7 +140,7 @@ fpu_cleanup(l, fs)
|
|||
union instr instr;
|
||||
struct fpemu fe;
|
||||
u_char *fpu_codes;
|
||||
ksiginfo_t ksi;
|
||||
int code = 0;
|
||||
|
||||
fpu_codes =
|
||||
#ifdef COMPAT_SUNOS
|
||||
|
@ -159,15 +159,7 @@ fpu_cleanup(l, fs)
|
|||
/* XXX missing trap address! */
|
||||
if ((i = fsr & FSR_CX) == 0)
|
||||
panic("fpu ieee trap, but no exception");
|
||||
ksi.ksi_signo = SIGFPE;
|
||||
ksi.ksi_code = fpu_codes[i - 1];
|
||||
KERNEL_PROC_LOCK(l);
|
||||
#ifdef __HAVE_SIGINFO
|
||||
trapsignal(l, &ksi);
|
||||
#else
|
||||
trapsignal(l, ksi.ksi_signo, ksi.ksi_code);
|
||||
#endif
|
||||
KERNEL_PROC_UNLOCK(l);
|
||||
code = fpu_codes[i - 1];
|
||||
break; /* XXX should return, but queue remains */
|
||||
|
||||
case FSR_TT_UNFIN:
|
||||
|
@ -176,7 +168,7 @@ fpu_cleanup(l, fs)
|
|||
if (fs->fs_qsize == 0) {
|
||||
printf("fpu_cleanup: unfinished fpop");
|
||||
/* The book sez reexecute or emulate. */
|
||||
return;
|
||||
return (0);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -196,15 +188,7 @@ fpu_cleanup(l, fs)
|
|||
log(LOG_ERR, "fpu hardware error (%s[%d])\n",
|
||||
p->p_comm, p->p_pid);
|
||||
uprintf("%s[%d]: fpu hardware error\n", p->p_comm, p->p_pid);
|
||||
ksi.ksi_signo = SIGFPE;
|
||||
ksi.ksi_code = 0;
|
||||
KERNEL_PROC_LOCK(l);
|
||||
#ifdef __HAVE_SIGINFO
|
||||
trapsignal(l, &ksi);
|
||||
#else
|
||||
trapsignal(l, ksi.ksi_signo, ksi.ksi_code);
|
||||
#endif
|
||||
KERNEL_PROC_UNLOCK(l);
|
||||
code = SI_NOINFO;
|
||||
goto out;
|
||||
|
||||
default:
|
||||
|
@ -224,16 +208,9 @@ fpu_cleanup(l, fs)
|
|||
if (error == 0)
|
||||
continue;
|
||||
|
||||
KERNEL_PROC_LOCK(l);
|
||||
switch (error) {
|
||||
case FPE:
|
||||
ksi.ksi_signo = SIGFPE;
|
||||
ksi.ksi_code = fpu_codes[(fs->fs_fsr & FSR_CX) - 1];
|
||||
#ifdef __HAVE_SIGINFO
|
||||
trapsignal(l, &ksi);
|
||||
#else
|
||||
trapsignal(l, ksi.ksi_signo, ksi.ksi_code);
|
||||
#endif
|
||||
code = fpu_codes[(fs->fs_fsr & FSR_CX) - 1];
|
||||
break;
|
||||
|
||||
case NOTFPU:
|
||||
|
@ -242,24 +219,18 @@ fpu_cleanup(l, fs)
|
|||
printf("fpu_cleanup: not an FPU error -- sending SIGILL\n");
|
||||
#endif
|
||||
#endif /* SUN4U */
|
||||
ksi.ksi_signo = SIGFPE;
|
||||
ksi.ksi_code = ILL_ILLOPC;
|
||||
#ifdef __HAVE_SIGINFO
|
||||
trapsignal(l, &ksi);
|
||||
#else
|
||||
trapsignal(l, ksi.ksi_signo, ksi.ksi_code);
|
||||
#endif
|
||||
code = SI_NOINFO;
|
||||
break;
|
||||
|
||||
default:
|
||||
panic("fpu_cleanup 3");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
KERNEL_PROC_UNLOCK(l);
|
||||
/* XXX should stop here, but queue remains */
|
||||
}
|
||||
out:
|
||||
fs->fs_qsize = 0;
|
||||
return (code);
|
||||
}
|
||||
|
||||
#ifdef notyet
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: fpu_extern.h,v 1.6 2003/01/18 06:45:00 thorpej Exp $ */
|
||||
/* $NetBSD: fpu_extern.h,v 1.7 2003/10/12 19:48:52 pk Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1995 The NetBSD Foundation, Inc.
|
||||
|
@ -54,10 +54,10 @@ struct fpn;
|
|||
|
||||
/* fpu.c */
|
||||
#ifndef SUN4U
|
||||
void fpu_cleanup __P((struct lwp *, struct fpstate *));
|
||||
int fpu_cleanup __P((struct lwp *, struct fpstate *));
|
||||
int fpu_emulate __P((struct lwp *, struct trapframe *, struct fpstate *));
|
||||
#else /* SUN4U */
|
||||
void fpu_cleanup __P((struct lwp *, struct fpstate64 *));
|
||||
int fpu_cleanup __P((struct lwp *, struct fpstate64 *));
|
||||
int fpu_emulate __P((struct lwp *, struct trapframe64 *, struct fpstate64 *));
|
||||
#endif /* SUN4U */
|
||||
int fpu_execute __P((struct fpemu *, union instr));
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: trap.c,v 1.145 2003/10/12 14:34:31 pk Exp $ */
|
||||
/* $NetBSD: trap.c,v 1.146 2003/10/12 19:48:52 pk Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996
|
||||
|
@ -49,7 +49,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.145 2003/10/12 14:34:31 pk Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.146 2003/10/12 19:48:52 pk Exp $");
|
||||
|
||||
#include "opt_ddb.h"
|
||||
#include "opt_ktrace.h"
|
||||
|
@ -336,8 +336,7 @@ trap(type, psr, pc, tf)
|
|||
char bits[64];
|
||||
u_quad_t sticks;
|
||||
ksiginfo_t ksi;
|
||||
int sig;
|
||||
u_long ucode;
|
||||
int code, sig;
|
||||
|
||||
/* This steps the PC over the trap. */
|
||||
#define ADVANCE (n = tf->tf_npc, tf->tf_pc = n, tf->tf_npc = n + 4)
|
||||
|
@ -435,7 +434,6 @@ trap(type, psr, pc, tf)
|
|||
#endif
|
||||
|
||||
sig = 0;
|
||||
ucode = 0;
|
||||
|
||||
switch (type) {
|
||||
|
||||
|
@ -447,7 +445,6 @@ trap(type, psr, pc, tf)
|
|||
type, pc, tf->tf_npc, bitmask_snprintf(psr,
|
||||
PSR_BITS, bits, sizeof(bits)));
|
||||
sig = SIGILL;
|
||||
ucode = type;
|
||||
KSI_INIT_TRAP(&ksi);
|
||||
ksi.ksi_trap = type;
|
||||
ksi.ksi_code = ILL_ILLTRP;
|
||||
|
@ -533,10 +530,9 @@ badtrap:
|
|||
fpu_emulate(l, tf, fs);
|
||||
#else
|
||||
sig = SIGFPE;
|
||||
/* XXX - ucode? */
|
||||
KSI_INIT_TRAP(&ksi);
|
||||
ksi.ksi_trap = type;
|
||||
ksi.ksi_code = 0;
|
||||
ksi.ksi_code = 0; /* XXX - ucode? */
|
||||
ksi.ksi_addr = (void *)pc;
|
||||
#endif
|
||||
break;
|
||||
|
@ -547,7 +543,13 @@ badtrap:
|
|||
* resolve the FPU state, turn it on, and try again.
|
||||
*/
|
||||
if (fs->fs_qsize) {
|
||||
fpu_cleanup(l, fs);
|
||||
if ((code = fpu_cleanup(l, fs)) != 0) {
|
||||
sig = SIGFPE;
|
||||
KSI_INIT_TRAP(&ksi);
|
||||
ksi.ksi_trap = type;
|
||||
ksi.ksi_code = code;
|
||||
ksi.ksi_addr = (void *)pc;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -695,10 +697,15 @@ badtrap:
|
|||
cpuinfo.fplwp = NULL;
|
||||
l->l_md.md_fpu = NULL;
|
||||
FPU_UNLOCK(s);
|
||||
/* tf->tf_psr &= ~PSR_EF; */ /* share_fpu will do this */
|
||||
fpu_cleanup(l, l->l_md.md_fpstate);
|
||||
KERNEL_PROC_UNLOCK(l);
|
||||
/* fpu_cleanup posts signals if needed */
|
||||
/* tf->tf_psr &= ~PSR_EF; */ /* share_fpu will do this */
|
||||
if ((code = fpu_cleanup(l, l->l_md.md_fpstate)) != 0) {
|
||||
sig = SIGFPE;
|
||||
KSI_INIT_TRAP(&ksi);
|
||||
ksi.ksi_trap = type;
|
||||
ksi.ksi_code = code;
|
||||
ksi.ksi_addr = (void *)pc;
|
||||
}
|
||||
#if 0 /* ??? really never??? */
|
||||
ADVANCE;
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: trap.c,v 1.94 2003/10/12 19:08:17 pk Exp $ */
|
||||
/* $NetBSD: trap.c,v 1.95 2003/10/12 19:48:52 pk Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996-2002 Eduardo Horvath. All rights reserved.
|
||||
|
@ -50,7 +50,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.94 2003/10/12 19:08:17 pk Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.95 2003/10/12 19:48:52 pk Exp $");
|
||||
|
||||
#define NEW_FPSTATE
|
||||
|
||||
|
@ -520,7 +520,7 @@ trap(tf, type, pc, tstate)
|
|||
int pstate = tstate >> TSTATE_PSTATE_SHIFT;
|
||||
ksiginfo_t ksi;
|
||||
int error;
|
||||
int sig;
|
||||
int code, sig;
|
||||
|
||||
/* This steps the PC over the trap. */
|
||||
#define ADVANCE (n = tf->tf_npc, tf->tf_pc = n, tf->tf_npc = n + 4)
|
||||
|
@ -857,14 +857,18 @@ badtrap:
|
|||
break;
|
||||
}
|
||||
l->l_md.md_fpstate->fs_qsize = 1;
|
||||
fpu_cleanup(l, l->l_md.md_fpstate);
|
||||
code = fpu_cleanup(l, l->l_md.md_fpstate);
|
||||
ADVANCE;
|
||||
} else
|
||||
fpu_cleanup(l, l->l_md.md_fpstate);
|
||||
/* fpu_cleanup posts signals if needed */
|
||||
#if 0 /* ??? really never??? */
|
||||
ADVANCE;
|
||||
#endif
|
||||
code = fpu_cleanup(l, l->l_md.md_fpstate);
|
||||
|
||||
if (code != 0) {
|
||||
sig = SIGFPE;
|
||||
KSI_INIT_TRAP(&ksi);
|
||||
ksi.ksi_trap = type;
|
||||
ksi.ksi_code = code;
|
||||
ksi.ksi_addr = (void *)pc;
|
||||
}
|
||||
break;
|
||||
|
||||
case T_TAGOF:
|
||||
|
|
Loading…
Reference in New Issue