How did our Fiber tests ever pass? Best regards, Alex Ionescu
On Thu, Oct 8, 2015 at 9:26 AM, <sginsb...@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/fiber.c?rev=69466&r1=69465&r2=69466&view=diff > > ============================================================================== > --- 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, > + sizeof(FIBER)); > if (!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, > + sizeof(FIBER)); > if (!Fiber) > { > /* Free the activation context stack */ > @@ -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/i386/fiber.S?rev=69466&r1=69465&r2=69466&view=diff > > ============================================================================== > --- 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/utils.c?rev=69466&r1=69465&r2=69466&view=diff > > ============================================================================== > --- 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.h?rev=69466&r1=69465&r2=69466&view=diff > > ============================================================================== > --- 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=69466&r1=69465&r2=69466&view=diff > > ============================================================================== > --- 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 > > // > > >
_______________________________________________ Ros-dev mailing list Ros-dev@reactos.org http://www.reactos.org/mailman/listinfo/ros-dev