Date: Fri, 31 Aug 2012 11:33:54 +0000 (UTC) From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r239944 - in stable/9/sys/amd64: amd64 include Message-ID: <201208311133.q7VBXsaP023189@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kib Date: Fri Aug 31 11:33:54 2012 New Revision: 239944 URL: http://svn.freebsd.org/changeset/base/239944 Log: MFC r238598: 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. Modified: stable/9/sys/amd64/amd64/fpu.c stable/9/sys/amd64/amd64/trap.c stable/9/sys/amd64/include/fpu.h Directory Properties: stable/9/sys/ (props changed) Modified: stable/9/sys/amd64/amd64/fpu.c ============================================================================== --- stable/9/sys/amd64/amd64/fpu.c Fri Aug 31 11:29:39 2012 (r239943) +++ stable/9/sys/amd64/amd64/fpu.c Fri Aug 31 11:33:54 2012 (r239944) @@ -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: stable/9/sys/amd64/amd64/trap.c ============================================================================== --- stable/9/sys/amd64/amd64/trap.c Fri Aug 31 11:29:39 2012 (r239943) +++ stable/9/sys/amd64/amd64/trap.c Fri Aug 31 11:33:54 2012 (r239944) @@ -333,7 +333,7 @@ trap(struct trapframe *frame) break; case T_ARITHTRAP: /* arithmetic trap */ - ucode = fputrap(); + ucode = fputrap_x87(); if (ucode == -1) goto userout; i = SIGFPE; @@ -447,7 +447,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: stable/9/sys/amd64/include/fpu.h ============================================================================== --- stable/9/sys/amd64/include/fpu.h Fri Aug 31 11:29:39 2012 (r239943) +++ stable/9/sys/amd64/include/fpu.h Fri Aug 31 11:33:54 2012 (r239944) @@ -145,7 +145,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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201208311133.q7VBXsaP023189>