Hi, I'm porting a MIPS-based realtime control system that runs directly on top of the MIPS hardware (i.e. no dedicated operating systen inbetween) to x86 Linux. The systen is open to execute user code, and it catches floating point exceptions (e.g. underflow and overflow) by replacing out of range numbers with "sensible" values. To remain compatible whith the old system, I somehow need to do the same under Linux. I started out quite cheerfully whith some initial test code by registering a signal handler for floation point exceptions that just skips across any floating point instruction that causes an exception. (Note that the function instructionSize() calculates the length of the assembler instruction pointed to by ist argument): void fpeHandler(int, siginfo_t *info, void *context) { int size = instructionSize((unsigned char *) info->si_addr); ((ucontext_t *) context)->uc_mcontext.gregs[REG_EIP] += size; } This works great so far: When the signal handler returns, my program resumes right _after_ the instruction that caused the exception. But there is (much) more to do: To start with, the exception flags need to be cleared, otherwise any following floation point instructions would throw the exception again, even if they would not normally cause one. Initially, this seemed to be an easy task again, as the floating point registers are as well available in ucontext_t. So I looked at the source code of glibc to see the implementation of feclearexcept() to learn how to clear exception flags: Int feclearexcept (int excepts) { fenv_t temp; unsigned int mxcsr; /* Mask out unsupported bits/exceptions. */ excepts &= FE_ALL_EXCEPT; /* Bah, we have to clear selected exceptions. Since there is no `fldsw' instruction we have to do it the hard way. */ __asm__ ("fnstenv %0" : "=m" (*&temp)); /* Clear the relevant bits. */ temp.__status_word &= excepts ^ FE_ALL_EXCEPT; /* Put the new data in effect. */ __asm__ ("fldenv %0" : : "m" (*&temp)); /* And the same procedure for SSE. */ __asm__ ("stmxcsr %0" : "=m" (*&mxcsr)); /* Clear the relevant bits. */ mxcsr &= ~excepts; /* And put them into effect. */ __asm__ ("ldmxcsr %0" : : "m" (*&mxcsr)); /* Success. */ return 0; } So I need to clear the relevant bits in the processor's floating point status word and in the mxcsr register. Looks easy. But ... 1) While ucontext_t _does_ have the status register, e.g.: ((ucontext_t *) context)->uc_mcontext.fpregs->status &= FE_ALL_EXCEPT ^ FE_ALL_EXCEPT; , the register mxcsr is _not_ part of ucontext_t. 2) Even worse, the following link suggests that only the general purpose registers are restored from ucontext_t, while the floating point registers in ucontext_t are ignored: http://valgrind.10908.n7.nabble.com/need-FPU-and-SSE-state-in-sigcontext-ucontext-td19844.html As everything is so nicely available for general purpose registers, why are things not done in the same way for floating point registers? Is there any other way to achive my goal? If not, are there any realistic chances (for a kernel newbie) to fix this in the kernel? I already looked at arch/x86/kernel/signal.c, but it looks difficult to get on track. Thanks for any help, Chris _______________________________________________ Kernelnewbies mailing list Kernelnewbies@xxxxxxxxxxxxxxxxx http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies