Author: tfaber Date: Sun Apr 13 12:04:13 2014 New Revision: 62736
URL: http://svn.reactos.org/svn/reactos?rev=62736&view=rev Log: [NTOS:KE] - When switching to VM86 mode, ensure a 16 byte aligned floating point save area. CORE-7581 #resolve
Modified: trunk/reactos/ntoskrnl/include/internal/i386/ke.h trunk/reactos/ntoskrnl/ke/i386/ctxswitch.S trunk/reactos/ntoskrnl/ke/i386/v86vdm.c
Modified: trunk/reactos/ntoskrnl/include/internal/i386/ke.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/i... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/i386/ke.h [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/include/internal/i386/ke.h [iso-8859-1] Sun Apr 13 12:04:13 2014 @@ -557,6 +557,7 @@ PFX_SAVE_AREA KiGetThreadNpxArea(IN PKTHREAD Thread) { + ASSERT((ULONG_PTR)Thread->InitialStack % 16 == 0); return (PFX_SAVE_AREA)((ULONG_PTR)Thread->InitialStack - sizeof(FX_SAVE_AREA)); }
Modified: trunk/reactos/ntoskrnl/ke/i386/ctxswitch.S URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/ctxswitch.... ============================================================================== --- trunk/reactos/ntoskrnl/ke/i386/ctxswitch.S [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ke/i386/ctxswitch.S [iso-8859-1] Sun Apr 13 12:04:13 2014 @@ -143,7 +143,7 @@
/* Enter V8086 mode */ pushad - sub esp, (12 + KTRAP_FRAME_LENGTH + NPX_FRAME_LENGTH) + sub esp, (12 + KTRAP_FRAME_LENGTH + NPX_FRAME_LENGTH + 16) mov ecx, esp call @KiEnterV86Mode@4 jmp $ @@ -155,7 +155,7 @@ /* Exit V8086 mode */ call @KiExitV86Mode@4 mov esp, eax - add esp, (12 + KTRAP_FRAME_LENGTH + NPX_FRAME_LENGTH) + add esp, (12 + KTRAP_FRAME_LENGTH + NPX_FRAME_LENGTH + 16) popad ret 4
Modified: trunk/reactos/ntoskrnl/ke/i386/v86vdm.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/v86vdm.c?r... ============================================================================== --- trunk/reactos/ntoskrnl/ke/i386/v86vdm.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ke/i386/v86vdm.c [iso-8859-1] Sun Apr 13 12:04:13 2014 @@ -465,6 +465,7 @@ FASTCALL KiExitV86Mode(IN PKTRAP_FRAME TrapFrame) { + ULONG_PTR StackFrameUnaligned; PKV8086_STACK_FRAME StackFrame; PKTHREAD Thread; PKTRAP_FRAME PmTrapFrame; @@ -472,10 +473,12 @@ PFX_SAVE_AREA NpxFrame;
/* Get the stack frame back */ - StackFrame = CONTAINING_RECORD(TrapFrame->Esi, KV8086_STACK_FRAME, V86Frame); + StackFrameUnaligned = TrapFrame->Esi; + StackFrame = (PKV8086_STACK_FRAME)(ROUND_UP(StackFrameUnaligned - 4, 16) + 4); PmTrapFrame = &StackFrame->TrapFrame; V86Frame = &StackFrame->V86Frame; NpxFrame = &StackFrame->NpxArea; + ASSERT((ULONG_PTR)NpxFrame % 16 == 0);
/* Copy the FPU frame back */ Thread = KeGetCurrentThread(); @@ -493,17 +496,20 @@
/* Enable interrupts and return a pointer to the trap frame */ _enable(); - return (ULONG)PmTrapFrame; + return StackFrameUnaligned; }
VOID FASTCALL -KiEnterV86Mode(IN PKV8086_STACK_FRAME StackFrame) +KiEnterV86Mode(IN ULONG_PTR StackFrameUnaligned) { PKTHREAD Thread; + PKV8086_STACK_FRAME StackFrame = (PKV8086_STACK_FRAME)(ROUND_UP(StackFrameUnaligned - 4, 16) + 4); PKTRAP_FRAME TrapFrame = &StackFrame->TrapFrame; PKV86_FRAME V86Frame = &StackFrame->V86Frame; PFX_SAVE_AREA NpxFrame = &StackFrame->NpxArea; + + ASSERT((ULONG_PTR)NpxFrame % 16 == 0);
/* Build fake user-mode trap frame */ TrapFrame->SegCs = KGDT_R0_CODE | RPL_MASK; @@ -522,7 +528,7 @@ TrapFrame->Eip = (ULONG_PTR)Ki386BiosCallReturnAddress;
/* Save our stack (after the frames) */ - TrapFrame->Esi = (ULONG_PTR)V86Frame; + TrapFrame->Esi = StackFrameUnaligned; TrapFrame->Edi = (ULONG_PTR)_AddressOfReturnAddress() + 4;
/* Sanitize EFlags and enable interrupts */