Intel 64 and IA-32 Architectures Software Developers Manual Volume 1, Basic Architecture
Vol. 1 D-23
GUIDELINES FOR WRITING X87 FPU EXCEPTION HANDLERS
; type will cause the same problem
. . . .
FCLEX ; clear the x87 FPU error conditions & thus
; turn off FERR# & reset the IGNNE# FF
The problem will only occur if the processor enters SMM between the OUT and the
FLDCW instructions. But if that happens, AND the SMM code saves the x87 FPU state
using FNSAVE, then the IGNNE# Flip Flop will be cleared (because FNSAVE clears the
x87 FPU errors and thus de-asserts FERR#). When the processor returns from SMM it
will restore the x87 FPU state with FRSTOR, which will re-assert FERR#, but the
IGNNE# Flip Flop will not get set. Then when the x87 FPU error handler executes the
FLDCW instruction, the active error condition will cause the processor to re-enter the
x87 FPU error handler from the beginning. This may cause the handler to malfunction.
To avoid this problem, Intel recommends two measures:
1. Do not use the x87 FPU for calculations inside SMM code. (The normal power
management, and sometimes security, functions provided by SMM have no need
for x87 FPU calculations; if they are needed for some special case, use scaling
or emulation instead.) This eliminates the need to do FNSAVE/FRSTOR inside
SMM code, except when going into a 0 V suspend state (in which, in order to
save power, the CPU is turned off completely, requiring its complete state to be
saved).
2. The system should not call upon SMM code to put the processor into 0 V suspend
while the processor is running x87 FPU calculations, or just after an interrupt has
occurred. Normal power management protocol avoids this by going into power
down states only after timed intervals in which no system activity occurs.
D.3.6 Considerations When x87 FPU Shared Between Tasks
The IA-32 architecture allows speculative deferral of floating-point state swaps on
task switches. This feature allows postponing an x87 FPU state swap until an x87 FPU
instruction is actually encountered in another task. Since kernel tasks rarely use
floating-point, and some applications do not use floating-point or use it infrequently,
the amount of time saved by avoiding unnecessary stores of the floating-point state
is significant. Speculative deferral of x87 FPU saves does, however, place an extra
burden on the kernel in three key ways:
1. The kernel must keep track of which thread owns the x87 FPU, which may be
different from the currently executing thread.
2. The kernel must associate any floating-point exceptions with the generating task.
This requires special handling since floating-point exceptions are delivered
asynchronous with other system activity.
3. There are conditions under which spurious floating-point exception interrupts are
generated, which the kernel must recognize and discard.