From 46166f9be5066db364880c18d541caabb82a5749 Mon Sep 17 00:00:00 2001 From: pk Date: Sun, 12 Oct 2003 19:48:52 +0000 Subject: [PATCH] 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. --- sys/arch/sparc/fpu/fpu.c | 49 +++++++-------------------------- sys/arch/sparc/fpu/fpu_extern.h | 6 ++-- sys/arch/sparc/sparc/trap.c | 31 +++++++++++++-------- sys/arch/sparc64/sparc64/trap.c | 22 +++++++++------ 4 files changed, 45 insertions(+), 63 deletions(-) diff --git a/sys/arch/sparc/fpu/fpu.c b/sys/arch/sparc/fpu/fpu.c index bad6c85ef646..501b5074a3e7 100644 --- a/sys/arch/sparc/fpu/fpu.c +++ b/sys/arch/sparc/fpu/fpu.c @@ -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 -__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 #include @@ -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 diff --git a/sys/arch/sparc/fpu/fpu_extern.h b/sys/arch/sparc/fpu/fpu_extern.h index d719302fcef0..301e99a4a0af 100644 --- a/sys/arch/sparc/fpu/fpu_extern.h +++ b/sys/arch/sparc/fpu/fpu_extern.h @@ -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)); diff --git a/sys/arch/sparc/sparc/trap.c b/sys/arch/sparc/sparc/trap.c index 0b4dda8fa5db..1996fb706d54 100644 --- a/sys/arch/sparc/sparc/trap.c +++ b/sys/arch/sparc/sparc/trap.c @@ -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 -__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 diff --git a/sys/arch/sparc64/sparc64/trap.c b/sys/arch/sparc64/sparc64/trap.c index 6a3658eaa79f..946f72fa506b 100644 --- a/sys/arch/sparc64/sparc64/trap.c +++ b/sys/arch/sparc64/sparc64/trap.c @@ -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 -__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: