Skip to content

Commit d585b0d

Browse files
committed
[NTOS:KE]
- When switching to VM86 mode, ensure a 16 byte aligned floating point save area. CORE-7581 #resolve svn path=/trunk/; revision=62736
1 parent 6d83ec9 commit d585b0d

File tree

3 files changed

+13
-6
lines changed

3 files changed

+13
-6
lines changed

reactos/ntoskrnl/include/internal/i386/ke.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,7 @@ FORCEINLINE
557557
PFX_SAVE_AREA
558558
KiGetThreadNpxArea(IN PKTHREAD Thread)
559559
{
560+
ASSERT((ULONG_PTR)Thread->InitialStack % 16 == 0);
560561
return (PFX_SAVE_AREA)((ULONG_PTR)Thread->InitialStack - sizeof(FX_SAVE_AREA));
561562
}
562563

reactos/ntoskrnl/ke/i386/ctxswitch.S

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ _Ki386SetupAndExitToV86Mode@4:
143143

144144
/* Enter V8086 mode */
145145
pushad
146-
sub esp, (12 + KTRAP_FRAME_LENGTH + NPX_FRAME_LENGTH)
146+
sub esp, (12 + KTRAP_FRAME_LENGTH + NPX_FRAME_LENGTH + 16)
147147
mov ecx, esp
148148
call @KiEnterV86Mode@4
149149
jmp $
@@ -155,7 +155,7 @@ PUBLIC @Ki386BiosCallReturnAddress@4
155155
/* Exit V8086 mode */
156156
call @KiExitV86Mode@4
157157
mov esp, eax
158-
add esp, (12 + KTRAP_FRAME_LENGTH + NPX_FRAME_LENGTH)
158+
add esp, (12 + KTRAP_FRAME_LENGTH + NPX_FRAME_LENGTH + 16)
159159
popad
160160
ret 4
161161

reactos/ntoskrnl/ke/i386/v86vdm.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -465,17 +465,20 @@ ULONG_PTR
465465
FASTCALL
466466
KiExitV86Mode(IN PKTRAP_FRAME TrapFrame)
467467
{
468+
ULONG_PTR StackFrameUnaligned;
468469
PKV8086_STACK_FRAME StackFrame;
469470
PKTHREAD Thread;
470471
PKTRAP_FRAME PmTrapFrame;
471472
PKV86_FRAME V86Frame;
472473
PFX_SAVE_AREA NpxFrame;
473474

474475
/* Get the stack frame back */
475-
StackFrame = CONTAINING_RECORD(TrapFrame->Esi, KV8086_STACK_FRAME, V86Frame);
476+
StackFrameUnaligned = TrapFrame->Esi;
477+
StackFrame = (PKV8086_STACK_FRAME)(ROUND_UP(StackFrameUnaligned - 4, 16) + 4);
476478
PmTrapFrame = &StackFrame->TrapFrame;
477479
V86Frame = &StackFrame->V86Frame;
478480
NpxFrame = &StackFrame->NpxArea;
481+
ASSERT((ULONG_PTR)NpxFrame % 16 == 0);
479482

480483
/* Copy the FPU frame back */
481484
Thread = KeGetCurrentThread();
@@ -493,18 +496,21 @@ KiExitV86Mode(IN PKTRAP_FRAME TrapFrame)
493496

494497
/* Enable interrupts and return a pointer to the trap frame */
495498
_enable();
496-
return (ULONG)PmTrapFrame;
499+
return StackFrameUnaligned;
497500
}
498501

499502
VOID
500503
FASTCALL
501-
KiEnterV86Mode(IN PKV8086_STACK_FRAME StackFrame)
504+
KiEnterV86Mode(IN ULONG_PTR StackFrameUnaligned)
502505
{
503506
PKTHREAD Thread;
507+
PKV8086_STACK_FRAME StackFrame = (PKV8086_STACK_FRAME)(ROUND_UP(StackFrameUnaligned - 4, 16) + 4);
504508
PKTRAP_FRAME TrapFrame = &StackFrame->TrapFrame;
505509
PKV86_FRAME V86Frame = &StackFrame->V86Frame;
506510
PFX_SAVE_AREA NpxFrame = &StackFrame->NpxArea;
507511

512+
ASSERT((ULONG_PTR)NpxFrame % 16 == 0);
513+
508514
/* Build fake user-mode trap frame */
509515
TrapFrame->SegCs = KGDT_R0_CODE | RPL_MASK;
510516
TrapFrame->SegEs = TrapFrame->SegDs = TrapFrame->SegFs = TrapFrame->SegGs = 0;
@@ -522,7 +528,7 @@ KiEnterV86Mode(IN PKV8086_STACK_FRAME StackFrame)
522528
TrapFrame->Eip = (ULONG_PTR)Ki386BiosCallReturnAddress;
523529

524530
/* Save our stack (after the frames) */
525-
TrapFrame->Esi = (ULONG_PTR)V86Frame;
531+
TrapFrame->Esi = StackFrameUnaligned;
526532
TrapFrame->Edi = (ULONG_PTR)_AddressOfReturnAddress() + 4;
527533

528534
/* Sanitize EFlags and enable interrupts */

0 commit comments

Comments
 (0)