From 2b6de7c1433de0ac775eff65b25cf2d81908e160 Mon Sep 17 00:00:00 2001 From: Hartmut Birr Date: Sat, 27 Nov 2004 16:12:26 +0000 Subject: [PATCH] - Saved the state of the fpu at a win32 call and restored the state after the call to the previous state. svn path=/trunk/; revision=11831 --- reactos/ntoskrnl/include/internal/i386/fpu.h | 3 ++ reactos/ntoskrnl/ke/i386/fpu.c | 40 +++++++++++++++++++- reactos/ntoskrnl/ps/w32call.c | 33 +++++++--------- 3 files changed, 55 insertions(+), 21 deletions(-) diff --git a/reactos/ntoskrnl/include/internal/i386/fpu.h b/reactos/ntoskrnl/include/internal/i386/fpu.h index 14475e2b43b..5362edee314 100644 --- a/reactos/ntoskrnl/include/internal/i386/fpu.h +++ b/reactos/ntoskrnl/include/internal/i386/fpu.h @@ -78,6 +78,9 @@ KiFloatingSaveAreaToFxSaveArea(PFX_SAVE_AREA FxSaveArea, CONST FLOATING_SAVE_ARE BOOL KiContextToFxSaveArea(PFX_SAVE_AREA FxSaveArea, PCONTEXT Context); +VOID +KiClearFloatingPointState(BOOLEAN Save); + #endif /* !__ASM__ */ #endif /* __NTOSKRNL_INCLUDE_INTERNAL_I386_FPU_H */ diff --git a/reactos/ntoskrnl/ke/i386/fpu.c b/reactos/ntoskrnl/ke/i386/fpu.c index 62da935ac94..3dd2d53800a 100644 --- a/reactos/ntoskrnl/ke/i386/fpu.c +++ b/reactos/ntoskrnl/ke/i386/fpu.c @@ -1,4 +1,4 @@ -/* $Id: fpu.c,v 1.17 2004/11/25 13:22:54 blight Exp $ +/* $Id: fpu.c,v 1.18 2004/11/27 16:12:26 hbirr Exp $ * * ReactOS kernel * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team @@ -403,6 +403,44 @@ KeRestoreFloatingPointState(IN PKFLOATING_SAVE Save) return STATUS_SUCCESS; } +VOID +KiClearFloatingPointState(BOOLEAN Save) +{ + PKTHREAD CurrentThread; + PFX_SAVE_AREA FxSaveArea; + + ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL); + + CurrentThread = KeGetCurrentThread(); + + if (CurrentThread->NpxState & NPX_STATE_DIRTY) + { + if (Save) + { + FxSaveArea = (PFX_SAVE_AREA)((char *)CurrentThread->InitialStack - sizeof (FX_SAVE_AREA)); + if (FxsrSupport) + { + asm volatile("fxsave %0" : : "m"(FxSaveArea->U.FxArea)); + } + else + { + asm volatile("fnsave %0" : : "m"(FxSaveArea->U.FnArea)); + } + CurrentThread->NpxState = NPX_STATE_VALID; + } + else + { + CurrentThread->NpxState = NPX_STATE_INVALID; + } + Ke386SetCr0(Ke386GetCr0() | X86_CR0_TS); + } + if (KeGetCurrentKPCR()->PrcbData.NpxThread == CurrentThread) + { + KeGetCurrentKPCR()->PrcbData.NpxThread = NULL; + } +} + + NTSTATUS KiHandleFpuFault(PKTRAP_FRAME Tf, ULONG ExceptionNr) { diff --git a/reactos/ntoskrnl/ps/w32call.c b/reactos/ntoskrnl/ps/w32call.c index 386c1d99794..62ba1d20a2a 100644 --- a/reactos/ntoskrnl/ps/w32call.c +++ b/reactos/ntoskrnl/ps/w32call.c @@ -1,4 +1,4 @@ -/* $Id: w32call.c,v 1.18 2004/11/20 23:46:37 blight Exp $ +/* $Id: w32call.c,v 1.19 2004/11/27 16:12:26 hbirr Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -45,6 +45,7 @@ typedef struct _NTW32CALL_SAVED_STATE PKTRAP_FRAME SavedTrapFrame; PVOID SavedCallbackStack; PVOID SavedExceptionStack; + BYTE SavedNpxState; } NTW32CALL_SAVED_STATE, *PNTW32CALL_SAVED_STATE; typedef struct @@ -83,6 +84,7 @@ NtCallbackReturn (PVOID Result, PKTRAP_FRAME SavedTrapFrame; PVOID SavedCallbackStack; PVOID SavedExceptionStack; + BYTE SavedNpxState; Thread = PsGetCurrentThread(); if (Thread->Tcb.CallbackStack == NULL) @@ -105,7 +107,7 @@ NtCallbackReturn (PVOID Result, SavedTrapFrame = State->SavedTrapFrame; SavedCallbackStack = State->SavedCallbackStack; SavedExceptionStack = State->SavedExceptionStack; - + SavedNpxState = State->SavedNpxState; /* * Copy the callback status and the callback result to NtW32Call */ @@ -127,20 +129,14 @@ NtCallbackReturn (PVOID Result, * Restore the old stack. */ KeRaiseIrql(HIGH_LEVEL, &oldIrql); - if ((Thread->Tcb.NpxState & NPX_STATE_VALID) && - ETHREAD_TO_KTHREAD(Thread) != KeGetCurrentKPCR()->PrcbData.NpxThread) - { - memcpy((char*)InitialStack - sizeof(FX_SAVE_AREA), - (char*)Thread->Tcb.InitialStack - sizeof(FX_SAVE_AREA), - sizeof(FX_SAVE_AREA)); - } + KiClearFloatingPointState(FALSE); + Thread->Tcb.NpxState = SavedNpxState; Thread->Tcb.InitialStack = InitialStack; Thread->Tcb.StackBase = StackBase; Thread->Tcb.StackLimit = StackLimit; Thread->Tcb.TrapFrame = SavedTrapFrame; Thread->Tcb.CallbackStack = SavedCallbackStack; KeGetCurrentKPCR()->TSS->Esp0 = (ULONG)SavedExceptionStack; - Ke386SetCr0(Ke386GetCr0() | X86_CR0_TS); /* set TS */ KeStackSwitchAndRet((PVOID)(OldStack + 1)); /* Should never return. */ @@ -243,6 +239,7 @@ PsAllocateCallbackStack(ULONG StackSize) } return(NULL); } + DPRINT1("KernelStack %x\n", KernelStack); return(KernelStack); } @@ -288,9 +285,7 @@ NtW32Call (IN ULONG RoutineIndex, AssignedStack = CONTAINING_RECORD(StackEntry, NTW32CALL_CALLBACK_STACK, ListEntry); NewStack = AssignedStack->BaseAddress; - - MmUpdatePageDir(PsGetCurrentProcess(), NewStack, StackSize); - + memset(NewStack, 0, StackSize); } /* FIXME: Need to check whether we were interrupted from v86 mode. */ memcpy((char*)NewStack + StackSize - sizeof(KTRAP_FRAME) - sizeof(FX_SAVE_AREA), @@ -316,17 +311,15 @@ NtW32Call (IN ULONG RoutineIndex, SavedState.SavedTrapFrame = Thread->Tcb.TrapFrame; SavedState.SavedCallbackStack = Thread->Tcb.CallbackStack; SavedState.SavedExceptionStack = (PVOID)KeGetCurrentKPCR()->TSS->Esp0; - if ((Thread->Tcb.NpxState & NPX_STATE_VALID) && - ETHREAD_TO_KTHREAD(Thread) != KeGetCurrentKPCR()->PrcbData.NpxThread) - { - memcpy((char*)NewStack + StackSize - sizeof(FX_SAVE_AREA), - (char*)SavedState.SavedInitialStack - sizeof(FX_SAVE_AREA), - sizeof(FX_SAVE_AREA)); - } + + KiClearFloatingPointState(TRUE); + + SavedState.SavedNpxState = Thread->Tcb.NpxState; Thread->Tcb.InitialStack = Thread->Tcb.StackBase = (char*)NewStack + StackSize; Thread->Tcb.StackLimit = (ULONG)NewStack; Thread->Tcb.KernelStack = (char*)NewStack + StackSize - sizeof(KTRAP_FRAME) - sizeof(FX_SAVE_AREA); KeGetCurrentKPCR()->TSS->Esp0 = (ULONG)Thread->Tcb.InitialStack - sizeof(FX_SAVE_AREA); + Thread->Tcb.NpxState = NPX_STATE_INVALID; KePushAndStackSwitchAndSysRet((ULONG)&SavedState, Thread->Tcb.KernelStack); /*