Fix KiGetFpuState() - Thanks to Hartmut for finding this bug and testing the patch.

svn path=/trunk/; revision=18300
This commit is contained in:
Gregor Anich 2005-10-06 20:34:20 +00:00
parent d004682a00
commit ff9641a734

View file

@ -326,6 +326,7 @@ KiGetFpuState(PKTHREAD Thread)
{ {
PFX_SAVE_AREA FxSaveArea = NULL; PFX_SAVE_AREA FxSaveArea = NULL;
KIRQL OldIrql; KIRQL OldIrql;
ULONG Cr0;
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
if (Thread->NpxState & NPX_STATE_VALID) if (Thread->NpxState & NPX_STATE_VALID)
@ -334,16 +335,19 @@ KiGetFpuState(PKTHREAD Thread)
if (Thread->NpxState & NPX_STATE_DIRTY) if (Thread->NpxState & NPX_STATE_DIRTY)
{ {
ASSERT(KeGetCurrentPrcb()->NpxThread == Thread); ASSERT(KeGetCurrentPrcb()->NpxThread == Thread);
ASSERT((Ke386GetCr0() & X86_CR0_TS) == 0);
Cr0 = Ke386GetCr0();
asm volatile("clts");
if (FxsrSupport) if (FxsrSupport)
asm volatile("fxsave %0" : : "m"(FxSaveArea->U.FxArea)); asm volatile("fxsave %0" : : "m"(FxSaveArea->U.FxArea));
else else
{ {
KeGetCurrentPrcb()->NpxThread = NULL;
asm volatile("fnsave %0" : : "m"(FxSaveArea->U.FnArea)); asm volatile("fnsave %0" : : "m"(FxSaveArea->U.FnArea));
Ke386SetCr0(Ke386GetCr0() | X86_CR0_TS); /* FPU state has to be reloaded because fnsave changes it. */ /* FPU state has to be reloaded because fnsave changes it. */
Cr0 |= X86_CR0_TS;
KeGetCurrentPrcb()->NpxThread = NULL;
} }
Ke386SetCr0(Cr0);
Thread->NpxState = NPX_STATE_VALID; Thread->NpxState = NPX_STATE_VALID;
} }
} }