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