aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/traps.c
diff options
context:
space:
mode:
authorChuck Ebbert <76306.1226@compuserve.com>2005-08-23 21:36:40 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-08-23 22:52:37 -0400
commitb1daec3089a129a67169d3ae975985a7480fe17f (patch)
tree874a99ec05afb39419f1e4ac0f90cf7c6a70e1fc /arch/i386/kernel/traps.c
parent11532cc6aa73a47023268d718bf43b646494615c (diff)
[PATCH] i386: fix incorrect FP signal code
i386 floating-point exception handling has a bug that can cause error code 0 to be sent instead of the proper code during signal delivery. This is caused by unconditionally checking the IS and c1 bits from the FPU status word when they are not always relevant. The IS bit tells whether an exception is a stack fault and is only relevant when the exception is IE (invalid operation.) The C1 bit determines whether a stack fault is overflow or underflow and is only relevant when IS and IE are set. Signed-off-by: Chuck Ebbert <76306.1226@compuserve.com> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/i386/kernel/traps.c')
-rw-r--r--arch/i386/kernel/traps.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index a61f33d06ea3..cd2d5d5514fe 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -803,15 +803,17 @@ void math_error(void __user *eip)
803 */ 803 */
804 cwd = get_fpu_cwd(task); 804 cwd = get_fpu_cwd(task);
805 swd = get_fpu_swd(task); 805 swd = get_fpu_swd(task);
806 switch (((~cwd) & swd & 0x3f) | (swd & 0x240)) { 806 switch (swd & ~cwd & 0x3f) {
807 case 0x000: 807 case 0x000:
808 default: 808 default:
809 break; 809 break;
810 case 0x001: /* Invalid Op */ 810 case 0x001: /* Invalid Op */
811 case 0x041: /* Stack Fault */ 811 /*
812 case 0x241: /* Stack Fault | Direction */ 812 * swd & 0x240 == 0x040: Stack Underflow
813 * swd & 0x240 == 0x240: Stack Overflow
814 * User must clear the SF bit (0x40) if set
815 */
813 info.si_code = FPE_FLTINV; 816 info.si_code = FPE_FLTINV;
814 /* Should we clear the SF or let user space do it ???? */
815 break; 817 break;
816 case 0x002: /* Denormalize */ 818 case 0x002: /* Denormalize */
817 case 0x010: /* Underflow */ 819 case 0x010: /* Underflow */