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/f... ============================================================================== --- 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/i... ============================================================================== --- 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/u... ============================================================================== --- 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