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.
This commit is contained in:
parent
fa93eca116
commit
804a183b9c
@ -358,9 +358,6 @@ trap(int vector, struct trapframe *tf)
|
|||||||
|
|
||||||
user = TRAPF_USERMODE(tf) ? 1 : 0;
|
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);
|
atomic_add_int(&cnt.v_trap, 1);
|
||||||
|
|
||||||
td = curthread;
|
td = curthread;
|
||||||
@ -368,6 +365,7 @@ trap(int vector, struct trapframe *tf)
|
|||||||
ucode = 0;
|
ucode = 0;
|
||||||
|
|
||||||
if (user) {
|
if (user) {
|
||||||
|
ia64_set_fpsr(IA64_FPSR_DEFAULT);
|
||||||
sticks = td->td_sticks;
|
sticks = td->td_sticks;
|
||||||
td->td_frame = tf;
|
td->td_frame = tf;
|
||||||
if (td->td_ucred != p->p_ucred)
|
if (td->td_ucred != p->p_ucred)
|
||||||
@ -668,10 +666,11 @@ trap(int vector, struct trapframe *tf)
|
|||||||
FPSWA_BUNDLE bundle;
|
FPSWA_BUNDLE bundle;
|
||||||
char *ip;
|
char *ip;
|
||||||
|
|
||||||
if (fpswa_interface == NULL) {
|
/* Always fatal in kernel. Should never happen. */
|
||||||
if (!user)
|
if (!user)
|
||||||
trap_panic(vector, tf);
|
trap_panic(vector, tf);
|
||||||
|
|
||||||
|
if (fpswa_interface == NULL) {
|
||||||
sig = SIGFPE;
|
sig = SIGFPE;
|
||||||
ucode = 0;
|
ucode = 0;
|
||||||
break;
|
break;
|
||||||
@ -681,15 +680,12 @@ trap(int vector, struct trapframe *tf)
|
|||||||
if (vector == IA64_VEC_FLOATING_POINT_TRAP &&
|
if (vector == IA64_VEC_FLOATING_POINT_TRAP &&
|
||||||
(tf->tf_special.psr & IA64_PSR_RI) == 0)
|
(tf->tf_special.psr & IA64_PSR_RI) == 0)
|
||||||
ip -= 16;
|
ip -= 16;
|
||||||
if (user) {
|
error = copyin(ip, &bundle, 16);
|
||||||
error = copyin(ip, &bundle, 16);
|
if (error) {
|
||||||
if (error) {
|
sig = SIGBUS; /* EFAULT, basically */
|
||||||
sig = SIGBUS; /* EFAULT, basically */
|
ucode = 0; /* exception summary */
|
||||||
ucode = 0; /* exception summary */
|
break;
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
} else
|
|
||||||
bcopy(ip, &bundle, 16);
|
|
||||||
|
|
||||||
/* f6-f15 are saved in exception_save */
|
/* f6-f15 are saved in exception_save */
|
||||||
fp_state.bitmask_low64 = 0xffc0; /* bits 6 - 15 */
|
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",
|
printf("FATAL: FPSWA err1 %lx, err2 %lx, err3 %lx\n",
|
||||||
fpswa_ret.err1, fpswa_ret.err2, fpswa_ret.err3);
|
fpswa_ret.err1, fpswa_ret.err2, fpswa_ret.err3);
|
||||||
panic("fpswa fatal error on fp fault");
|
panic("fpswa fatal error on fp fault");
|
||||||
} else if (user) {
|
} else {
|
||||||
sig = SIGFPE;
|
sig = SIGFPE;
|
||||||
ucode = 0; /* XXX exception summary */
|
ucode = 0; /* XXX exception summary */
|
||||||
break;
|
break;
|
||||||
} else
|
}
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case IA64_VEC_IA32_EXCEPTION:
|
case IA64_VEC_IA32_EXCEPTION:
|
||||||
@ -897,6 +892,8 @@ syscall(struct trapframe *tf)
|
|||||||
int code, error;
|
int code, error;
|
||||||
u_int sticks;
|
u_int sticks;
|
||||||
|
|
||||||
|
ia64_set_fpsr(IA64_FPSR_DEFAULT);
|
||||||
|
|
||||||
code = tf->tf_scratch.gr15;
|
code = tf->tf_scratch.gr15;
|
||||||
args = &tf->tf_scratch.gr16;
|
args = &tf->tf_scratch.gr16;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user