svn commit: r238598 - in head/sys/amd64: amd64 include
Konstantin Belousov
kib at FreeBSD.org
Wed Jul 18 15:43:47 UTC 2012
Author: kib
Date: Wed Jul 18 15:43:47 2012
New Revision: 238598
URL: http://svn.freebsd.org/changeset/base/238598
Log:
On AMD64, provide siginfo.si_code for floating point errors when error
occurs using the SSE math processor. Update comments describing the
handling of the exception status bits in coprocessors control words.
Remove GET_FPU_CW and GET_FPU_SW macros which were used only once.
Prefer to use curpcb to access pcb_save over the longer path of
referencing pcb through the thread structure.
Based on the submission by: Ed Alley <wea llnl gov>
PR: amd64/169927
Reviewed by: bde
MFC after: 3 weeks
Modified:
head/sys/amd64/amd64/fpu.c
head/sys/amd64/amd64/trap.c
head/sys/amd64/include/fpu.h
Modified: head/sys/amd64/amd64/fpu.c
==============================================================================
--- head/sys/amd64/amd64/fpu.c Wed Jul 18 15:36:03 2012 (r238597)
+++ head/sys/amd64/amd64/fpu.c Wed Jul 18 15:43:47 2012 (r238598)
@@ -115,9 +115,6 @@ void xsave(char *addr, uint64_t mask);
#define start_emulating() load_cr0(rcr0() | CR0_TS)
#define stop_emulating() clts()
-#define GET_FPU_CW(thread) ((thread)->td_pcb->pcb_save->sv_env.en_cw)
-#define GET_FPU_SW(thread) ((thread)->td_pcb->pcb_save->sv_env.en_sw)
-
CTASSERT(sizeof(struct savefpu) == 512);
CTASSERT(sizeof(struct xstate_hdr) == 64);
CTASSERT(sizeof(struct savefpu_ymm) == 832);
@@ -516,11 +513,15 @@ static char fpetable[128] = {
};
/*
- * Preserve the FP status word, clear FP exceptions, then generate a SIGFPE.
+ * Preserve the FP status word, clear FP exceptions for x87, then
+ * generate a SIGFPE.
+ *
+ * Clearing exceptions was necessary mainly to avoid IRQ13 bugs and is
+ * engraved in our i386 ABI. We now depend on longjmp() restoring a
+ * usable state. Restoring the state or examining it might fail if we
+ * didn't clear exceptions.
*
- * Clearing exceptions is necessary mainly to avoid IRQ13 bugs. We now
- * depend on longjmp() restoring a usable state. Restoring the state
- * or examining it might fail if we didn't clear exceptions.
+ * For SSE exceptions, the exceptions are not cleared.
*
* The error code chosen will be one of the FPE_... macros. It will be
* sent as the second argument to old BSD-style signal handlers and as
@@ -533,8 +534,9 @@ static char fpetable[128] = {
* solution for signals other than SIGFPE.
*/
int
-fputrap()
+fputrap_x87(void)
{
+ struct savefpu *pcb_save;
u_short control, status;
critical_enter();
@@ -545,19 +547,33 @@ fputrap()
* wherever they are.
*/
if (PCPU_GET(fpcurthread) != curthread) {
- control = GET_FPU_CW(curthread);
- status = GET_FPU_SW(curthread);
+ pcb_save = PCPU_GET(curpcb)->pcb_save;
+ control = pcb_save->sv_env.en_cw;
+ status = pcb_save->sv_env.en_sw;
} else {
fnstcw(&control);
fnstsw(&status);
+ fnclex();
}
- if (PCPU_GET(fpcurthread) == curthread)
- fnclex();
critical_exit();
return (fpetable[status & ((~control & 0x3f) | 0x40)]);
}
+int
+fputrap_sse(void)
+{
+ u_int mxcsr;
+
+ critical_enter();
+ if (PCPU_GET(fpcurthread) != curthread)
+ mxcsr = PCPU_GET(curpcb)->pcb_save->sv_env.en_mxcsr;
+ else
+ stmxcsr(&mxcsr);
+ critical_exit();
+ return (fpetable[(mxcsr & (~mxcsr >> 7)) & 0x3f]);
+}
+
/*
* Implement device not available (DNA) exception
*
Modified: head/sys/amd64/amd64/trap.c
==============================================================================
--- head/sys/amd64/amd64/trap.c Wed Jul 18 15:36:03 2012 (r238597)
+++ head/sys/amd64/amd64/trap.c Wed Jul 18 15:43:47 2012 (r238598)
@@ -328,7 +328,7 @@ trap(struct trapframe *frame)
break;
case T_ARITHTRAP: /* arithmetic trap */
- ucode = fputrap();
+ ucode = fputrap_x87();
if (ucode == -1)
goto userout;
i = SIGFPE;
@@ -442,7 +442,9 @@ trap(struct trapframe *frame)
break;
case T_XMMFLT: /* SIMD floating-point exception */
- ucode = 0; /* XXX */
+ ucode = fputrap_sse();
+ if (ucode == -1)
+ goto userout;
i = SIGFPE;
break;
}
Modified: head/sys/amd64/include/fpu.h
==============================================================================
--- head/sys/amd64/include/fpu.h Wed Jul 18 15:36:03 2012 (r238597)
+++ head/sys/amd64/include/fpu.h Wed Jul 18 15:43:47 2012 (r238598)
@@ -62,7 +62,8 @@ int fpusetregs(struct thread *td, struct
char *xfpustate, size_t xfpustate_size);
int fpusetxstate(struct thread *td, char *xfpustate,
size_t xfpustate_size);
-int fputrap(void);
+int fputrap_sse(void);
+int fputrap_x87(void);
void fpuuserinited(struct thread *td);
struct fpu_kern_ctx *fpu_kern_alloc_ctx(u_int flags);
void fpu_kern_free_ctx(struct fpu_kern_ctx *ctx);
More information about the svn-src-head
mailing list