From 0feb759f621ea76ccebbd1e361a9a8854a466458 Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Mon, 11 Jan 2010 18:26:46 +0000 Subject: [PATCH] [NTOS]: Switch to a slightly (perhaps, hopefully?) safer version of V86 entry/exit to see if this fixes the buildbot boot (suffice it to say, the original code works fine on my test machine, but since half the developers seem to be using GCC 4.4 and the others GCC 4.1, I wouldn't be surprised if there's compiler subtleties involved). svn path=/trunk/; revision=45046 --- reactos/ntoskrnl/include/internal/i386/ke.h | 7 ++++++- reactos/ntoskrnl/ke/i386/ctxswitch.S | 15 ++++++++++++++- reactos/ntoskrnl/ke/i386/traphdlr.c | 4 ++-- reactos/ntoskrnl/ke/i386/v86vdm.c | 10 ++++------ 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/reactos/ntoskrnl/include/internal/i386/ke.h b/reactos/ntoskrnl/include/internal/i386/ke.h index 3bfe15f0c9e..533bf4b0d59 100644 --- a/reactos/ntoskrnl/include/internal/i386/ke.h +++ b/reactos/ntoskrnl/include/internal/i386/ke.h @@ -411,6 +411,12 @@ KiEoiHelper( VOID FASTCALL +Ki386BiosCallReturnAddress( + IN PKTRAP_FRAME TrapFrame +); + +ULONG_PTR +FASTCALL KiExitV86Mode( IN PKTRAP_FRAME TrapFrame ); @@ -442,7 +448,6 @@ extern VOID NTAPI ExpInterlockedPopEntrySListFault(VOID); extern VOID __cdecl CopyParams(VOID); extern VOID __cdecl ReadBatch(VOID); extern VOID __cdecl FrRestore(VOID); -extern VOID Ki386BiosCallReturnAddress(VOID); PFX_SAVE_AREA FORCEINLINE diff --git a/reactos/ntoskrnl/ke/i386/ctxswitch.S b/reactos/ntoskrnl/ke/i386/ctxswitch.S index 7b3f9637849..16d14372ba9 100644 --- a/reactos/ntoskrnl/ke/i386/ctxswitch.S +++ b/reactos/ntoskrnl/ke/i386/ctxswitch.S @@ -871,6 +871,19 @@ _Ki386SetupAndExitToV86Mode@4: /* Enter V8086 mode */ pushad - call @KiEnterV86Mode@0 + sub esp, (12 + KTRAP_FRAME_LENGTH + NPX_FRAME_LENGTH) + mov ecx, esp + call @KiEnterV86Mode@4 + jmp $ .endfunc +.globl @Ki386BiosCallReturnAddress@4 +@Ki386BiosCallReturnAddress@4: + + /* Exit V8086 mode */ + call @KiExitV86Mode@4 + mov esp, eax + add esp, (12 + KTRAP_FRAME_LENGTH + NPX_FRAME_LENGTH) + popad + ret + diff --git a/reactos/ntoskrnl/ke/i386/traphdlr.c b/reactos/ntoskrnl/ke/i386/traphdlr.c index 3864e6b2596..76fb4c00126 100644 --- a/reactos/ntoskrnl/ke/i386/traphdlr.c +++ b/reactos/ntoskrnl/ke/i386/traphdlr.c @@ -1255,11 +1255,11 @@ KiTrap13Handler(IN PKTRAP_FRAME TrapFrame) * Why? Because part of the trap frame actually corresponds to the IRET * stack during the trap exit! */ - if ((TrapFrame->HardwareEsp == (ULONG)KiExitV86Mode) && + if ((TrapFrame->HardwareEsp == (ULONG)Ki386BiosCallReturnAddress) && (TrapFrame->HardwareSegSs == (KGDT_R0_CODE | RPL_MASK))) { /* Exit the V86 trap! */ - KiExitV86Mode(TrapFrame); + Ki386BiosCallReturnAddress(TrapFrame); } else { diff --git a/reactos/ntoskrnl/ke/i386/v86vdm.c b/reactos/ntoskrnl/ke/i386/v86vdm.c index d0239fd655b..6fcf72a6756 100644 --- a/reactos/ntoskrnl/ke/i386/v86vdm.c +++ b/reactos/ntoskrnl/ke/i386/v86vdm.c @@ -429,7 +429,7 @@ Ki386HandleOpcodeV86(IN PKTRAP_FRAME TrapFrame) return KiVdmHandleOpcode(TrapFrame, 1); } -VOID +ULONG_PTR FASTCALL KiExitV86Mode(IN PKTRAP_FRAME TrapFrame) { @@ -468,17 +468,15 @@ KiExitV86Mode(IN PKTRAP_FRAME TrapFrame) /* Enable interrupts and get back to protected mode */ _enable(); - KiV86TrapReturn(TrapFrame->Edi); + return TrapFrame->Edi; } VOID FASTCALL -KiEnterV86Mode(VOID) +KiEnterV86Mode(IN PKV8086_STACK_FRAME StackFrame) { PKTHREAD Thread; PKGDTENTRY GdtEntry; - KV8086_STACK_FRAME StackFrameBuffer; - PKV8086_STACK_FRAME StackFrame = &StackFrameBuffer; PKTRAP_FRAME TrapFrame = &StackFrame->TrapFrame; PKV86_FRAME V86Frame = &StackFrame->V86Frame; PFX_SAVE_AREA NpxFrame = &StackFrame->NpxArea; @@ -497,7 +495,7 @@ KiEnterV86Mode(VOID) V86Frame->PcrTeb = KeGetPcr()->Tib.Self; /* Save return EIP */ - TrapFrame->Eip = (ULONG_PTR)KiExitV86Mode; + TrapFrame->Eip = (ULONG_PTR)Ki386BiosCallReturnAddress; /* Save our stack (after the frames) */ TrapFrame->Esi = (ULONG_PTR)V86Frame;