CPUMRCA.asm revision 447d6c76d88201b58c0bd7b0c8621088cf428951
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync; $Id$
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync;; @file
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync; CPUM - Raw-mode Context Assembly Routines.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync;
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync; Copyright (C) 2006-2015 Oracle Corporation
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync; This file is part of VirtualBox Open Source Edition (OSE), as
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync; available from http://www.virtualbox.org. This file is free software;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync; you can redistribute it and/or modify it under the terms of the GNU
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync; General Public License (GPL) as published by the Free Software
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync; Foundation, in version 2 as it comes in the "COPYING" file of the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync;
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync;*******************************************************************************
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync;* Header Files *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync;*******************************************************************************
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync%include "VMMRC.mac"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync%include "VBox/vmm/vm.mac"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync%include "VBox/err.mac"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync%include "VBox/vmm/stam.mac"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync%include "CPUMInternal.mac"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync%include "iprt/x86.mac"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync%include "VBox/vmm/cpum.mac"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync;*******************************************************************************
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync;* External Symbols *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync;*******************************************************************************
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncextern IMPNAME(g_CPUM) ; VMM GC Builtin import
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncextern IMPNAME(g_VM) ; VMM GC Builtin import
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncextern NAME(cpumRCHandleNPAndGP) ; CPUMGC.cpp
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncextern NAME(CPUMRCAssertPreExecutionSanity)
e11fe099decbb0f65cfcc7e2939fa00bacefbb1cvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync; Enables write protection of Hypervisor memory pages.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync; !note! Must be commented out for Trap8 debug handler.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync%define ENABLE_WRITE_PROTECTION 1
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncBEGINCODE
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync;;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync; Handles lazy FPU saving and restoring.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync; This handler will implement lazy fpu (sse/mmx/stuff) saving.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync; Two actions may be taken in this handler since the Guest OS may
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync; be doing lazy fpu switching. So, we'll have to generate those
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync; traps which the Guest CPU CTX shall have according to the
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync; its CR0 flags. If no traps for the Guest OS, we'll save the host
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync; context and restore the guest context.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync; @returns 0 if caller should continue execution.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync; @returns VINF_EM_RAW_GUEST_TRAP if a guest trap should be generated.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync; @param pCPUMCPU x86:[esp+4] gcc:rdi msc:rcx CPUMCPU pointer
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncalign 16
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncBEGINPROC cpumHandleLazyFPUAsm
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync push ebx
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync push esi
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mov ebx, [esp + 4]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync%define pCpumCpu ebx
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync%define pXState esi
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ; Figure out what to do.
cfb3a8ae5e9668de4506cf5c053b8009bcc89dafvboxsync ;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ; There are two basic actions:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ; 1. Save host fpu and restore guest fpu.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ; 2. Generate guest trap.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ;
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync ; When entering the hypervisor we'll always enable MP (for proper wait
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ; trapping) and TS (for intercepting all fpu/mmx/sse stuff). The EM flag
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync ; is taken from the guest OS in order to get proper SSE handling.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ;
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync ; Actions taken depending on the guest CR0 flags:
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync ;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ; 3 2 1
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync ; TS | EM | MP | FPUInstr | WAIT :: VMM Action
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync ; ------------------------------------------------------------------------
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync ; 0 | 0 | 0 | Exec | Exec :: Clear TS & MP, Save HC, Load GC.
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync ; 0 | 0 | 1 | Exec | Exec :: Clear TS, Save HC, Load GC.
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync ; 0 | 1 | 0 | #NM | Exec :: Clear TS & MP, Save HC, Load GC;
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync ; 0 | 1 | 1 | #NM | Exec :: Clear TS, Save HC, Load GC.
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync ; 1 | 0 | 0 | #NM | Exec :: Clear MP, Save HC, Load GC. (EM is already cleared.)
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync ; 1 | 0 | 1 | #NM | #NM :: Go to host taking trap there.
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync ; 1 | 1 | 0 | #NM | Exec :: Clear MP, Save HC, Load GC. (EM is already set.)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ; 1 | 1 | 1 | #NM | #NM :: Go to host taking trap there.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync ;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ; Before taking any of these actions we're checking if we have already
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ; loaded the GC FPU. Because if we have, this is an trap for the guest - raw ring-3.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ;
05406988cc320ac1b0971de976b6cf0c986044a9vboxsync test dword [pCpumCpu + CPUMCPU.fUseFlags], CPUM_USED_FPU
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync jz hlfpua_not_loaded
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync jmp hlfpua_guest_trap
05406988cc320ac1b0971de976b6cf0c986044a9vboxsync
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync ;
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync ; Take action.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ;
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsyncalign 16
323b78bf4831666c95416edf3b6e54657a769e5dvboxsynchlfpua_not_loaded:
05406988cc320ac1b0971de976b6cf0c986044a9vboxsync mov eax, [pCpumCpu + CPUMCPU.Guest.cr0]
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync and eax, X86_CR0_MP | X86_CR0_EM | X86_CR0_TS
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync jmp dword [eax*2 + hlfpuajmp1]
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsyncalign 16
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync;; jump table using fpu related cr0 flags as index.
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsynchlfpuajmp1:
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync RTCCPTR_DEF hlfpua_switch_fpu_ctx
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync RTCCPTR_DEF hlfpua_switch_fpu_ctx
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync RTCCPTR_DEF hlfpua_switch_fpu_ctx
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync RTCCPTR_DEF hlfpua_switch_fpu_ctx
05406988cc320ac1b0971de976b6cf0c986044a9vboxsync RTCCPTR_DEF hlfpua_switch_fpu_ctx
05406988cc320ac1b0971de976b6cf0c986044a9vboxsync RTCCPTR_DEF hlfpua_guest_trap
05406988cc320ac1b0971de976b6cf0c986044a9vboxsync RTCCPTR_DEF hlfpua_switch_fpu_ctx
05406988cc320ac1b0971de976b6cf0c986044a9vboxsync RTCCPTR_DEF hlfpua_guest_trap
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync;; and mask for cr0.
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsynchlfpu_afFlags:
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync RTCCPTR_DEF ~(X86_CR0_TS | X86_CR0_MP)
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync RTCCPTR_DEF ~(X86_CR0_TS)
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync RTCCPTR_DEF ~(X86_CR0_TS | X86_CR0_MP)
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync RTCCPTR_DEF ~(X86_CR0_TS)
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync RTCCPTR_DEF ~(X86_CR0_MP)
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync RTCCPTR_DEF 0
05406988cc320ac1b0971de976b6cf0c986044a9vboxsync RTCCPTR_DEF ~(X86_CR0_MP)
05406988cc320ac1b0971de976b6cf0c986044a9vboxsync RTCCPTR_DEF 0
05406988cc320ac1b0971de976b6cf0c986044a9vboxsync
05406988cc320ac1b0971de976b6cf0c986044a9vboxsync ;
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync ; Action - switch FPU context and change cr0 flags.
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync ;
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsyncalign 16
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsynchlfpua_switch_fpu_ctx:
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync mov ecx, cr0
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync mov edx, ecx
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync and ecx, [eax*2 + hlfpu_afFlags] ; Calc the new cr0 flags. Do NOT use ECX until we restore it!
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync and edx, ~(X86_CR0_TS | X86_CR0_EM)
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync mov cr0, edx ; Clear flags so we don't trap here.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mov pXState, [pCpumCpu + CPUMCPU.Host.pXStateRC]
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync mov eax, pCpumCpu ; Calculate the PCPUM pointer
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync sub eax, [pCpumCpu + CPUMCPU.offCPUM]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync test dword [eax + CPUM.CPUFeatures.edx], X86_CPUID_FEATURE_EDX_FXSR
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync jz short hlfpua_no_fxsave
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync fxsave [pXState]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mov pXState, [pCpumCpu + CPUMCPU.Guest.pXStateRC]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync fxrstor [pXState]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsynchlfpua_finished_switch:
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync or dword [pCpumCpu + CPUMCPU.fUseFlags], (CPUM_USED_FPU | CPUM_USED_FPU_SINCE_REM)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ; Load new CR0 value.
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync mov cr0, ecx ; load the new cr0 flags.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ; return continue execution.
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync pop esi
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pop ebx
23de3d76e5d27015e334e6ff763ab08de5969363vboxsync xor eax, eax
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync ret
23de3d76e5d27015e334e6ff763ab08de5969363vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ; Legacy CPU support.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsynchlfpua_no_fxsave:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync fnsave [pXState]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mov pXState, [pCpumCpu + CPUMCPU.Guest.pXStateRC]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mov eax, [pXState] ; control word
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync not eax ; 1 means exception ignored (6 LS bits)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync and eax, byte 03Fh ; 6 LS bits only
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync test eax, [pXState + 4] ; status word
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync jz short hlfpua_no_exceptions_pending
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ; Technically incorrect, but we certainly don't want any exceptions now!!
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync and dword [pXState + 4], ~03Fh
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsynchlfpua_no_exceptions_pending:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync frstor [pXState]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync jmp near hlfpua_finished_switch
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ;
e11fe099decbb0f65cfcc7e2939fa00bacefbb1cvboxsync ; Action - Generate Guest trap.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsynchlfpua_action_4:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsynchlfpua_guest_trap:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pop esi
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pop ebx
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync mov eax, VINF_EM_RAW_GUEST_TRAP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ret
323b78bf4831666c95416edf3b6e54657a769e5dvboxsyncENDPROC cpumHandleLazyFPUAsm
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync;;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync; Calls a guest trap/interrupt handler directly
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync; Assumes a trap stack frame has already been setup on the guest's stack!
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync;
61e80138f3c5ea5213990bde94a973c8e64d1dadvboxsync; @param pRegFrame [esp + 4] Original trap/interrupt context
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync; @param selCS [esp + 8] Code selector of handler
61e80138f3c5ea5213990bde94a973c8e64d1dadvboxsync; @param pHandler [esp + 12] GC virtual address of handler
61e80138f3c5ea5213990bde94a973c8e64d1dadvboxsync; @param eflags [esp + 16] Callee's EFLAGS
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync; @param selSS [esp + 20] Stack selector for handler
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync; @param pEsp [esp + 24] Stack address for handler
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync; @remark This call never returns!
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync; VMMRCDECL(void) CPUMGCCallGuestTrapHandler(PCPUMCTXCORE pRegFrame, uint32_t selCS, RTGCPTR pHandler, uint32_t eflags, uint32_t selSS, RTGCPTR pEsp);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncalign 16
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncBEGINPROC_EXPORTED CPUMGCCallGuestTrapHandler
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync mov ebp, esp
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ; construct iret stack frame
61e80138f3c5ea5213990bde94a973c8e64d1dadvboxsync push dword [ebp + 20] ; SS
61e80138f3c5ea5213990bde94a973c8e64d1dadvboxsync push dword [ebp + 24] ; ESP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync push dword [ebp + 16] ; EFLAGS
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync push dword [ebp + 8] ; CS
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync push dword [ebp + 12] ; EIP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
61e80138f3c5ea5213990bde94a973c8e64d1dadvboxsync ;
61e80138f3c5ea5213990bde94a973c8e64d1dadvboxsync ; enable WP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync%ifdef ENABLE_WRITE_PROTECTION
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mov eax, cr0
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync or eax, X86_CR0_WRITE_PROTECT
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mov cr0, eax
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync%endif
61e80138f3c5ea5213990bde94a973c8e64d1dadvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ; restore CPU context (all except cs, eip, ss, esp & eflags; which are restored or overwritten by iret)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mov ebp, [ebp + 4] ; pRegFrame
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mov ebx, [ebp + CPUMCTXCORE.ebx]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mov ecx, [ebp + CPUMCTXCORE.ecx]
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync mov edx, [ebp + CPUMCTXCORE.edx]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mov esi, [ebp + CPUMCTXCORE.esi]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mov edi, [ebp + CPUMCTXCORE.edi]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ;; @todo load segment registers *before* enabling WP.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync TRPM_NP_GP_HANDLER NAME(cpumRCHandleNPAndGP), CPUM_HANDLER_GS | CPUM_HANDLER_CTXCORE_IN_EBP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mov gs, [ebp + CPUMCTXCORE.gs.Sel]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync TRPM_NP_GP_HANDLER NAME(cpumRCHandleNPAndGP), CPUM_HANDLER_FS | CPUM_HANDLER_CTXCORE_IN_EBP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mov fs, [ebp + CPUMCTXCORE.fs.Sel]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync TRPM_NP_GP_HANDLER NAME(cpumRCHandleNPAndGP), CPUM_HANDLER_ES | CPUM_HANDLER_CTXCORE_IN_EBP
e11fe099decbb0f65cfcc7e2939fa00bacefbb1cvboxsync mov es, [ebp + CPUMCTXCORE.es.Sel]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync TRPM_NP_GP_HANDLER NAME(cpumRCHandleNPAndGP), CPUM_HANDLER_DS | CPUM_HANDLER_CTXCORE_IN_EBP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mov ds, [ebp + CPUMCTXCORE.ds.Sel]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mov eax, [ebp + CPUMCTXCORE.eax]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mov ebp, [ebp + CPUMCTXCORE.ebp]
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync TRPM_NP_GP_HANDLER NAME(cpumRCHandleNPAndGP), CPUM_HANDLER_IRET
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync iret
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncENDPROC CPUMGCCallGuestTrapHandler
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync;;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync; Performs an iret to V86 code
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync; Assumes a trap stack frame has already been setup on the guest's stack!
be9bc9b4ba510c4b4159c193f783d024633ef8e9vboxsync;
be9bc9b4ba510c4b4159c193f783d024633ef8e9vboxsync; @param pRegFrame Original trap/interrupt context
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync; This function does not return!
be9bc9b4ba510c4b4159c193f783d024633ef8e9vboxsync;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync;VMMRCDECL(void) CPUMGCCallV86Code(PCPUMCTXCORE pRegFrame);
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsyncalign 16
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncBEGINPROC CPUMGCCallV86Code
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mov ebp, [esp + 4] ; pRegFrame
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ; construct iret stack frame
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync push dword [ebp + CPUMCTXCORE.gs.Sel]
d8df004f4caf4f71e78f0be1cc2e2a918358ae9fvboxsync push dword [ebp + CPUMCTXCORE.fs.Sel]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync push dword [ebp + CPUMCTXCORE.ds.Sel]
7e960d3a0a8a3a84d7aba2cca45d72b1c31cc97bvboxsync push dword [ebp + CPUMCTXCORE.es.Sel]
78a205e3fc6719d59e8c561b3d287d3a4f879852vboxsync push dword [ebp + CPUMCTXCORE.ss.Sel]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync push dword [ebp + CPUMCTXCORE.esp]
eb90d5a431eee79842fb6c676c05aa9ca51ca6a9vboxsync push dword [ebp + CPUMCTXCORE.eflags]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync push dword [ebp + CPUMCTXCORE.cs.Sel]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync push dword [ebp + CPUMCTXCORE.eip]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync ;
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync ; enable WP
d8df004f4caf4f71e78f0be1cc2e2a918358ae9fvboxsync ;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync%ifdef ENABLE_WRITE_PROTECTION
7e960d3a0a8a3a84d7aba2cca45d72b1c31cc97bvboxsync mov eax, cr0
78a205e3fc6719d59e8c561b3d287d3a4f879852vboxsync or eax, X86_CR0_WRITE_PROTECT
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mov cr0, eax
eb90d5a431eee79842fb6c676c05aa9ca51ca6a9vboxsync%endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ; restore CPU context (all except cs, eip, ss, esp, eflags, ds, es, fs & gs; which are restored or overwritten by iret)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mov eax, [ebp + CPUMCTXCORE.eax]
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync mov ebx, [ebp + CPUMCTXCORE.ebx]
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync mov ecx, [ebp + CPUMCTXCORE.ecx]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mov edx, [ebp + CPUMCTXCORE.edx]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mov esi, [ebp + CPUMCTXCORE.esi]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mov edi, [ebp + CPUMCTXCORE.edi]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mov ebp, [ebp + CPUMCTXCORE.ebp]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync TRPM_NP_GP_HANDLER NAME(cpumRCHandleNPAndGP), CPUM_HANDLER_IRET
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync iret
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncENDPROC CPUMGCCallV86Code
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
e11fe099decbb0f65cfcc7e2939fa00bacefbb1cvboxsync;;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync; This is a main entry point for resuming (or starting) guest
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync; code execution.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync; We get here directly from VMMSwitcher.asm (jmp at the end
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync; of VMMSwitcher_HostToGuest).
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync; This call never returns!
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync; @param edx Pointer to CPUMCPU structure.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncalign 16
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncBEGINPROC_EXPORTED CPUMGCResumeGuest
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync%ifdef VBOX_STRICT
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync ; Call CPUM to check sanity.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync push edx
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mov edx, IMP(g_VM)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync push edx
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync call NAME(CPUMRCAssertPreExecutionSanity)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync add esp, 4
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pop edx
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync%endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
7e960d3a0a8a3a84d7aba2cca45d72b1c31cc97bvboxsync ;
0ebb1ef53864eb9cc97580f722288c9b29bc5d03vboxsync ; Setup iretd
0ebb1ef53864eb9cc97580f722288c9b29bc5d03vboxsync ;
0ebb1ef53864eb9cc97580f722288c9b29bc5d03vboxsync push dword [edx + CPUMCPU.Guest.ss.Sel]
0ebb1ef53864eb9cc97580f722288c9b29bc5d03vboxsync push dword [edx + CPUMCPU.Guest.esp]
0ebb1ef53864eb9cc97580f722288c9b29bc5d03vboxsync push dword [edx + CPUMCPU.Guest.eflags]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync push dword [edx + CPUMCPU.Guest.cs.Sel]
f5395a2af3050ddd694b0ad505975f7b717ab4f1vboxsync push dword [edx + CPUMCPU.Guest.eip]
a44cdd0b29504e3de7b8aa87f839ad62b6e66f51vboxsync
a44cdd0b29504e3de7b8aa87f839ad62b6e66f51vboxsync ;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ; Restore registers.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync TRPM_NP_GP_HANDLER NAME(cpumRCHandleNPAndGP), CPUM_HANDLER_ES
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mov es, [edx + CPUMCPU.Guest.es.Sel]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync TRPM_NP_GP_HANDLER NAME(cpumRCHandleNPAndGP), CPUM_HANDLER_FS
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mov fs, [edx + CPUMCPU.Guest.fs.Sel]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync TRPM_NP_GP_HANDLER NAME(cpumRCHandleNPAndGP), CPUM_HANDLER_GS
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mov gs, [edx + CPUMCPU.Guest.gs.Sel]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync%ifdef VBOX_WITH_STATISTICS
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync ;
61e80138f3c5ea5213990bde94a973c8e64d1dadvboxsync ; Statistics.
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync ;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync push edx
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mov edx, IMP(g_VM)
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync lea edx, [edx + VM.StatTotalQemuToGC]
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync STAM_PROFILE_ADV_STOP edx
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mov edx, IMP(g_VM)
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync lea edx, [edx + VM.StatTotalInGC]
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync STAM_PROFILE_ADV_START edx
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pop edx
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync%endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ; enable WP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync%ifdef ENABLE_WRITE_PROTECTION
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mov eax, cr0
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync or eax, X86_CR0_WRITE_PROTECT
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mov cr0, eax
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync%endif
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ; Continue restore.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mov esi, [edx + CPUMCPU.Guest.esi]
13d75a5db336ccb682d7ab28b397a4f0b8982ea3vboxsync mov edi, [edx + CPUMCPU.Guest.edi]
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync mov ebp, [edx + CPUMCPU.Guest.ebp]
a64bf60e92e5cb8a76aa6c8e92193932d88a906fvboxsync mov ebx, [edx + CPUMCPU.Guest.ebx]
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync mov ecx, [edx + CPUMCPU.Guest.ecx]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mov eax, [edx + CPUMCPU.Guest.eax]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync push dword [edx + CPUMCPU.Guest.ds.Sel]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mov edx, [edx + CPUMCPU.Guest.edx]
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync TRPM_NP_GP_HANDLER NAME(cpumRCHandleNPAndGP), CPUM_HANDLER_DS
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pop ds
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ; restart execution.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync TRPM_NP_GP_HANDLER NAME(cpumRCHandleNPAndGP), CPUM_HANDLER_IRET
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync iretd
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncENDPROC CPUMGCResumeGuest
7e960d3a0a8a3a84d7aba2cca45d72b1c31cc97bvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync;;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync; This is a main entry point for resuming (or starting) guest
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync; code execution for raw V86 mode
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync; We get here directly from VMMSwitcher.asm (jmp at the end
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync; of VMMSwitcher_HostToGuest).
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync; This call never returns!
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync;
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync; @param edx Pointer to CPUMCPU structure.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncalign 16
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncBEGINPROC_EXPORTED CPUMGCResumeGuestV86
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync%ifdef VBOX_STRICT
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ; Call CPUM to check sanity.
13d75a5db336ccb682d7ab28b397a4f0b8982ea3vboxsync push edx
13d75a5db336ccb682d7ab28b397a4f0b8982ea3vboxsync mov edx, IMP(g_VM)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync push edx
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync call NAME(CPUMRCAssertPreExecutionSanity)
7e960d3a0a8a3a84d7aba2cca45d72b1c31cc97bvboxsync add esp, 4
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pop edx
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync%endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ; Setup iretd
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync push dword [edx + CPUMCPU.Guest.gs.Sel]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync push dword [edx + CPUMCPU.Guest.fs.Sel]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync push dword [edx + CPUMCPU.Guest.ds.Sel]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync push dword [edx + CPUMCPU.Guest.es.Sel]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync push dword [edx + CPUMCPU.Guest.ss.Sel]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync push dword [edx + CPUMCPU.Guest.esp]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync push dword [edx + CPUMCPU.Guest.eflags]
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync push dword [edx + CPUMCPU.Guest.cs.Sel]
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync push dword [edx + CPUMCPU.Guest.eip]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync ;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ; Restore registers.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync%ifdef VBOX_WITH_STATISTICS
13d75a5db336ccb682d7ab28b397a4f0b8982ea3vboxsync ;
a64bf60e92e5cb8a76aa6c8e92193932d88a906fvboxsync ; Statistics.
a64bf60e92e5cb8a76aa6c8e92193932d88a906fvboxsync ;
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync push edx
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mov edx, IMP(g_VM)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync lea edx, [edx + VM.StatTotalQemuToGC]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync STAM_PROFILE_ADV_STOP edx
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mov edx, IMP(g_VM)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync lea edx, [edx + VM.StatTotalInGC]
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync STAM_PROFILE_ADV_START edx
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync pop edx
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync%endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ; enable WP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ;
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync%ifdef ENABLE_WRITE_PROTECTION
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync mov eax, cr0
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync or eax, X86_CR0_WRITE_PROTECT
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mov cr0, eax
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync%endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ; Continue restore.
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync ;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mov esi, [edx + CPUMCPU.Guest.esi]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mov edi, [edx + CPUMCPU.Guest.edi]
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync mov ebp, [edx + CPUMCPU.Guest.ebp]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mov ecx, [edx + CPUMCPU.Guest.ecx]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mov ebx, [edx + CPUMCPU.Guest.ebx]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mov eax, [edx + CPUMCPU.Guest.eax]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mov edx, [edx + CPUMCPU.Guest.edx]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
13d75a5db336ccb682d7ab28b397a4f0b8982ea3vboxsync ; restart execution.
13d75a5db336ccb682d7ab28b397a4f0b8982ea3vboxsync TRPM_NP_GP_HANDLER NAME(cpumRCHandleNPAndGP), CPUM_HANDLER_IRET
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync iretd
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncENDPROC CPUMGCResumeGuestV86
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync