In fpu_emul_arith(), check lower 7 bits in word1 rather than only 6 bits
to check 040/060 FP instructions, and don't call fpu_implode() and fpu_upd_fpsr() if no vaild emulated result is set otherwise these functions cause NULL pointer dereference. Fixes panics triggered by 040/060's FDADD instruction (which has the same lower 6 bits with fscale instruction) on 020/030 machines (even with 68881/68882) running kernels with options FPU_EMULATE. Problem reported by John Carr on port-sun3. Should be pulled up to netbsd-4-0, netbsd-4 and netbsd-5. XXX: m68k 4.0 packages binaries on ftp have this FDADD instruction.
This commit is contained in:
parent
e80f4e9ccb
commit
7107680c9d
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: fpu_emulate.c,v 1.27 2007/03/09 16:23:01 tsutsui Exp $ */
|
||||
/* $NetBSD: fpu_emulate.c,v 1.28 2009/01/20 14:57:21 tsutsui Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995 Gordon W. Ross
|
||||
@ -37,7 +37,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: fpu_emulate.c,v 1.27 2007/03/09 16:23:01 tsutsui Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: fpu_emulate.c,v 1.28 2009/01/20 14:57:21 tsutsui Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
@ -753,8 +753,8 @@ fpu_emul_arith(fe, insn)
|
||||
* pointer to the result.
|
||||
|
||||
*/
|
||||
res = 0;
|
||||
switch (word1 & 0x3f) {
|
||||
res = NULL;
|
||||
switch (word1 & 0x7f) {
|
||||
case 0x00: /* fmove */
|
||||
res = &fe->fe_f2;
|
||||
break;
|
||||
@ -910,7 +910,7 @@ fpu_emul_arith(fe, insn)
|
||||
discard_result = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
default: /* possibly 040/060 instructions */
|
||||
#ifdef DEBUG
|
||||
printf("fpu_emul_arith: bad opcode=0x%x, word1=0x%x\n",
|
||||
insn->is_opcode, insn->is_word1);
|
||||
@ -918,8 +918,15 @@ fpu_emul_arith(fe, insn)
|
||||
sig = SIGILL;
|
||||
} /* switch (word1 & 0x3f) */
|
||||
|
||||
/* for sanity */
|
||||
if (res == NULL)
|
||||
sig = SIGILL;
|
||||
|
||||
if (!discard_result && sig == 0) {
|
||||
fpu_implode(fe, res, FTYPE_EXT, &fpregs[regnum * 3]);
|
||||
|
||||
/* update fpsr according to the result of operation */
|
||||
fpu_upd_fpsr(fe, res);
|
||||
#if DEBUG_FPE
|
||||
printf("fpu_emul_arith: %08x,%08x,%08x stored in FP%d\n",
|
||||
fpregs[regnum*3], fpregs[regnum*3+1],
|
||||
@ -937,9 +944,6 @@ fpu_emul_arith(fe, insn)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* update fpsr according to the result of operation */
|
||||
fpu_upd_fpsr(fe, res);
|
||||
|
||||
#if DEBUG_FPE
|
||||
printf("fpu_emul_arith: FPSR = %08x, FPCR = %08x\n",
|
||||
fe->fe_fpsr, fe->fe_fpcr);
|
||||
|
Loading…
x
Reference in New Issue
Block a user