Date: Sun, 21 Sep 1997 12:00:01 -0700 (PDT) From: Bruce Evans <bde@zeta.org.au> To: freebsd-bugs Subject: Re: kern/4597: Patch to pass NPX status word in signal code. Message-ID: <199709211900.MAA12642@hub.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/4597; it has been noted by GNATS. From: Bruce Evans <bde@zeta.org.au> To: dtc@scrooge.ee.swin.oz.au, FreeBSD-gnats-submit@FreeBSD.ORG Cc: Subject: Re: kern/4597: Patch to pass NPX status word in signal code. Date: Mon, 22 Sep 1997 04:48:36 +1000 >determining which exception occurred. The suggested change would have >the NPX status word passed in the signal code allowing the process to >determine the cause of the exception. One minor problem: the raw npx status word has nothing to do with the codes in <machine/trap.h> (and these codes are incomplete, not to mention inadequate since they can't be ORed together). I think the code should be fairly raw and <machine/trap.h> should be changed to match it. >Algorithms may also be mixing the monitoring the accrued exceptions >with some traps enabled. The clearing of all the exceptions on a >SIGFPE clears the accrued exceptions and may break such code unless >the accrued exceptions are restored by the application on a longjump; >but if the application doesn't have access to these it can't restore >them. My version of npx.c has an option to avoided clearing the exception bits. The idea is to pass the exact state that caused the exception to the SIGFPE handler and let it worry about possible nested SIGFPEs. Naive handlers will work as follows: 1. If SIGFPE is SIG_IGN'ed, or the handler just returns, the behaviour is undefined, as before, and more obviously broken than before, since nothing clears the exception bits, so SIGFPEs will occur endlessly on the FPU instruction after the one that set the exception bit. Clearing the exception bits allows broken programs to make progress, often with a corrupt FPU stack. 2. If the handler calls longjmp(), then longjmp() will clear the exception bits. longjmp() only attempts to preserve the part of the FPU state necessary for standard C programs. Since I also mask all FPU exceptions by default and don't use any sophisticated SIGFPE handlers (that I know about), and don't actually use the option :-), I don't know how well this works in practice. diff -c2 npx.c~ npx.c *** npx.c~ Fri Aug 22 05:11:14 1997 --- npx.c Thu Sep 4 21:29:26 1997 *************** *** 1,2 **** --- 1,3 ---- + static int old_npxintr = 0; /*- * Copyright (c) 1990 William Jolitz. *************** *** 508,514 **** outb(0xf0, 0); ! fnstsw(&curpcb->pcb_savefpu.sv_ex_sw); ! fnclex(); ! fnop(); /* --- 523,538 ---- outb(0xf0, 0); ! /* ! * Save state to work around the IRQ13 interface bugs. If the ! * exception 16 interface is used then the exception-pending bits ! * will be saved and will cause another exception on the next FPU ! * instruction in user mode (the same one unless the exception is ! * cleared by the application). If the IRQ13 interface is used ! * then the exception-pending bits will be saved and will usually ! * a bogus IRQ13 in the kernel when the state is restored. ! */ ! npxsave(&curpcb->pcb_savefpu); ! if (old_npxintr) ! curpcb->pcb_savefpu.sv_env.en_sw &= ~0x80bf; /* >Some operating systems will save the FP state in the signal >context. This has been discussed on the freebsd-current list some time >ago and the general consensus seemed to be that the overhead of doing >so is prohibitive. This may be the case, and if an application needs >to save the NPX state it can do so in its SIGFPE handler, however the >exceptions in the status word are currently cleared and lost. Saving the state for SIGFPE would be acceptable, but saving it for all signal handlers would be wasteful except possibly if the save is done lazily (note that lazy saving is not implemented even for ordinary context switches and doing it is even further away for the SMP case). However, I think presenting the exception state as is to the SIGFPE handler is best. If it knows enough to do fixups, then it can know enough to clear the state for itself. Bruce
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199709211900.MAA12642>