How did our Fiber tests ever pass?
Best regards, Alex Ionescu
On Thu, Oct 8, 2015 at 9:26 AM, sginsberg@svn.reactos.org wrote:
Author: sginsberg Date: Thu Oct 8 16:26:29 2015 New Revision: 69466
URL: http://svn.reactos.org/svn/reactos?rev=69466&view=rev Log: [KERNEL32] Fix bug in CreateFiberEx that made it replace the CONTEXT_FULL bits rather than ORing in CONTEXT_FLOATING_POINT when caller wanted FPU state saved. SwitchToFiber checks for CONTEXT_FULL OR CONTEXT_FLOATING_POINT so the save/restore would fail. Moreover, fix BaseInitializeContext that was not checking CONTEXT_FLOATING_POINT correctly for some fibers and, as a result, not initializing FPU context correctly for callers of ConvertThreadToFiberEx. Finally, because trying to access address 0x6 is generally a bad idea, fix SwitchToFiber to use the correct shared user data offsets. Misc cleanup all around. Bonus: Sort TEB/PEB asm offsets and add GDI Batch Count offset, needed soon.
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 trunk/reactos/include/asm/ks386.template.h trunk/reactos/include/ndk/i386/asm.h
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] Thu Oct 8 16:26:29 2015 @@ -27,10 +27,9 @@
VOID WINAPI -BaseRundownFls(IN PVOID FlsData) +BaseRundownFls(_In_ PVOID FlsData) { /* No FLS support yet */
}
/* PUBLIC FUNCTIONS ***********************************************************/ @@ -55,16 +54,18 @@ return FALSE; }
- /* this thread won't run a fiber anymore */
/* This thread won't run a fiber anymore */ Teb->HasFiberData = FALSE; FiberData = Teb->NtTib.FiberData; Teb->NtTib.FiberData = NULL;
/* Free the fiber */ ASSERT(FiberData != NULL);
- RtlFreeHeap(GetProcessHeap(), 0, FiberData);
- /* success */
- RtlFreeHeap(GetProcessHeap(),
0,FiberData);- /* Success */ return TRUE;
}
@@ -73,15 +74,15 @@ */ LPVOID WINAPI -ConvertThreadToFiberEx(LPVOID lpParameter,
DWORD dwFlags)+ConvertThreadToFiberEx(_In_opt_ LPVOID lpParameter,
_In_ DWORD dwFlags){ PTEB Teb; PFIBER Fiber; DPRINT1("Converting Thread to Fiber\n");
/* Check for invalid flags */
- if (dwFlags &~ FIBER_FLAG_FLOAT_SWITCH)
- if (dwFlags & ~FIBER_FLAG_FLOAT_SWITCH) { /* Fail */ SetLastError(ERROR_INVALID_PARAMETER);
@@ -98,9 +99,12 @@ }
/* Allocate the fiber */
- Fiber = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(FIBER));
- Fiber = RtlAllocateHeap(RtlGetProcessHeap(),
0, if (!Fiber) {sizeof(FIBER)); }/* Fail */ SetLastError(ERROR_NOT_ENOUGH_MEMORY); return NULL;@@ -114,13 +118,11 @@ Fiber->FlsData = Teb->FlsData; Fiber->GuaranteedStackBytes = Teb->GuaranteedStackBytes; Fiber->ActivationContextStackPointer = Teb->ActivationContextStackPointer;
- Fiber->FiberContext.ContextFlags = CONTEXT_FULL;
- /* Save FPU State if requested */
- if (dwFlags & FIBER_FLAG_FLOAT_SWITCH)
- {
Fiber->FiberContext.ContextFlags |= CONTEXT_FLOATING_POINT;- }
- /* Save FPU State if requested, otherwise just the basic registers */
- Fiber->FiberContext.ContextFlags = (dwFlags &
FIBER_FLAG_FLOAT_SWITCH) ?
(CONTEXT_FULL |CONTEXT_FLOATING_POINT) :
CONTEXT_FULL;/* Associate the fiber to the current thread */ Teb->NtTib.FiberData = Fiber;
@@ -135,10 +137,11 @@ */ LPVOID WINAPI -ConvertThreadToFiber(LPVOID lpParameter) +ConvertThreadToFiber(_In_opt_ LPVOID lpParameter) { /* Call the newer function */
- return ConvertThreadToFiberEx(lpParameter, 0);
- return ConvertThreadToFiberEx(lpParameter,
0);}
/* @@ -146,12 +149,16 @@ */ LPVOID WINAPI -CreateFiber(SIZE_T dwStackSize,
LPFIBER_START_ROUTINE lpStartAddress,LPVOID lpParameter)+CreateFiber(_In_ SIZE_T dwStackSize,
_In_ LPFIBER_START_ROUTINE lpStartAddress,_In_opt_ LPVOID lpParameter){ /* Call the Newer Function */
- return CreateFiberEx(dwStackSize, 0, 0, lpStartAddress, lpParameter);
- return CreateFiberEx(dwStackSize,
0,0,lpStartAddress,lpParameter);}
/* @@ -159,20 +166,20 @@ */ LPVOID WINAPI -CreateFiberEx(SIZE_T dwStackCommitSize,
SIZE_T dwStackReserveSize,DWORD dwFlags,LPFIBER_START_ROUTINE lpStartAddress,LPVOID lpParameter)+CreateFiberEx(_In_ SIZE_T dwStackCommitSize,
_In_ SIZE_T dwStackReserveSize,_In_ DWORD dwFlags,_In_ LPFIBER_START_ROUTINE lpStartAddress,_In_opt_ LPVOID lpParameter){ PFIBER Fiber; NTSTATUS Status; INITIAL_TEB InitialTeb;
- PACTIVATION_CONTEXT_STACK ActivationContextStackPointer = NULL;
PACTIVATION_CONTEXT_STACK ActivationContextStackPointer; DPRINT("Creating Fiber\n");
/* Check for invalid flags */
- if (dwFlags &~ FIBER_FLAG_FLOAT_SWITCH)
- if (dwFlags & ~FIBER_FLAG_FLOAT_SWITCH) { /* Fail */ SetLastError(ERROR_INVALID_PARAMETER);
@@ -180,6 +187,7 @@ }
/* Allocate the Activation Context Stack */
- ActivationContextStackPointer = NULL; Status =
RtlAllocateActivationContextStack(&ActivationContextStackPointer); if (!NT_SUCCESS(Status)) { @@ -189,7 +197,9 @@ }
/* Allocate the fiber */
- Fiber = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(FIBER));
- Fiber = RtlAllocateHeap(RtlGetProcessHeap(),
0, if (!Fiber) { /* Free the activation context stack */sizeof(FIBER));@@ -208,7 +218,9 @@ if (!NT_SUCCESS(Status)) { /* Free the fiber */
RtlFreeHeap(GetProcessHeap(), 0, Fiber);
RtlFreeHeap(GetProcessHeap(),0,Fiber); /* Free the activation context stack */ RtlFreeActivationContextStack(ActivationContextStackPointer);@@ -219,7 +231,8 @@ }
/* Clear the context */
- RtlZeroMemory(&Fiber->FiberContext, sizeof(CONTEXT));
RtlZeroMemory(&Fiber->FiberContext,
sizeof(CONTEXT));/* Copy the data into the fiber */ Fiber->StackBase = InitialTeb.StackBase;
@@ -230,12 +243,13 @@ Fiber->GuaranteedStackBytes = 0; Fiber->FlsData = NULL; Fiber->ActivationContextStackPointer = ActivationContextStackPointer;
- Fiber->FiberContext.ContextFlags = CONTEXT_FULL;
- /* Save FPU State if requested */
- Fiber->FiberContext.ContextFlags = (dwFlags &
FIBER_FLAG_FLOAT_SWITCH) ? CONTEXT_FLOATING_POINT : 0;
- /* initialize the context for the fiber */
- /* Save FPU State if requested, otherwise just the basic registers */
- Fiber->FiberContext.ContextFlags = (dwFlags &
FIBER_FLAG_FLOAT_SWITCH) ?
(CONTEXT_FULL |CONTEXT_FLOATING_POINT) :
CONTEXT_FULL;- /* Initialize the context for the fiber */ BaseInitializeContext(&Fiber->FiberContext, lpParameter, lpStartAddress,
@@ -251,17 +265,24 @@ */ VOID WINAPI -DeleteFiber(LPVOID lpFiber) -{
- SIZE_T Size = 0;
- PFIBER Fiber = (PFIBER)lpFiber;
+DeleteFiber(_In_ LPVOID lpFiber) +{
- SIZE_T Size;
- PFIBER Fiber; PTEB Teb;
- /* First, exit the thread */
- /* Are we deleting ourselves? */ Teb = NtCurrentTeb();
- if ((Teb->HasFiberData) && (Teb->NtTib.FiberData == Fiber))
ExitThread(1);
- /* Now de-allocate the stack */
- Fiber = (PFIBER)lpFiber;
- if ((Teb->HasFiberData) &&
(Teb->NtTib.FiberData == Fiber))- {
/* Just exit */ExitThread(1);- }
- /* Not ourselves, de-allocate the stack */
- Size = 0 ; NtFreeVirtualMemory(NtCurrentProcess(), &Fiber->DeallocationStack, &Size,
@@ -274,7 +295,9 @@ RtlFreeActivationContextStack(Fiber->ActivationContextStackPointer);
/* Free the fiber data */
- RtlFreeHeap(GetProcessHeap(), 0, lpFiber);
- RtlFreeHeap(GetProcessHeap(),
0,lpFiber);}
/* @@ -284,6 +307,7 @@ WINAPI IsThreadAFiber(VOID) {
- /* Return flag in the TEB */ return NtCurrentTeb()->HasFiberData;
}
@@ -349,7 +373,8 @@ */ BOOL WINAPI -FlsSetValue(DWORD dwFlsIndex, PVOID lpFlsData) +FlsSetValue(DWORD dwFlsIndex,
PVOID lpFlsData){ PVOID *ppFlsSlots; TEB *pTeb = NtCurrentTeb();
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] Thu Oct 8 16:26:29 2015 @@ -15,21 +15,26 @@ .code
PUBLIC _BaseFiberStartup@0 -.PROC _BaseFiberStartup@0
- /* Frame pointer is zeroed */
+FUNC _BaseFiberStartup@0 FPO 0, 0, 0, 0, 0, FRAME_FPO
/* Note that EBP is already zeroed for us during fiber creation */
/* Get the fiber data */ mov eax, fs:[TEB_FIBER_DATA]
- push dword ptr [eax+FIBER_CONTEXT_EBX] /* Parameter */
- push dword ptr [eax+FIBER_CONTEXT_EAX] /* Start Address */
- call _BaseThreadStartup@8
-.ENDP
- /* Start the thread with our parameters */
- push dword ptr [eax+FIBER_CONTEXT_EBX]
- push dword ptr [eax+FIBER_CONTEXT_EAX]
- jmp _BaseThreadStartup@8
+ENDFUNC
PUBLIC _SwitchToFiber@4 -_SwitchToFiber@4: +FUNC _SwitchToFiber@4
- FPO 0, 0, 0, 0, 0, FRAME_FPO
- /* Get the TEB */ mov edx, fs:[TEB_SELF]
@@ -51,7 +56,7 @@ fnstcw [eax+FIBER_CONTEXT_FLOAT_SAVE_CONTROL_WORD]
/* Check if the CPU supports SIMD MXCSR State Save */
- cmp byte ptr ds:[PF_XMMI_INSTRUCTIONS_AVAILABLE], 1
- cmp byte ptr ds:[USER_SHARED_DATA +
USER_SHARED_DATA_PROCESSOR_FEATURES + PF_XMMI_INSTRUCTIONS_AVAILABLE], 1 jnz NoFpuStateSave stmxcsr [eax+FIBER_CONTEXT_DR6]
@@ -109,13 +114,13 @@ StatusWordChanged:
/* Load the new one */
- mov word ptr [ecx+FIBER_CONTEXT_FLOAT_SAVE_TAG_WORD], HEX(0FFFF)
- mov word ptr [ecx+FIBER_CONTEXT_FLOAT_SAVE_TAG_WORD], HEX(FFFF) fldenv [ecx+FIBER_CONTEXT_FLOAT_SAVE_CONTROL_WORD]
ControlWordEqual:
/* Load the new one */
- cmp byte ptr ds:[PF_XMMI_INSTRUCTIONS_AVAILABLE], 1
- cmp byte ptr ds:[USER_SHARED_DATA +
USER_SHARED_DATA_PROCESSOR_FEATURES + PF_XMMI_INSTRUCTIONS_AVAILABLE], 1 jnz NoFpuStateRestore ldmxcsr [ecx+FIBER_CONTEXT_DR6]
@@ -136,6 +141,7 @@ mov esp, [ecx+FIBER_CONTEXT_ESP] ret 4
+ENDFUNC
END /* EOF */
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] Thu Oct 8 16:26:29 2015 @@ -548,7 +548,7 @@
/* Is FPU state required? */ Context->ContextFlags |= ContextFlags;
if (ContextFlags == CONTEXT_FLOATING_POINT)
if ((ContextFlags & CONTEXT_FLOATING_POINT) ==CONTEXT_FLOATING_POINT) { /* Set an initial state */ Context->FloatSave.ControlWord = 0x27F;
Modified: trunk/reactos/include/asm/ks386.template.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/asm/ks386.template....
============================================================================== --- trunk/reactos/include/asm/ks386.template.h [iso-8859-1] (original) +++ trunk/reactos/include/asm/ks386.template.h [iso-8859-1] Thu Oct 8 16:26:29 2015 @@ -724,17 +724,20 @@
HEADER("TEB"), OFFSET(TEB_EXCEPTION_LIST, TEB, NtTib.ExceptionList), +OFFSET(TEB_STACK_BASE, TEB, NtTib.StackBase), OFFSET(TEB_STACK_LIMIT, TEB, NtTib.StackLimit), -OFFSET(TEB_STACK_BASE, TEB, NtTib.StackBase), +OFFSET(TEB_FIBER_DATA, TEB, NtTib.FiberData), OFFSET(TEB_SELF, TEB, NtTib.Self), -OFFSET(TEB_FIBER_DATA, TEB, NtTib.FiberData), OFFSET(TEB_PEB, TEB, ProcessEnvironmentBlock), OFFSET(TEB_EXCEPTION_CODE, TEB, ExceptionCode), +OFFSET(TEB_ACTIVATION_CONTEXT_STACK_POINTER, TEB, ActivationContextStackPointer), +OFFSET(TEB_DEALLOCATION_STACK, TEB, DeallocationStack), +OFFSET(TEB_GDI_BATCH_COUNT, TEB, GdiBatchCount), +OFFSET(TEB_GUARANTEED_STACK_BYTES, TEB, GuaranteedStackBytes), +OFFSET(TEB_FLS_DATA, TEB, FlsData),
+HEADER("PEB"), OFFSET(PEB_KERNEL_CALLBACK_TABLE, PEB, KernelCallbackTable), -OFFSET(TEB_FLS_DATA, TEB, FlsData), -OFFSET(TEB_ACTIVATION_CONTEXT_STACK_POINTER, TEB, ActivationContextStackPointer), -OFFSET(TEB_GUARANTEED_STACK_BYTES, TEB, GuaranteedStackBytes), -OFFSET(TEB_DEALLOCATION_STACK, TEB, DeallocationStack),
HEADER("Misc"), CONSTANT(NPX_FRAME_LENGTH), @@ -754,4 +757,6 @@ CONSTANT(CONTEXT_ALIGNED_SIZE), CONSTANT(PROCESSOR_FEATURE_FXSR), CONSTANT(KUSER_SHARED_SYSCALL_RET),
+CONSTANT(USER_SHARED_DATA), +CONSTANT(USER_SHARED_DATA_PROCESSOR_FEATURES),
Modified: trunk/reactos/include/ndk/i386/asm.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/i386/asm.h?rev=...
============================================================================== --- trunk/reactos/include/ndk/i386/asm.h [iso-8859-1] (original) +++ trunk/reactos/include/ndk/i386/asm.h [iso-8859-1] Thu Oct 8 16:26:29 2015 @@ -315,13 +315,14 @@ #define FRAME_EDITED 0xFFF8
// -// KUSER_SHARED_DATA Offsets +// USER_SHARED_DATA Offsets // #ifdef __ASM__ #define USER_SHARED_DATA 0xFFDF0000 #endif #define USER_SHARED_DATA_INTERRUPT_TIME 0x8 #define USER_SHARED_DATA_SYSTEM_TIME 0x14 +#define USER_SHARED_DATA_PROCESSOR_FEATURES 0x274 #define USER_SHARED_DATA_TICK_COUNT 0x320
//