From bdb6d7db1a7d8b87597e503d31a86f8323a2bd2a Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Fri, 7 Mar 2025 16:37:57 -0500 Subject: [PATCH] kernel/x86: Determine math/SIMD exception cause in exception handler. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes a TODO. Change-Id: I75e7f05bd72f1500234a7b43ed9da01d3a61ecf2 Reviewed-on: https://review.haiku-os.org/c/haiku/+/9082 Tested-by: Commit checker robot Reviewed-by: Jérôme Duval Reviewed-by: waddlesplash --- src/system/kernel/arch/x86/arch_int.cpp | 41 ++++++++++++++++++------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/src/system/kernel/arch/x86/arch_int.cpp b/src/system/kernel/arch/x86/arch_int.cpp index 407d5858a6..d25c34b823 100644 --- a/src/system/kernel/arch/x86/arch_int.cpp +++ b/src/system/kernel/arch/x86/arch_int.cpp @@ -28,6 +28,7 @@ #include #include +#include #include // interrupt controllers @@ -157,13 +158,39 @@ x86_unexpected_exception(iframe* frame) break; case 16: // x87 FPU Floating-Point Error (#MF) + case 19: // SIMD Floating-Point Exception (#XF) + { type = B_FLOATING_POINT_EXCEPTION; signalNumber = SIGFPE; - signalCode = FPE_FLTDIV; - // TODO: Determine the correct cause via the FPU status - // register! + signalCode = FPE_FLTINV; signalAddress = frame->ip; + + uint32 status = 0; + if (frame->vector == 19) { + // MXCSR is only available on SSE, however exception 19 should only + // ever occur if the processor has SSE anyway and OSXMMEXCPT is set. + __stmxcsr(&status); + } else { + uint16 fsw = 0; + __fnstsw(&fsw); + status = fsw; + } + + // Determine the real cause of the exception, if possible. + if ((status & FE_INVALID) != 0) + signalCode = FPE_FLTINV; + else if ((status & FE_DENORMAL) != 0) + signalCode = FPE_FLTUND; + else if ((status & FE_DIVBYZERO) != 0) + signalCode = FPE_FLTDIV; + else if ((status & FE_OVERFLOW) != 0) + signalCode = FPE_FLTOVF; + else if ((status & FE_UNDERFLOW) != 0) + signalCode = FPE_FLTUND; + else if ((status & FE_INEXACT) != 0) + signalCode = FPE_FLTRES; break; + } case 17: // Alignment Check Exception (#AC) type = B_ALIGNMENT_EXCEPTION; @@ -174,14 +201,6 @@ x86_unexpected_exception(iframe* frame) signalError = EFAULT; break; - case 19: // SIMD Floating-Point Exception (#XF) - type = B_FLOATING_POINT_EXCEPTION; - signalNumber = SIGFPE; - signalCode = FPE_FLTDIV; - // TODO: Determine the correct cause via the MXCSR register! - signalAddress = frame->ip; - break; - default: x86_invalid_exception(frame); return;