diff options
author | Chuck Ebbert <76306.1226@compuserve.com> | 2005-09-12 12:49:25 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-09-12 13:50:58 -0400 |
commit | ff347b221512a83e7b08356729e3e2c14346e29e (patch) | |
tree | 3af9934eecd9ce119a840f53912e657951da9656 /arch/x86_64/kernel | |
parent | 847815760cc0f41985b3185d780aa4369fcb475d (diff) |
[PATCH] x86-64: Fix incorrect FP signals
This is the same patch that went into i386 just before 2.6.13
came out. I still can't build 64-bit user apps, so I tested
with program (see below) in 32-bit mode on 64-bit kernel:
Before:
$ fpsig
handler: nr = 8, si = 0x0804bc90, vuc = 0x0804bd10
handler: altstack is at 0x0804b000, ebp = 0x0804bc7c
handler: si_signo = 8, si_errno = 0, si_code = 0 [unknown]
handler: fpu cwd = 0xb40, fpu swd = 0xbaa0
handler: i387 unmasked precision exception, rounded up
After:
$ fpsig
handler: nr = 8, si = 0x0804bc90, vuc = 0x0804bd10
handler: altstack is at 0x0804b000, ebp = 0x0804bc7c
handler: si_signo = 8, si_errno = 0, si_code = 6 [inexact result]
handler: fpu cwd = 0xb40, fpu swd = 0xbaa0
handler: i387 unmasked precision exception, rounded up
Signed-off-by: Chuck Ebbert <76306.1226@compuserve.com>
Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/x86_64/kernel')
-rw-r--r-- | arch/x86_64/kernel/traps.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index 64a59cb49411..77658f7f4e84 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c | |||
@@ -795,13 +795,16 @@ asmlinkage void do_coprocessor_error(struct pt_regs *regs) | |||
795 | */ | 795 | */ |
796 | cwd = get_fpu_cwd(task); | 796 | cwd = get_fpu_cwd(task); |
797 | swd = get_fpu_swd(task); | 797 | swd = get_fpu_swd(task); |
798 | switch (((~cwd) & swd & 0x3f) | (swd & 0x240)) { | 798 | switch (swd & ~cwd & 0x3f) { |
799 | case 0x000: | 799 | case 0x000: |
800 | default: | 800 | default: |
801 | break; | 801 | break; |
802 | case 0x001: /* Invalid Op */ | 802 | case 0x001: /* Invalid Op */ |
803 | case 0x041: /* Stack Fault */ | 803 | /* |
804 | case 0x241: /* Stack Fault | Direction */ | 804 | * swd & 0x240 == 0x040: Stack Underflow |
805 | * swd & 0x240 == 0x240: Stack Overflow | ||
806 | * User must clear the SF bit (0x40) if set | ||
807 | */ | ||
805 | info.si_code = FPE_FLTINV; | 808 | info.si_code = FPE_FLTINV; |
806 | break; | 809 | break; |
807 | case 0x002: /* Denormalize */ | 810 | case 0x002: /* Denormalize */ |