summaryrefslogtreecommitdiffstats
path: root/sys/ia64
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2004-05-07 05:35:31 +0000
committermarcel <marcel@FreeBSD.org>2004-05-07 05:35:31 +0000
commit27622b9560473116cb1ddcba873f0953310f5c0f (patch)
tree7467a840be9f9f6dfe7405ce9651ca6ea2b26996 /sys/ia64
parent254a0ce34ef95d879069eb07b8cb558f6650d477 (diff)
downloadFreeBSD-src-27622b9560473116cb1ddcba873f0953310f5c0f.zip
FreeBSD-src-27622b9560473116cb1ddcba873f0953310f5c0f.tar.gz
Revert previous commit. We should not get any FP traps from within
the kernel. We can guarantee this by resetting the FP status register. This masks all FP traps. The reason we did get FP traps was that we didn't reset the FP status register in all cases. Make sure to reset the FP status register in syscall(). This is one of the places where it was forgotten. While on the subject, reset the FP status register only when we trapped from user space.
Diffstat (limited to 'sys/ia64')
-rw-r--r--sys/ia64/ia64/trap.c33
1 files changed, 15 insertions, 18 deletions
diff --git a/sys/ia64/ia64/trap.c b/sys/ia64/ia64/trap.c
index 324be68..83946b1 100644
--- a/sys/ia64/ia64/trap.c
+++ b/sys/ia64/ia64/trap.c
@@ -358,9 +358,6 @@ trap(int vector, struct trapframe *tf)
user = TRAPF_USERMODE(tf) ? 1 : 0;
- /* Sanitize the FP state in case the user has trashed it. */
- ia64_set_fpsr(IA64_FPSR_DEFAULT);
-
atomic_add_int(&cnt.v_trap, 1);
td = curthread;
@@ -368,6 +365,7 @@ trap(int vector, struct trapframe *tf)
ucode = 0;
if (user) {
+ ia64_set_fpsr(IA64_FPSR_DEFAULT);
sticks = td->td_sticks;
td->td_frame = tf;
if (td->td_ucred != p->p_ucred)
@@ -668,10 +666,11 @@ trap(int vector, struct trapframe *tf)
FPSWA_BUNDLE bundle;
char *ip;
- if (fpswa_interface == NULL) {
- if (!user)
- trap_panic(vector, tf);
+ /* Always fatal in kernel. Should never happen. */
+ if (!user)
+ trap_panic(vector, tf);
+ if (fpswa_interface == NULL) {
sig = SIGFPE;
ucode = 0;
break;
@@ -681,15 +680,12 @@ trap(int vector, struct trapframe *tf)
if (vector == IA64_VEC_FLOATING_POINT_TRAP &&
(tf->tf_special.psr & IA64_PSR_RI) == 0)
ip -= 16;
- if (user) {
- error = copyin(ip, &bundle, 16);
- if (error) {
- sig = SIGBUS; /* EFAULT, basically */
- ucode = 0; /* exception summary */
- break;
- }
- } else
- bcopy(ip, &bundle, 16);
+ error = copyin(ip, &bundle, 16);
+ if (error) {
+ sig = SIGBUS; /* EFAULT, basically */
+ ucode = 0; /* exception summary */
+ break;
+ }
/* f6-f15 are saved in exception_save */
fp_state.bitmask_low64 = 0xffc0; /* bits 6 - 15 */
@@ -741,12 +737,11 @@ trap(int vector, struct trapframe *tf)
printf("FATAL: FPSWA err1 %lx, err2 %lx, err3 %lx\n",
fpswa_ret.err1, fpswa_ret.err2, fpswa_ret.err3);
panic("fpswa fatal error on fp fault");
- } else if (user) {
+ } else {
sig = SIGFPE;
ucode = 0; /* XXX exception summary */
break;
- } else
- goto out;
+ }
}
case IA64_VEC_IA32_EXCEPTION:
@@ -897,6 +892,8 @@ syscall(struct trapframe *tf)
int code, error;
u_int sticks;
+ ia64_set_fpsr(IA64_FPSR_DEFAULT);
+
code = tf->tf_scratch.gr15;
args = &tf->tf_scratch.gr16;
OpenPOWER on IntegriCloud