tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Possible bug in i386 NetBSD 1.6 emulated signal delivery, sanity check on reasoning and possible fix.
We have a project that is 5.1 i386, and a couple of our guys (Naren and
Ashok) tracked down a problem with 1.6 emulation enabled, a signal would
corrupt the fpu context. That turned out to be the use of buildcontext in
sendsig_sigcontext. It blindly calls buildcontext, which resets the
MDL_USEDFPU flag. However, in the siginfo (sendsig_siginfo) case, it calls
cpu_getmcontext, which builds a full register context for the processor
(including FPU if needed -- and sets a flag noting that the fpu context was
saved, and needs to be restored). The sigcontext case has no such save, and as
such the effect is that the fpu context is a fresh one when that process next
attempts to use floating point. In our case, the signal happened to slice a
set of floating point operations in snprintf -- that is dtoa. The result being
that the code is sliced, and on return from the signal, attempted to complete
the set of fpu operations, which now operated on a reset fpu register context
--obviously giving erroneous results.
I assume the sigcontext (1.6) signal delivery context assumes that the
signal handler uses the same fpu context as the main portion of the program.
In that case, I believe saving the state of the MDL_USEDFPU prior to calling
buildcontext, and restoring it after the buildcontext call (only in the
sigcontext case -- thus in compat_16_machdep.c:
---
//depot/main/Dev/Cyclone/ManagedPVT/NAVASOTA-DEV-9-1-0/SW-NetBSD5/usr/src/sys/arch/i386/i386/compat_16_machdep.c
2011-09-07 05:46:27.000000000 -0700
+++
/work/swos-01/glee/glee-nav4/SW-NetBSD5/usr/src/sys/arch/i386/i386/compat_16_machdep.c
2011-09-07 05:46:27.000000000 -0700
@@ -175,6 +175,7 @@
u_long code = KSI_TRAPCODE(ksi);
struct sigframe_sigcontext *fp = getframe(l, sig, &onstack), frame;
sig_t catcher = SIGACTION(p, sig).sa_handler;
+ int svufpu;
fp--;
@@ -259,8 +260,9 @@
sigexit(l, SIGILL);
/* NOTREACHED */
}
-
+ svufpu = l->l_md.md_flags & MDL_USEDFPU;
buildcontext(l, sel, catcher, fp);
+ l->l_md.md_flags |= svufpu;
/* Remember that we're now on the signal stack. */
if (onstack)
Home |
Main Index |
Thread Index |
Old Index