[Bug 289232] i386 (x87) signal incorrectly reports FPE_FLTRES over FPE_FLTUND when both are present

From: <bugzilla-noreply_at_freebsd.org>
Date: Mon, 01 Sep 2025 18:32:46 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=289232

--- Comment #9 from Dave Rivers <riverstdr@gmail.com> ---
The flag bits from the status word are modified before the signal handler is
called to only reflect the meaning of the si_code.

So, if originally the x87 flag bits had #U and #P set, the x87 #U flag bit is
turned off before invoking the signal handler so that the bits in the status
register match the value of the SI_CODE  (which is - unfortunate - because it
means there is no programmatic way to work-around his problem.) 

If you look at this comment in /usr/src/sys/amd64/amd64/fpu.c, it says:


 * The macro to choose one of these values does these steps: 1) Throw
 * away status word bits that cannot be masked.  2) Throw away the bits
 * currently masked in the control word, assuming the user isn't
 * interested in them anymore.  3) Reinsert status word bit 7 (stack
 * fault) if it is set, which cannot be masked but must be presered.
 * 4) Use the remaining bits to point into the trapcode table.


Step #2 is the one I thought would be the idea of removing any "uninteresting"
bits in the status register... but - I have to admit to not seeing in the code
precisely where that is accomplished.   Seems like that would require a FLDCW
instruction, but I didn't find it... 

Still - that seems to be the behavior I'm seeing - the fpu status word only has
the (one) bit set that match the value from si_code; when the operation would
have set both.  So, perhaps it's modifying the saved context to only have the
one bit set, then when the process restarts that value is loaded into the FPU
status word?  (But FXRSTOR will also restore the x87 FPU mask.)

-- 
You are receiving this mail because:
You are the assignee for the bug.