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:
pk 2003-10-12 19:48:52 +00:00
parent c298ea9fc9
commit 46166f9be5
4 changed files with 45 additions and 63 deletions

View File

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

View File

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

View File

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

View File

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