Hello again!
Hartmut Birr wrote:
 I've revert some parts of fpu.c to your first
patch. It works now on my smp
machine.
 
I have attached a patch to this email, maybe you can try if it works
with this patch. It is a patch against current reactos CVS.
I didn't see diff which you attached to your mail the first time, but it
looks like it's an old version of the fpu.c which I have modified...
maybe it doesn't bugcheck but I think it won't work (unless you have
also reverted tskswitch.S...)
I have also attached a fputest program which tests wether the FPU state
is preserved or not.
 - blight
Index: ntoskrnl/ke/i386/fpu.c
===================================================================
RCS file: /CVS/ReactOS/reactos/ntoskrnl/ke/i386/fpu.c,v
retrieving revision 1.16
diff -u -r1.16 fpu.c
--- ntoskrnl/ke/i386/fpu.c      21 Nov 2004 13:33:34 -0000      1.16
+++ ntoskrnl/ke/i386/fpu.c      23 Nov 2004 20:36:58 -0000
@@ -28,6 +28,7 @@
 /* INCLUDES *****************************************************************/
+#include <roscfg.h>
 #include <ntoskrnl.h>
 #define NDEBUG
 #include <internal/debug.h>
@@ -67,7 +68,8 @@
 /* GLOBALS *******************************************************************/
 ULONG HardwareMathSupport = 0;
-static ULONG MxcsrFeatureMask = 0, FxsrSupport = 0, XmmSupport = 0;
+static ULONG MxcsrFeatureMask = 0, XmmSupport = 0;
+ULONG FxsrSupport = 0; /* used by Ki386ContextSwitch for MP */
 /* FUNCTIONS *****************************************************************/
@@ -406,10 +408,14 @@
 {
   if (ExceptionNr == 7) /* device not present */
     {
+      BOOL FpuInitialized = FALSE;
       unsigned int cr0 = Ke386GetCr0();
-      PKTHREAD CurrentThread, NpxThread;
+      PKTHREAD CurrentThread;
       PFX_SAVE_AREA FxSaveArea;
       KIRQL oldIrql;
+#ifndef MP
+      PKTHREAD NpxThread;
+#endif
       (void) cr0;
       ASSERT((cr0 & X86_CR0_TS) == X86_CR0_TS);
@@ -422,15 +428,17 @@
       asm volatile("clts");
       CurrentThread = KeGetCurrentThread();
+#ifndef MP
       NpxThread = KeGetCurrentKPCR()->PrcbData.NpxThread;
+#endif
       ASSERT(CurrentThread != NULL);
-      DPRINT("Device not present exception happened! (Cr0 = 0x%x, NpxState =
0x%x)\n", Ke386GetCr0(), CurrentThread->NpxState);
+      DPRINT("Device not present exception happened! (Cr0 = 0x%x, NpxState =
0x%x)\n", cr0, CurrentThread->NpxState);
+#ifndef MP
       /* check if the current thread already owns the FPU */
       if (NpxThread != CurrentThread) /* FIXME: maybe this could be an assertation */
         {
-          BOOL FpuInitialized = FALSE;
           /* save the FPU state into the owner's save area */
           if (NpxThread != NULL)
             {
@@ -448,6 +456,7 @@
                 }
               NpxThread->NpxState = NPX_STATE_VALID;
             }
+#endif /* !MP */
           /* restore the state of the current thread */
           ASSERT((CurrentThread->NpxState & NPX_STATE_DIRTY) == 0);
@@ -483,7 +492,9 @@
                 }
             }
           KeGetCurrentKPCR()->PrcbData.NpxThread = CurrentThread;
+#ifndef MP
         }
+#endif
       CurrentThread->NpxState |= NPX_STATE_DIRTY;
       KeLowerIrql(oldIrql);
@@ -508,8 +519,8 @@
       CurrentThread = KeGetCurrentThread();
       if (NpxThread == NULL)
         {
-          DPRINT1("!!! Math/Xmm fault ignored! (NpxThread == NULL)\n");
           KeLowerIrql(oldIrql);
+          DPRINT1("!!! Math/Xmm fault ignored! (NpxThread == NULL)\n");
           return STATUS_SUCCESS;
         }
@@ -540,7 +551,6 @@
           PFNSAVE_FORMAT FnSave = (PFNSAVE_FORMAT)&Context->FloatSave;
           asm volatile("fnsave %0" : : "m"(*FnSave));
           KeLowerIrql(oldIrql);
-          memset(Context->FloatSave.RegisterArea, 0,
sizeof(Context->FloatSave.RegisterArea));
           KiFnsaveToFxsaveFormat((PFXSAVE_FORMAT)Context->ExtendedRegisters, FnSave);
         }
Index: ntoskrnl/ke/i386/tskswitch.S
===================================================================
RCS file: /CVS/ReactOS/reactos/ntoskrnl/ke/i386/tskswitch.S,v
retrieving revision 1.20
diff -u -r1.20 tskswitch.S
--- ntoskrnl/ke/i386/tskswitch.S        20 Nov 2004 23:46:36 -0000      1.20
+++ ntoskrnl/ke/i386/tskswitch.S        23 Nov 2004 20:13:31 -0000
@@ -26,6 +26,7 @@
 /* INCLUDES ******************************************************************/
+#include <roscfg.h>
 #include <internal/i386/segment.h>
 #include <internal/i386/ke.h>
 #include <internal/i386/fpu.h>
@@ -105,8 +106,30 @@
 0:
        lldtw   %ax
+       /*
+        * Get the pointer to the old thread.
+        */
        movl    12(%ebp), %ebx
+#ifdef MP
+       /*
+        * Save FPU state if the thread has used it.
+        */
+       movl    $0, %fs:KPCR_NPX_THREAD
+       testl   $NPX_STATE_DIRTY, KTHREAD_NPX_STATE(%ebx)
+       jz      3f
+       movl    KTHREAD_INITIAL_STACK(%ebx), %eax
+       cmpl    $0, _FxsrSupport
+       je      1f
+       fxsave  -SIZEOF_FX_SAVE_AREA(%eax)
+       jmp     2f
+1:
+       fnsave  -SIZEOF_FX_SAVE_AREA(%eax)
+2:
+       movl    $NPX_STATE_VALID, KTHREAD_NPX_STATE(%ebx)
+3:
+#endif /* MP */
+
        /*
         * FIXME: Save debugging state.
         */
@@ -152,14 +175,16 @@
        /*
         * Set TS in cr0 to catch FPU code and load the FPU state when needed
-        * We do this only if NewThread != KPCR->NpxThread
+        * For uni-processor we do this only if NewThread != KPCR->NpxThread
         */
+#ifndef MP
        cmpl    %ebx, %fs:KPCR_NPX_THREAD
-       je      1f
+       je      4f
+#endif /* !MP */
        movl    %cr0, %eax
        orl     $X86_CR0_TS, %eax
        movl    %eax, %cr0
-1:
+4:
        /*
         * FIXME: Restore debugging state
@@ -174,9 +199,9 @@
        call    _KeReleaseSpinLockFromDpcLevel@4
        cmpl    $0, _PiNrThreadsAwaitingReaping
-       je      4f
+       je      5f
        call    _PiWakeupReaperThread@0
-4:
+5:
        /*
         * Restore the saved register and exit