Intel 64 and IA-32 Architectures Software Developers Manual Volume 1, Basic Architecture

Vol. 1 D-25
GUIDELINES FOR WRITING X87 FPU EXCEPTION HANDLERS
D.3.6.2 Tracking x87 FPU Ownership
Since the contents of the x87 FPU may not belong to the currently executing thread,
the thread identifier for the last x87 FPU user needs to be tracked separately. This is
not complicated; the kernel should simply provide a variable to store the thread iden-
tifier of the x87 FPU owner, separate from the variable that stores the identifier for
the currently executing thread. This variable is updated in the DNA exception
handler, and is used by the DNA exception handler to find the x87 FPU save areas of
the old and new threads. A simplified flow for a DNA exception handler is then:
1. Use the “x87 FPU Owner” variable to find the x87 FPU save area of the last
thread to use the x87 FPU.
2. Save the x87 FPU contents to the old thread’s save area, typically using an
FNSAVE or FXSAVE instruction.
3. Set the x87 FPU Owner variable to the identify the currently executing thread.
4. Reload the x87 FPU contents from the new thread’s save area, typically using an
FRSTOR or FXSTOR instruction.
5. Clear TS using the CLTS instruction and exit the DNA exception handler.
While this flow covers the basic requirements for speculatively deferred x87 FPU
state swaps, there are some additional subtleties that need to be handled in a robust
implementation.
D.3.6.3 Interaction of x87 FPU State Saves and Floating-Point Exception
Association
Recall these key points from earlier in this document: When considering floating-
point exceptions across all implementations of the IA-32 architecture, and across all
floating-point instructions, a floating-point exception can be initiated from any time
during the excepting floating-point instruction, up to just before the next floating-
point instruction. The “next” floating-point instruction may be the FNSAVE used to
save the x87 FPU state for a task switch. In the case of “no-wait:” instructions such
as FNSAVE, the interrupt from a previously excepting instruction (NE = 0 case) may
arrive just before the no-wait instruction, during, or shortly thereafter with a system
dependent delay.
Note that this implies that an floating-point exception might be registered during the
state swap process itself, and the kernel and floating-point exception interrupt
handler must be prepared for this case.
A simple way to handle the case of exceptions arriving during x87 FPU state swaps is
to allow the kernel to be one of the x87 FPU owning threads. A reserved thread iden-
tifier is used to indicate kernel ownership of the x87 FPU. During an floating-point
state swap, the “x87 FPU owner” variable should be set to indicate the kernel as the
current owner. At the completion of the state swap, the variable should be set to indi-
cate the new owning thread. The numeric exception handler needs to check the x87
FPU owner and discard any numeric exceptions that occur while the kernel is the x87