Author: ion
Date: Sat Jul 23 16:26:03 2011
New Revision: 52809
URL:
http://svn.reactos.org/svn/reactos?rev=52809&view=rev
Log:
Thanks to Timo Kreuzer for discovering what led to these:
[KERNEL32]: BasepInitializeContext was not creating a correct CONTEXT record for fibers:
the stack return address was not set (EIP was being used instead), and support for
FPU-compatible Fibers was non-existent.
[KERNEL32]: CreateFiberEx was not passing the correct context flags to
BasepInitializeContext to notify it that this is an FPU-fiber.
[KERNEL32]: SwitchToFiber was using some weird "FXSR" constant that maps to
checking of PowerPC 64-bit Move instructions are available. We actually want to check for
XMMI.
Modified:
trunk/reactos/dll/win32/kernel32/client/fiber.c
trunk/reactos/dll/win32/kernel32/client/i386/fiber.S
trunk/reactos/dll/win32/kernel32/client/utils.c
Modified: trunk/reactos/dll/win32/kernel32/client/fiber.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/…
==============================================================================
--- trunk/reactos/dll/win32/kernel32/client/fiber.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/client/fiber.c [iso-8859-1] Sat Jul 23 16:26:03 2011
@@ -223,11 +223,8 @@
Fiber->ActivationContextStack = ActivationContextStack;
Fiber->Context.ContextFlags = CONTEXT_FULL;
- /* Save FPU State if requsted */
- if (dwFlags & FIBER_FLAG_FLOAT_SWITCH)
- {
- Fiber->Context.ContextFlags |= CONTEXT_FLOATING_POINT;
- }
+ /* Save FPU State if requested */
+ Fiber->Context.ContextFlags = (dwFlags & FIBER_FLAG_FLOAT_SWITCH) ?
CONTEXT_FLOATING_POINT : 0;
/* initialize the context for the fiber */
BasepInitializeContext(&Fiber->Context,
Modified: trunk/reactos/dll/win32/kernel32/client/i386/fiber.S
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/…
==============================================================================
--- trunk/reactos/dll/win32/kernel32/client/i386/fiber.S [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/client/i386/fiber.S [iso-8859-1] Sat Jul 23 16:26:03
2011
@@ -35,7 +35,7 @@
fnstcw [eax+FIBER_CONTEXT_FLOAT_SAVE_CONTROL_WORD]
/* Check if the CPU supports SIMD MXCSR State Save */
- cmp byte ptr ds:[PROCESSOR_FEATURE_FXSR], 1
+ cmp byte ptr ds:[PF_XMMI_INSTRUCTIONS_AVAILABLE], 1
jnz NoFpuStateSave
stmxcsr [eax+FIBER_CONTEXT_DR6]
@@ -99,7 +99,7 @@
ControlWordEqual:
/* Load the new one */
- cmp byte ptr ds:[PROCESSOR_FEATURE_FXSR], 1
+ cmp byte ptr ds:[PF_XMMI_INSTRUCTIONS_AVAILABLE], 1
jnz NoFpuStateRestore
ldmxcsr [ecx+FIBER_CONTEXT_DR6]
Modified: trunk/reactos/dll/win32/kernel32/client/utils.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/…
==============================================================================
--- trunk/reactos/dll/win32/kernel32/client/utils.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/client/utils.c [iso-8859-1] Sat Jul 23 16:26:03 2011
@@ -336,8 +336,9 @@
IN ULONG ContextType)
{
#ifdef _M_IX86
+ ULONG ContextFlags;
DPRINT("BasepInitializeContext: %p\n", Context);
-
+
/* Setup the Initial Win32 Thread Context */
Context->Eax = (ULONG)StartAddress;
Context->Ebx = (ULONG)Parameter;
@@ -352,30 +353,53 @@
Context->SegSs = KGDT_R3_DATA | RPL_MASK;
Context->SegGs = 0;
+ /* Set the Context Flags */
+ ContextFlags = Context->ContextFlags;
+ Context->ContextFlags = CONTEXT_FULL;
+
+ /* Give it some room for the Parameter */
+ Context->Esp -= sizeof(PVOID);
+
/* Set the EFLAGS */
Context->EFlags = 0x3000; /* IOPL 3 */
- if (ContextType == 1) /* For Threads */
- {
+ /* What kind of context is being created? */
+ if (ContextType == 1)
+ {
+ /* For Threads */
Context->Eip = (ULONG)BaseThreadStartupThunk;
}
- else if (ContextType == 2) /* For Fibers */
- {
- Context->Eip = (ULONG)BaseFiberStartup;
- }
- else /* For first thread in a Process */
- {
+ else if (ContextType == 2)
+ {
+ /* This is a fiber: make space for the return address */
+ Context->Esp -= sizeof(PVOID);
+ *((PVOID*)Context->Esp) = BaseFiberStartup;
+
+ /* Is FPU state required? */
+ Context->ContextFlags |= ContextFlags;
+ if (ContextFlags == CONTEXT_FLOATING_POINT)
+ {
+ /* Set an initial state */
+ Context->FloatSave.ControlWord = 0x27F;
+ Context->FloatSave.StatusWord = 0;
+ Context->FloatSave.TagWord = 0xFFFF;
+ Context->FloatSave.ErrorOffset = 0;
+ Context->FloatSave.ErrorSelector = 0;
+ Context->FloatSave.DataOffset = 0;
+ Context->FloatSave.DataSelector = 0;
+ if (SharedUserData->ProcessorFeatures[PF_XMMI_INSTRUCTIONS_AVAILABLE])
+ Context->Dr6 = 0x1F80;
+ }
+ }
+ else
+ {
+ /* For first thread in a Process */
Context->Eip = (ULONG)BaseProcessStartThunk;
}
-
- /* Set the Context Flags */
- Context->ContextFlags = CONTEXT_FULL;
-
- /* Give it some room for the Parameter */
- Context->Esp -= sizeof(PVOID);
+
#elif defined(_M_AMD64)
DPRINT("BasepInitializeContext: %p\n", Context);
-
+
/* Setup the Initial Win32 Thread Context */
Context->Rax = (ULONG_PTR)StartAddress;
Context->Rbx = (ULONG_PTR)Parameter;
@@ -405,10 +429,10 @@
{
Context->Rip = (ULONG_PTR)BaseProcessStartThunk;
}
-
+
/* Set the Context Flags */
Context->ContextFlags = CONTEXT_FULL;
-
+
/* Give it some room for the Parameter */
Context->Rsp -= sizeof(PVOID);
#else