summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>1999-05-24 20:48:23 +0000
committerRoland McGrath <roland@gnu.org>1999-05-24 20:48:23 +0000
commit384cbd6c552b851db2759badc36530b11f9698d9 (patch)
treeacd2e93af70d24cd3aab45f8b4f8e1d36b5fac14
parentd999fe3e06322be3fd0eb014cb22c9666e48d317 (diff)
1999-05-24 Mark Kettenis <kettenis@gnu.org>
* i386/i386/fpu.c (fp_free): Clear task switch flag before calling fwait. (fpu_get_state): Only save FPU state info if the live FPU state belongs to our target, i.e. if THREAD is the current thread. (fp_load): Print warning if we try to load an invalid FPU state, and reset the FPU to some sane state instead.
-rw-r--r--i386/i386/fpu.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/i386/i386/fpu.c b/i386/i386/fpu.c
index dc49a6a..c5d15a6 100644
--- a/i386/i386/fpu.c
+++ b/i386/i386/fpu.c
@@ -179,6 +179,7 @@ ASSERT_IPL(SPL0);
* Make sure we don't get FPU interrupts later for
* this thread
*/
+ clear_ts();
fwait();
/* Mark it free and disable access */
@@ -215,6 +216,7 @@ ASSERT_IPL(SPL0);
* FPU state.
*/
if (fp_thread == thread) {
+ clear_ts();
fwait(); /* wait for possible interrupt */
clear_fpu(); /* no state in FPU */
}
@@ -345,9 +347,17 @@ ASSERT_IPL(SPL0);
}
/* Make sure we`ve got the latest fp state info */
- clear_ts();
- fp_save(thread);
- clear_fpu();
+ /* If the live fpu state belongs to our target */
+#if NCPUS == 1
+ if (thread == fp_thread)
+#else
+ if (thread == current_thread())
+#endif
+ {
+ clear_ts();
+ fp_save(thread);
+ clear_fpu();
+ }
state->fpkind = fp_kind;
state->exc_status = 0;
@@ -652,6 +662,9 @@ ASSERT_IPL(SPL0);
thread->pcb->ims.ifps->fp_save_state.fp_status);
/*NOTREACHED*/
#endif
+ } else if (! ifps->fp_valid) {
+ printf("fp_load: invalid FPU state!\n");
+ fninit ();
} else {
frstor(ifps->fp_save_state);
}