Cope with the rare case of an imprecise FPU exception caught when
authormiod <miod@openbsd.org>
Sun, 3 Mar 2024 11:14:34 +0000 (11:14 +0000)
committermiod <miod@openbsd.org>
Sun, 3 Mar 2024 11:14:34 +0000 (11:14 +0000)
reenabling the FPU as part of the regular processing of another exception.

sys/arch/m88k/m88k/m88100_fp.c
sys/arch/m88k/m88k/trap.c

index 250cfe3..c227f8b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: m88100_fp.c,v 1.6 2024/03/03 11:03:13 miod Exp $      */
+/*     $OpenBSD: m88100_fp.c,v 1.7 2024/03/03 11:14:34 miod Exp $      */
 
 /*
  * Copyright (c) 2007, 2014, Miodrag Vallat.
@@ -442,9 +442,16 @@ m88100_fpu_imprecise_exception(struct trapframe *frame)
         */
        __asm__ volatile ("fstcr %0, %%fcr62" :: "r"(frame->tf_fpsr));
 
-       /* Check for a SIGFPE condition */
-       if (frame->tf_fpsr & frame->tf_fpcr)
-               m88100_fpu_checksig(frame, SIGFPE, 0 /* SI_NOINFO */);
+       /*
+        * Check for a SIGFPE condition.
+        *
+        * XXX If the exception was caught while in kernel mode, we can't
+        * XXX send a signal at this point... what to do?
+        */
+       if ((frame->tf_fpsr & PSR_MODE) == 0) {
+               if (frame->tf_fpsr & frame->tf_fpcr)
+                       m88100_fpu_checksig(frame, SIGFPE, 0 /* SI_NOINFO */);
+       }
 }
 
 /*
index 02fa561..66677e2 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: trap.c,v 1.134 2024/02/18 21:27:38 miod Exp $ */
+/*     $OpenBSD: trap.c,v 1.135 2024/03/03 11:14:34 miod Exp $ */
 /*
  * Copyright (c) 2004, Miodrag Vallat.
  * Copyright (c) 1998 Steve Murphree, Jr.
@@ -511,6 +511,15 @@ user_fault:
        case T_FPEPFLT+T_USER:
                m88100_fpu_precise_exception(frame);
                goto userexit;
+       case T_FPEIFLT:
+               /*
+                * Although the kernel does not use FPU instructions,
+                * userland-triggered FPU imprecise exceptions may be
+                * raised during exception processing, when the FPU gets
+                * reenabled (i.e. immediately when returning to
+                * m88100_fpu_enable).
+                */
+               /* FALLTHROUGH */
        case T_FPEIFLT+T_USER:
                m88100_fpu_imprecise_exception(frame);
                goto userexit;