Skip site navigation (1)Skip section navigation (2)
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>