Index: ntoskrnl/include/internal/i386/intrin_i.h
===================================================================
--- ntoskrnl/include/internal/i386/intrin_i.h	(revision 68659)
+++ ntoskrnl/include/internal/i386/intrin_i.h	(working copy)
@@ -51,21 +51,6 @@
 }
 
 FORCEINLINE
-VOID
-Ke386LoadFpuState(IN PFX_SAVE_AREA SaveArea)
-{
-    extern ULONG KeI386FxsrPresent;
-    if (KeI386FxsrPresent)
-    {
-        __asm__ __volatile__ ("fxrstor %0\n" : "=m"(SaveArea) : );
-    }
-    else
-    {
-        __asm__ __volatile__ (".globl _FrRestore\n _FrRestore: \n frstor %0\n wait\n" : "=m"(SaveArea) : );
-    }
-}
-
-FORCEINLINE
 USHORT
 Ke386GetLocalDescriptorTable()
 {
Index: ntoskrnl/include/internal/i386/ke.h
===================================================================
--- ntoskrnl/include/internal/i386/ke.h	(revision 68659)
+++ ntoskrnl/include/internal/i386/ke.h	(working copy)
@@ -541,7 +541,6 @@
 extern VOID NTAPI ExpInterlockedPopEntrySListResume(VOID);
 extern VOID __cdecl CopyParams(VOID);
 extern VOID __cdecl ReadBatch(VOID);
-extern VOID __cdecl FrRestore(VOID);
 extern CHAR KiSystemCallExitBranch[];
 extern CHAR KiSystemCallExit[];
 extern CHAR KiSystemCallExit2[];
Index: ntoskrnl/ke/i386/ctxswitch.S
===================================================================
--- ntoskrnl/ke/i386/ctxswitch.S	(revision 68659)
+++ ntoskrnl/ke/i386/ctxswitch.S	(working copy)
@@ -18,6 +18,7 @@
 EXTERN @KiRetireDpcList@4:PROC
 EXTERN @KiEnterV86Mode@4:PROC
 EXTERN @KiExitV86Mode@4:PROC
+EXTERN _KeI386FxsrPresent:DWORD
 
 /* FUNCTIONS ****************************************************************/
 .code
@@ -159,4 +160,28 @@
     popad
     ret 4
 
+PUBLIC _FrRestore
+PUBLIC @Ke386LoadFpuState@4
+@Ke386LoadFpuState@4:
+
+    /* Check if we have FXSR and choose which operand to use */
+    test byte ptr [_KeI386FxsrPresent], 1
+    jz _FrRestore
+
+    /* Restore all the FPU, MMX, XMM and MXCSR registers */
+    fxrstor [ecx]
+    ret
+
+    /*
+     * Just restore the basic FPU registers.
+     * This may raise an exception depending
+     * on the status word, which KiNpxHandler will
+     * need to check for and handle during delayed load
+     * to avoid raising an unhandled exception
+     * and crashing the system.
+     */
+_FrRestore:
+    frstor [ecx]
+    ret
+
 END
Index: ntoskrnl/ke/i386/traphdlr.c
===================================================================
--- ntoskrnl/ke/i386/traphdlr.c	(revision 68659)
+++ ntoskrnl/ke/i386/traphdlr.c	(working copy)
@@ -15,6 +15,12 @@
 VOID KiFastCallEntry(VOID);
 VOID KiFastCallEntryWithSingleStep(VOID);
 
+extern PVOID FrRestore;
+
+VOID
+FASTCALL
+Ke386LoadFpuState(IN PFX_SAVE_AREA SaveArea);
+
 /* GLOBALS ********************************************************************/
 
 UCHAR KiTrapPrefixTable[] =
@@ -251,16 +257,16 @@
         SaveArea->Cr0NpxState |= CR0_TS;
 
         /* Only valid if it happened during a restore */
-        //if ((PVOID)TrapFrame->Eip == FrRestore)
+        if ((PVOID)TrapFrame->Eip == FrRestore)
         {
             /* It did, so just skip the instruction */
-            //TrapFrame->Eip += 3; /* sizeof(FRSTOR) */
-            //KiEoiHelper(TrapFrame);
+            TrapFrame->Eip += 3; /* sizeof(FRSTOR) */
+            KiEoiHelper(TrapFrame);
         }
     }
 
     /* User or kernel trap -- get ready to issue an exception */
-    //if (Thread->NpxState == NPX_STATE_NOT_LOADED)
+    if (Thread->NpxState == NPX_STATE_NOT_LOADED)
     {
         /* Update CR0 */
         Cr0 = __readcr0();
@@ -775,8 +781,7 @@
                 NpxSaveArea = KiGetThreadNpxArea(NpxThread);
 
                 /* Save FPU state */
-                DPRINT("FIXME: Save FPU state: %p\n", NpxSaveArea);
-                //Ke386SaveFpuState(NpxSaveArea);
+                Ke386SaveFpuState(NpxSaveArea);
 
                 /* Update NPX state */
                 NpxThread->NpxState = NPX_STATE_NOT_LOADED;
@@ -783,7 +788,7 @@
            }
 
             /* Load FPU state */
-            //Ke386LoadFpuState(SaveArea);
+            Ke386LoadFpuState(SaveArea);
 
             /* Update NPX state */
             Thread->NpxState = NPX_STATE_LOADED;
