[NTOS:KE]

- When switching to VM86 mode, ensure a 16 byte aligned floating point save area.
CORE-7581 #resolve

svn path=/trunk/; revision=62736
This commit is contained in:
Thomas Faber 2014-04-13 12:04:13 +00:00
parent 6d83ec90e4
commit d585b0d8e5
3 changed files with 13 additions and 6 deletions

View file

@ -557,6 +557,7 @@ FORCEINLINE
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));
}

View file

@ -143,7 +143,7 @@ _Ki386SetupAndExitToV86Mode@4:
/* 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 @@ PUBLIC @Ki386BiosCallReturnAddress@4
/* 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

View file

@ -465,6 +465,7 @@ ULONG_PTR
FASTCALL
KiExitV86Mode(IN PKTRAP_FRAME TrapFrame)
{
ULONG_PTR StackFrameUnaligned;
PKV8086_STACK_FRAME StackFrame;
PKTHREAD Thread;
PKTRAP_FRAME PmTrapFrame;
@ -472,10 +473,12 @@ KiExitV86Mode(IN PKTRAP_FRAME TrapFrame)
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,18 +496,21 @@ KiExitV86Mode(IN PKTRAP_FRAME TrapFrame)
/* 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;
TrapFrame->SegEs = TrapFrame->SegDs = TrapFrame->SegFs = TrapFrame->SegGs = 0;
@ -522,7 +528,7 @@ KiEnterV86Mode(IN PKV8086_STACK_FRAME StackFrame)
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 */