mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 01:35:47 +00:00
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. svn path=/trunk/; revision=52809
This commit is contained in:
parent
5a85fe0145
commit
09a15b8b05
3 changed files with 42 additions and 21 deletions
|
@ -223,11 +223,8 @@ CreateFiberEx(SIZE_T dwStackCommitSize,
|
||||||
Fiber->ActivationContextStack = ActivationContextStack;
|
Fiber->ActivationContextStack = ActivationContextStack;
|
||||||
Fiber->Context.ContextFlags = CONTEXT_FULL;
|
Fiber->Context.ContextFlags = CONTEXT_FULL;
|
||||||
|
|
||||||
/* Save FPU State if requsted */
|
/* Save FPU State if requested */
|
||||||
if (dwFlags & FIBER_FLAG_FLOAT_SWITCH)
|
Fiber->Context.ContextFlags = (dwFlags & FIBER_FLAG_FLOAT_SWITCH) ? CONTEXT_FLOATING_POINT : 0;
|
||||||
{
|
|
||||||
Fiber->Context.ContextFlags |= CONTEXT_FLOATING_POINT;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* initialize the context for the fiber */
|
/* initialize the context for the fiber */
|
||||||
BasepInitializeContext(&Fiber->Context,
|
BasepInitializeContext(&Fiber->Context,
|
||||||
|
|
|
@ -35,7 +35,7 @@ _SwitchToFiber@4:
|
||||||
fnstcw [eax+FIBER_CONTEXT_FLOAT_SAVE_CONTROL_WORD]
|
fnstcw [eax+FIBER_CONTEXT_FLOAT_SAVE_CONTROL_WORD]
|
||||||
|
|
||||||
/* Check if the CPU supports SIMD MXCSR State Save */
|
/* 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
|
jnz NoFpuStateSave
|
||||||
stmxcsr [eax+FIBER_CONTEXT_DR6]
|
stmxcsr [eax+FIBER_CONTEXT_DR6]
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ StatusWordChanged:
|
||||||
ControlWordEqual:
|
ControlWordEqual:
|
||||||
|
|
||||||
/* Load the new one */
|
/* Load the new one */
|
||||||
cmp byte ptr ds:[PROCESSOR_FEATURE_FXSR], 1
|
cmp byte ptr ds:[PF_XMMI_INSTRUCTIONS_AVAILABLE], 1
|
||||||
jnz NoFpuStateRestore
|
jnz NoFpuStateRestore
|
||||||
ldmxcsr [ecx+FIBER_CONTEXT_DR6]
|
ldmxcsr [ecx+FIBER_CONTEXT_DR6]
|
||||||
|
|
||||||
|
|
|
@ -336,8 +336,9 @@ BasepInitializeContext(IN PCONTEXT Context,
|
||||||
IN ULONG ContextType)
|
IN ULONG ContextType)
|
||||||
{
|
{
|
||||||
#ifdef _M_IX86
|
#ifdef _M_IX86
|
||||||
|
ULONG ContextFlags;
|
||||||
DPRINT("BasepInitializeContext: %p\n", Context);
|
DPRINT("BasepInitializeContext: %p\n", Context);
|
||||||
|
|
||||||
/* Setup the Initial Win32 Thread Context */
|
/* Setup the Initial Win32 Thread Context */
|
||||||
Context->Eax = (ULONG)StartAddress;
|
Context->Eax = (ULONG)StartAddress;
|
||||||
Context->Ebx = (ULONG)Parameter;
|
Context->Ebx = (ULONG)Parameter;
|
||||||
|
@ -352,30 +353,53 @@ BasepInitializeContext(IN PCONTEXT Context,
|
||||||
Context->SegSs = KGDT_R3_DATA | RPL_MASK;
|
Context->SegSs = KGDT_R3_DATA | RPL_MASK;
|
||||||
Context->SegGs = 0;
|
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 */
|
/* Set the EFLAGS */
|
||||||
Context->EFlags = 0x3000; /* IOPL 3 */
|
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;
|
Context->Eip = (ULONG)BaseThreadStartupThunk;
|
||||||
}
|
}
|
||||||
else if (ContextType == 2) /* For Fibers */
|
else if (ContextType == 2)
|
||||||
{
|
{
|
||||||
Context->Eip = (ULONG)BaseFiberStartup;
|
/* 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 */
|
else
|
||||||
{
|
{
|
||||||
|
/* For first thread in a Process */
|
||||||
Context->Eip = (ULONG)BaseProcessStartThunk;
|
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)
|
#elif defined(_M_AMD64)
|
||||||
DPRINT("BasepInitializeContext: %p\n", Context);
|
DPRINT("BasepInitializeContext: %p\n", Context);
|
||||||
|
|
||||||
/* Setup the Initial Win32 Thread Context */
|
/* Setup the Initial Win32 Thread Context */
|
||||||
Context->Rax = (ULONG_PTR)StartAddress;
|
Context->Rax = (ULONG_PTR)StartAddress;
|
||||||
Context->Rbx = (ULONG_PTR)Parameter;
|
Context->Rbx = (ULONG_PTR)Parameter;
|
||||||
|
@ -405,10 +429,10 @@ BasepInitializeContext(IN PCONTEXT Context,
|
||||||
{
|
{
|
||||||
Context->Rip = (ULONG_PTR)BaseProcessStartThunk;
|
Context->Rip = (ULONG_PTR)BaseProcessStartThunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the Context Flags */
|
/* Set the Context Flags */
|
||||||
Context->ContextFlags = CONTEXT_FULL;
|
Context->ContextFlags = CONTEXT_FULL;
|
||||||
|
|
||||||
/* Give it some room for the Parameter */
|
/* Give it some room for the Parameter */
|
||||||
Context->Rsp -= sizeof(PVOID);
|
Context->Rsp -= sizeof(PVOID);
|
||||||
#else
|
#else
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue