HMR0Mixed.mac revision 3b79e21f2c3e63e1ef8d514b20431dbe14903b08
78a072e1b56619e3230735ae073668311232ec94vboxsync; $Id$
78a072e1b56619e3230735ae073668311232ec94vboxsync;; @file
78a072e1b56619e3230735ae073668311232ec94vboxsync; HMR0Mixed.mac - Stuff that darwin needs to build two versions of.
78a072e1b56619e3230735ae073668311232ec94vboxsync;
78a072e1b56619e3230735ae073668311232ec94vboxsync; Included by HMR0A.asm with RT_ARCH_AMD64 defined or or undefined.
78a072e1b56619e3230735ae073668311232ec94vboxsync;
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync;
78a072e1b56619e3230735ae073668311232ec94vboxsync; Copyright (C) 2006-2013 Oracle Corporation
78a072e1b56619e3230735ae073668311232ec94vboxsync;
78a072e1b56619e3230735ae073668311232ec94vboxsync; This file is part of VirtualBox Open Source Edition (OSE), as
78a072e1b56619e3230735ae073668311232ec94vboxsync; available from http://www.virtualbox.org. This file is free software;
78a072e1b56619e3230735ae073668311232ec94vboxsync; you can redistribute it and/or modify it under the terms of the GNU
78a072e1b56619e3230735ae073668311232ec94vboxsync; General Public License (GPL) as published by the Free Software
78a072e1b56619e3230735ae073668311232ec94vboxsync; Foundation, in version 2 as it comes in the "COPYING" file of the
78a072e1b56619e3230735ae073668311232ec94vboxsync; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
78a072e1b56619e3230735ae073668311232ec94vboxsync; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
78a072e1b56619e3230735ae073668311232ec94vboxsync;
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync%ifndef VBOX_WITH_OLD_VTX_CODE
78a072e1b56619e3230735ae073668311232ec94vboxsync %ifdef RT_ARCH_AMD64
78a072e1b56619e3230735ae073668311232ec94vboxsync %define VMX_SKIP_GDTR_IDTR
78a072e1b56619e3230735ae073668311232ec94vboxsync %define VMX_SKIP_TR
78a072e1b56619e3230735ae073668311232ec94vboxsync %endif
78a072e1b56619e3230735ae073668311232ec94vboxsync%endif
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync;/**
78a072e1b56619e3230735ae073668311232ec94vboxsync; * Prepares for and executes VMLAUNCH/VMRESUME (32 bits guest mode)
78a072e1b56619e3230735ae073668311232ec94vboxsync; *
78a072e1b56619e3230735ae073668311232ec94vboxsync; * @returns VBox status code
78a072e1b56619e3230735ae073668311232ec94vboxsync; * @param fResume x86:[ebp+8], msc:rcx,gcc:rdi vmlauch/vmresume
78a072e1b56619e3230735ae073668311232ec94vboxsync; * @param pCtx x86:[ebp+c], msc:rdx,gcc:rsi Guest context
78a072e1b56619e3230735ae073668311232ec94vboxsync; * @param pCache x86:[esp+10],msc:r8, gcc:rdx VMCS cache
78a072e1b56619e3230735ae073668311232ec94vboxsync; */
78a072e1b56619e3230735ae073668311232ec94vboxsyncALIGNCODE(16)
78a072e1b56619e3230735ae073668311232ec94vboxsyncBEGINPROC MY_NAME(VMXR0StartVM32)
78a072e1b56619e3230735ae073668311232ec94vboxsync push xBP
78a072e1b56619e3230735ae073668311232ec94vboxsync mov xBP, xSP
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync pushf
78a072e1b56619e3230735ae073668311232ec94vboxsync cli
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Save all general purpose host registers.
78a072e1b56619e3230735ae073668311232ec94vboxsync MYPUSHAD
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; First we have to save some final CPU context registers.
78a072e1b56619e3230735ae073668311232ec94vboxsync mov eax, VMX_VMCS_HOST_RIP
78a072e1b56619e3230735ae073668311232ec94vboxsync%ifdef RT_ARCH_AMD64
78a072e1b56619e3230735ae073668311232ec94vboxsync lea r10, [.vmlaunch_done wrt rip]
78a072e1b56619e3230735ae073668311232ec94vboxsync vmwrite rax, r10
78a072e1b56619e3230735ae073668311232ec94vboxsync%else
78a072e1b56619e3230735ae073668311232ec94vboxsync mov ecx, .vmlaunch_done
78a072e1b56619e3230735ae073668311232ec94vboxsync vmwrite eax, ecx
78a072e1b56619e3230735ae073668311232ec94vboxsync%endif
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Note: assumes success!
08c4185261c17943cff6cc94522579696eeeb478vboxsync
08c4185261c17943cff6cc94522579696eeeb478vboxsync ; Save the Guest CPU context pointer.
08c4185261c17943cff6cc94522579696eeeb478vboxsync%ifdef RT_ARCH_AMD64
08c4185261c17943cff6cc94522579696eeeb478vboxsync %ifdef ASM_CALL64_GCC
08c4185261c17943cff6cc94522579696eeeb478vboxsync ; fResume already in rdi
08c4185261c17943cff6cc94522579696eeeb478vboxsync ; pCtx already in rsi
08c4185261c17943cff6cc94522579696eeeb478vboxsync mov rbx, rdx ; pCache
08c4185261c17943cff6cc94522579696eeeb478vboxsync %else
08c4185261c17943cff6cc94522579696eeeb478vboxsync mov rdi, rcx ; fResume
08c4185261c17943cff6cc94522579696eeeb478vboxsync mov rsi, rdx ; pCtx
08c4185261c17943cff6cc94522579696eeeb478vboxsync mov rbx, r8 ; pCache
08c4185261c17943cff6cc94522579696eeeb478vboxsync %endif
08c4185261c17943cff6cc94522579696eeeb478vboxsync%else
08c4185261c17943cff6cc94522579696eeeb478vboxsync mov edi, [ebp + 8] ; fResume
08c4185261c17943cff6cc94522579696eeeb478vboxsync mov esi, [ebp + 12] ; pCtx
08c4185261c17943cff6cc94522579696eeeb478vboxsync mov ebx, [ebp + 16] ; pCache
08c4185261c17943cff6cc94522579696eeeb478vboxsync%endif
08c4185261c17943cff6cc94522579696eeeb478vboxsync
08c4185261c17943cff6cc94522579696eeeb478vboxsync ; Save segment registers.
08c4185261c17943cff6cc94522579696eeeb478vboxsync ; Note: MYPUSHSEGS trashes rdx & rcx, so we moved it here (msvc amd64 case).
08c4185261c17943cff6cc94522579696eeeb478vboxsync MYPUSHSEGS xAX, ax
08c4185261c17943cff6cc94522579696eeeb478vboxsync
08c4185261c17943cff6cc94522579696eeeb478vboxsync%ifdef VMX_USE_CACHED_VMCS_ACCESSES
78a072e1b56619e3230735ae073668311232ec94vboxsync mov ecx, [xBX + VMCSCACHE.Write.cValidEntries]
08c4185261c17943cff6cc94522579696eeeb478vboxsync cmp ecx, 0
08c4185261c17943cff6cc94522579696eeeb478vboxsync je .no_cached_writes
08c4185261c17943cff6cc94522579696eeeb478vboxsync mov edx, ecx
08c4185261c17943cff6cc94522579696eeeb478vboxsync mov ecx, 0
08c4185261c17943cff6cc94522579696eeeb478vboxsync jmp .cached_write
08c4185261c17943cff6cc94522579696eeeb478vboxsync
08c4185261c17943cff6cc94522579696eeeb478vboxsyncALIGN(16)
08c4185261c17943cff6cc94522579696eeeb478vboxsync.cached_write:
08c4185261c17943cff6cc94522579696eeeb478vboxsync mov eax, [xBX + VMCSCACHE.Write.aField + xCX * 4]
08c4185261c17943cff6cc94522579696eeeb478vboxsync vmwrite xAX, [xBX + VMCSCACHE.Write.aFieldVal + xCX * 8]
08c4185261c17943cff6cc94522579696eeeb478vboxsync inc xCX
08c4185261c17943cff6cc94522579696eeeb478vboxsync cmp xCX, xDX
08c4185261c17943cff6cc94522579696eeeb478vboxsync jl .cached_write
08c4185261c17943cff6cc94522579696eeeb478vboxsync
08c4185261c17943cff6cc94522579696eeeb478vboxsync mov dword [xBX + VMCSCACHE.Write.cValidEntries], 0
08c4185261c17943cff6cc94522579696eeeb478vboxsync.no_cached_writes:
78a072e1b56619e3230735ae073668311232ec94vboxsync
08c4185261c17943cff6cc94522579696eeeb478vboxsync ; Save the pCache pointer.
08c4185261c17943cff6cc94522579696eeeb478vboxsync push xBX
78a072e1b56619e3230735ae073668311232ec94vboxsync%endif
08c4185261c17943cff6cc94522579696eeeb478vboxsync
08c4185261c17943cff6cc94522579696eeeb478vboxsync ; Save the pCtx pointer.
08c4185261c17943cff6cc94522579696eeeb478vboxsync push xSI
08c4185261c17943cff6cc94522579696eeeb478vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Save LDTR.
08c4185261c17943cff6cc94522579696eeeb478vboxsync xor eax, eax
a6ab77f04b22f0de7691f50dfdee8196024ce26dvboxsync sldt ax
a6ab77f04b22f0de7691f50dfdee8196024ce26dvboxsync push xAX
a6ab77f04b22f0de7691f50dfdee8196024ce26dvboxsync
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync%ifndef VMX_SKIP_TR
a6ab77f04b22f0de7691f50dfdee8196024ce26dvboxsync ; The TR limit is reset to 0x67; restore it manually.
78a072e1b56619e3230735ae073668311232ec94vboxsync str eax
08c4185261c17943cff6cc94522579696eeeb478vboxsync push xAX
08c4185261c17943cff6cc94522579696eeeb478vboxsync%endif
78a072e1b56619e3230735ae073668311232ec94vboxsync
08c4185261c17943cff6cc94522579696eeeb478vboxsync%ifndef VMX_SKIP_GDTR_IDTR
08c4185261c17943cff6cc94522579696eeeb478vboxsync ; VT-x only saves the base of the GDTR & IDTR and resets the limit to 0xffff; we must restore the limit correctly!
08c4185261c17943cff6cc94522579696eeeb478vboxsync sub xSP, xCB * 2
08c4185261c17943cff6cc94522579696eeeb478vboxsync sgdt [xSP]
08c4185261c17943cff6cc94522579696eeeb478vboxsync
08c4185261c17943cff6cc94522579696eeeb478vboxsync sub xSP, xCB * 2
08c4185261c17943cff6cc94522579696eeeb478vboxsync sidt [xSP]
08c4185261c17943cff6cc94522579696eeeb478vboxsync%endif
08c4185261c17943cff6cc94522579696eeeb478vboxsync
08c4185261c17943cff6cc94522579696eeeb478vboxsync ; Load CR2 if necessary (may be expensive as writing CR2 is a synchronizing instruction).
08c4185261c17943cff6cc94522579696eeeb478vboxsync mov xBX, [xSI + CPUMCTX.cr2]
78a072e1b56619e3230735ae073668311232ec94vboxsync mov xDX, cr2
08c4185261c17943cff6cc94522579696eeeb478vboxsync cmp xBX, xDX
08c4185261c17943cff6cc94522579696eeeb478vboxsync je .skipcr2write32
08c4185261c17943cff6cc94522579696eeeb478vboxsync mov cr2, xBX
08c4185261c17943cff6cc94522579696eeeb478vboxsync
08c4185261c17943cff6cc94522579696eeeb478vboxsync.skipcr2write32:
08c4185261c17943cff6cc94522579696eeeb478vboxsync mov eax, VMX_VMCS_HOST_RSP
08c4185261c17943cff6cc94522579696eeeb478vboxsync vmwrite xAX, xSP
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Note: assumes success!
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Don't mess with ESP anymore!!!
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Load Guest's general purpose registers.
78a072e1b56619e3230735ae073668311232ec94vboxsync mov eax, [xSI + CPUMCTX.eax]
78a072e1b56619e3230735ae073668311232ec94vboxsync mov ebx, [xSI + CPUMCTX.ebx]
78a072e1b56619e3230735ae073668311232ec94vboxsync mov ecx, [xSI + CPUMCTX.ecx]
78a072e1b56619e3230735ae073668311232ec94vboxsync mov edx, [xSI + CPUMCTX.edx]
78a072e1b56619e3230735ae073668311232ec94vboxsync mov ebp, [xSI + CPUMCTX.ebp]
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Resume or start?
78a072e1b56619e3230735ae073668311232ec94vboxsync cmp xDI, 0 ; fResume
78a072e1b56619e3230735ae073668311232ec94vboxsync je .vmlaunch_launch
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Restore edi & esi.
78a072e1b56619e3230735ae073668311232ec94vboxsync mov edi, [xSI + CPUMCTX.edi]
78a072e1b56619e3230735ae073668311232ec94vboxsync mov esi, [xSI + CPUMCTX.esi]
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync vmresume
78a072e1b56619e3230735ae073668311232ec94vboxsync jmp .vmlaunch_done; ; Here if vmresume detected a failure.
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync.vmlaunch_launch:
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Restore edi & esi.
78a072e1b56619e3230735ae073668311232ec94vboxsync mov edi, [xSI + CPUMCTX.edi]
78a072e1b56619e3230735ae073668311232ec94vboxsync mov esi, [xSI + CPUMCTX.esi]
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync vmlaunch
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync jmp .vmlaunch_done; ; Here if vmlaunch detected a failure.
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsyncALIGNCODE(16) ;; @todo YASM BUG - this alignment is wrong on darwin, it's 1 byte off.
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync.vmlaunch_done:
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync jc near .vmxstart_invalid_vmcs_ptr
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync jz near .vmxstart_start_failed
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync ; Restore base and limit of the IDTR & GDTR.
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync%ifndef VMX_SKIP_GDTR_IDTR
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync lidt [xSP]
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync add xSP, xCB * 2
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync lgdt [xSP]
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync add xSP, xCB * 2
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync%endif
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync push xDI
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync%ifndef VMX_SKIP_TR
ae072e31d733f2a7c9cb1b2b4c4901b66197aadavboxsync mov xDI, [xSP + xCB * 3] ; pCtx (*3 to skip the saved xDI, TR, LDTR).
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync%else
156101683587682f6d63b4af322f611d90b77fcevboxsync mov xDI, [xSP + xCB * 2] ; pCtx (*2 to skip the saved xDI, LDTR).
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync%endif
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync mov [ss:xDI + CPUMCTX.eax], eax
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync mov [ss:xDI + CPUMCTX.ebx], ebx
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync mov [ss:xDI + CPUMCTX.ecx], ecx
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync mov [ss:xDI + CPUMCTX.edx], edx
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync mov [ss:xDI + CPUMCTX.esi], esi
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync mov [ss:xDI + CPUMCTX.ebp], ebp
78a072e1b56619e3230735ae073668311232ec94vboxsync%ifndef VBOX_WITH_OLD_VTX_CODE
78a072e1b56619e3230735ae073668311232ec94vboxsync mov xAX, cr2
78a072e1b56619e3230735ae073668311232ec94vboxsync mov [ss:xDI + CPUMCTX.cr2], xAX
78a072e1b56619e3230735ae073668311232ec94vboxsync%endif
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync%ifdef RT_ARCH_AMD64
78a072e1b56619e3230735ae073668311232ec94vboxsync pop xAX ; The guest edi we pushed above.
78a072e1b56619e3230735ae073668311232ec94vboxsync mov dword [ss:xDI + CPUMCTX.edi], eax
78a072e1b56619e3230735ae073668311232ec94vboxsync%else
78a072e1b56619e3230735ae073668311232ec94vboxsync pop dword [ss:xDI + CPUMCTX.edi] ; The guest edi we pushed above.
78a072e1b56619e3230735ae073668311232ec94vboxsync%endif
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync%ifndef VMX_SKIP_TR
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Restore TSS selector; must mark it as not busy before using ltr (!)
78a072e1b56619e3230735ae073668311232ec94vboxsync ; ASSUME that this is supposed to be 'BUSY'. (saves 20-30 ticks on the T42p)
78a072e1b56619e3230735ae073668311232ec94vboxsync ; @todo get rid of sgdt
78a072e1b56619e3230735ae073668311232ec94vboxsync pop xBX ; Saved TR
78a072e1b56619e3230735ae073668311232ec94vboxsync sub xSP, xCB * 2
78a072e1b56619e3230735ae073668311232ec94vboxsync sgdt [xSP]
78a072e1b56619e3230735ae073668311232ec94vboxsync mov xAX, xBX
78a072e1b56619e3230735ae073668311232ec94vboxsync and al, 0F8h ; Mask away TI and RPL bits, get descriptor offset.
78a072e1b56619e3230735ae073668311232ec94vboxsync add xAX, [xSP + 2] ; eax <- GDTR.address + descriptor offset.
78a072e1b56619e3230735ae073668311232ec94vboxsync and dword [ss:xAX + 4], ~0200h ; Clear busy flag (2nd type2 bit).
78a072e1b56619e3230735ae073668311232ec94vboxsync ltr bx
78a072e1b56619e3230735ae073668311232ec94vboxsync add xSP, xCB * 2
78a072e1b56619e3230735ae073668311232ec94vboxsync%endif
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync pop xAX ; Saved LDTR
78a072e1b56619e3230735ae073668311232ec94vboxsync%ifdef RT_ARCH_AMD64
78a072e1b56619e3230735ae073668311232ec94vboxsync cmp xAX, 0
78a072e1b56619e3230735ae073668311232ec94vboxsync je .skipldtwrite32
78a072e1b56619e3230735ae073668311232ec94vboxsync%endif
78a072e1b56619e3230735ae073668311232ec94vboxsync lldt ax
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync.skipldtwrite32:
78a072e1b56619e3230735ae073668311232ec94vboxsync add xSP, xCB ; pCtx
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync%ifdef VMX_USE_CACHED_VMCS_ACCESSES
78a072e1b56619e3230735ae073668311232ec94vboxsync pop xDX ; Saved pCache
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync mov ecx, [ss:xDX + VMCSCACHE.Read.cValidEntries]
78a072e1b56619e3230735ae073668311232ec94vboxsync cmp ecx, 0 ; Can't happen
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync je .no_cached_reads
78a072e1b56619e3230735ae073668311232ec94vboxsync jmp .cached_read
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsyncALIGN(16)
78a072e1b56619e3230735ae073668311232ec94vboxsync.cached_read:
78a072e1b56619e3230735ae073668311232ec94vboxsync dec xCX
78a072e1b56619e3230735ae073668311232ec94vboxsync mov eax, [ss:xDX + VMCSCACHE.Read.aField + xCX * 4]
78a072e1b56619e3230735ae073668311232ec94vboxsync vmread [ss:xDX + VMCSCACHE.Read.aFieldVal + xCX * 8], xAX
78a072e1b56619e3230735ae073668311232ec94vboxsync cmp xCX, 0
78a072e1b56619e3230735ae073668311232ec94vboxsync jnz .cached_read
78a072e1b56619e3230735ae073668311232ec94vboxsync.no_cached_reads:
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync%ifdef VBOX_WITH_OLD_VTX_CODE
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Restore CR2 into VMCS-cache field (for EPT).
78a072e1b56619e3230735ae073668311232ec94vboxsync mov xAX, cr2
78a072e1b56619e3230735ae073668311232ec94vboxsync mov [ss:xDX + VMCSCACHE.cr2], xAX
78a072e1b56619e3230735ae073668311232ec94vboxsync%endif
78a072e1b56619e3230735ae073668311232ec94vboxsync%endif
78a072e1b56619e3230735ae073668311232ec94vboxsync
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync ; Restore segment registers.
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync MYPOPSEGS xAX, ax
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync ; Restore general purpose registers.
78a072e1b56619e3230735ae073668311232ec94vboxsync MYPOPAD
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync mov eax, VINF_SUCCESS
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync.vmstart_end:
78a072e1b56619e3230735ae073668311232ec94vboxsync popf
78a072e1b56619e3230735ae073668311232ec94vboxsync pop xBP
ae072e31d733f2a7c9cb1b2b4c4901b66197aadavboxsync ret
ae072e31d733f2a7c9cb1b2b4c4901b66197aadavboxsync
ae072e31d733f2a7c9cb1b2b4c4901b66197aadavboxsync
ae072e31d733f2a7c9cb1b2b4c4901b66197aadavboxsync.vmxstart_invalid_vmcs_ptr:
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Restore base and limit of the IDTR & GDTR
78a072e1b56619e3230735ae073668311232ec94vboxsync%ifndef VMX_SKIP_GDTR_IDTR
78a072e1b56619e3230735ae073668311232ec94vboxsync lidt [xSP]
78a072e1b56619e3230735ae073668311232ec94vboxsync add xSP, xCB * 2
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync lgdt [xSP]
78a072e1b56619e3230735ae073668311232ec94vboxsync add xSP, xCB * 2
78a072e1b56619e3230735ae073668311232ec94vboxsync%endif
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync%ifndef VMX_SKIP_TR
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync ; Restore TSS selector; must mark it as not busy before using ltr (!)
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync ; ASSUME that this is supposed to be 'BUSY'. (saves 20-30 ticks on the T42p)
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync ; @todo get rid of sgdt
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync pop xBX ; Saved TR
156101683587682f6d63b4af322f611d90b77fcevboxsync sub xSP, xCB * 2
156101683587682f6d63b4af322f611d90b77fcevboxsync sgdt [xSP]
156101683587682f6d63b4af322f611d90b77fcevboxsync mov xAX, xBX
156101683587682f6d63b4af322f611d90b77fcevboxsync and al, 0F8h ; Mask away TI and RPL bits, get descriptor offset.
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync add xAX, [xSP + 2] ; eax <- GDTR.address + descriptor offset.
78a072e1b56619e3230735ae073668311232ec94vboxsync and dword [ss:xAX + 4], ~0200h ; Clear busy flag (2nd type2 bit).
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync ltr bx
78a072e1b56619e3230735ae073668311232ec94vboxsync add xSP, xCB * 2
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync%endif
78a072e1b56619e3230735ae073668311232ec94vboxsync
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync pop xAX ; Saved LDTR
78a072e1b56619e3230735ae073668311232ec94vboxsync lldt ax ; Don't bother with conditional restoration in the error case.
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync%ifdef VMX_USE_CACHED_VMCS_ACCESSES
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync add xSP, xCB * 2 ; pCtx + pCache
78a072e1b56619e3230735ae073668311232ec94vboxsync%else
78a072e1b56619e3230735ae073668311232ec94vboxsync add xSP, xCB ; pCtx
78a072e1b56619e3230735ae073668311232ec94vboxsync%endif
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Restore segment registers.
78a072e1b56619e3230735ae073668311232ec94vboxsync MYPOPSEGS xAX, ax
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Restore all general purpose host registers.
78a072e1b56619e3230735ae073668311232ec94vboxsync MYPOPAD
78a072e1b56619e3230735ae073668311232ec94vboxsync mov eax, VERR_VMX_INVALID_VMCS_PTR_TO_START_VM
78a072e1b56619e3230735ae073668311232ec94vboxsync jmp .vmstart_end
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync.vmxstart_start_failed:
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Restore base and limit of the IDTR & GDTR.
78a072e1b56619e3230735ae073668311232ec94vboxsync%ifndef VMX_SKIP_GDTR_IDTR
78a072e1b56619e3230735ae073668311232ec94vboxsync lidt [xSP]
78a072e1b56619e3230735ae073668311232ec94vboxsync add xSP, xCB * 2
78a072e1b56619e3230735ae073668311232ec94vboxsync lgdt [xSP]
78a072e1b56619e3230735ae073668311232ec94vboxsync add xSP, xCB * 2
78a072e1b56619e3230735ae073668311232ec94vboxsync%endif
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync%ifndef VMX_SKIP_TR
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Restore TSS selector; must mark it as not busy before using ltr (!)
78a072e1b56619e3230735ae073668311232ec94vboxsync ; ASSUME that this is supposed to be 'BUSY'. (saves 20-30 ticks on the T42p)
78a072e1b56619e3230735ae073668311232ec94vboxsync ; @todo get rid of sgdt
78a072e1b56619e3230735ae073668311232ec94vboxsync pop xBX ; Saved TR
78a072e1b56619e3230735ae073668311232ec94vboxsync sub xSP, xCB * 2
78a072e1b56619e3230735ae073668311232ec94vboxsync sgdt [xSP]
78a072e1b56619e3230735ae073668311232ec94vboxsync mov xAX, xBX
78a072e1b56619e3230735ae073668311232ec94vboxsync and al, 0F8h ; Mask away TI and RPL bits, get descriptor offset.
78a072e1b56619e3230735ae073668311232ec94vboxsync add xAX, [xSP + 2] ; eax <- GDTR.address + descriptor offset.
78a072e1b56619e3230735ae073668311232ec94vboxsync and dword [ss:xAX + 4], ~0200h ; Clear busy flag (2nd type2 bit).
78a072e1b56619e3230735ae073668311232ec94vboxsync ltr bx
78a072e1b56619e3230735ae073668311232ec94vboxsync add xSP, xCB * 2
78a072e1b56619e3230735ae073668311232ec94vboxsync%endif
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync pop xAX ; Saved LDTR
78a072e1b56619e3230735ae073668311232ec94vboxsync lldt ax ; Don't bother with conditional restoration in the error case
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync%ifdef VMX_USE_CACHED_VMCS_ACCESSES
78a072e1b56619e3230735ae073668311232ec94vboxsync add xSP, xCB * 2 ; pCtx + pCache
78a072e1b56619e3230735ae073668311232ec94vboxsync%else
78a072e1b56619e3230735ae073668311232ec94vboxsync add xSP, xCB ; pCtx
78a072e1b56619e3230735ae073668311232ec94vboxsync%endif
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync ; Restore segment registers.
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync MYPOPSEGS xAX, ax
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync
34aa2e97a2a6d7c3c0a5be5121edfd51a31281acvboxsync ; Restore all general purpose host registers.
78a072e1b56619e3230735ae073668311232ec94vboxsync MYPOPAD
78a072e1b56619e3230735ae073668311232ec94vboxsync mov eax, VERR_VMX_UNABLE_TO_START_VM
78a072e1b56619e3230735ae073668311232ec94vboxsync jmp .vmstart_end
78a072e1b56619e3230735ae073668311232ec94vboxsync
ae072e31d733f2a7c9cb1b2b4c4901b66197aadavboxsyncENDPROC MY_NAME(VMXR0StartVM32)
ae072e31d733f2a7c9cb1b2b4c4901b66197aadavboxsync
ae072e31d733f2a7c9cb1b2b4c4901b66197aadavboxsync%ifdef RT_ARCH_AMD64
78a072e1b56619e3230735ae073668311232ec94vboxsync;/**
78a072e1b56619e3230735ae073668311232ec94vboxsync; * Prepares for and executes VMLAUNCH/VMRESUME (64 bits guest mode)
78a072e1b56619e3230735ae073668311232ec94vboxsync; *
78a072e1b56619e3230735ae073668311232ec94vboxsync; * @returns VBox status code
78a072e1b56619e3230735ae073668311232ec94vboxsync; * @param fResume msc:rcx, gcc:rdi vmlauch/vmresume
78a072e1b56619e3230735ae073668311232ec94vboxsync; * @param pCtx msc:rdx, gcc:rsi Guest context
78a072e1b56619e3230735ae073668311232ec94vboxsync; * @param pCache msc:r8, gcc:rdx VMCS cache
ae072e31d733f2a7c9cb1b2b4c4901b66197aadavboxsync; */
ae072e31d733f2a7c9cb1b2b4c4901b66197aadavboxsyncALIGNCODE(16)
ae072e31d733f2a7c9cb1b2b4c4901b66197aadavboxsyncBEGINPROC MY_NAME(VMXR0StartVM64)
ae072e31d733f2a7c9cb1b2b4c4901b66197aadavboxsync push xBP
ae072e31d733f2a7c9cb1b2b4c4901b66197aadavboxsync mov xBP, xSP
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync pushf
78a072e1b56619e3230735ae073668311232ec94vboxsync cli
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Save all general purpose host registers.
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync MYPUSHAD
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; First we have to save some final CPU context registers.
78a072e1b56619e3230735ae073668311232ec94vboxsync lea r10, [.vmlaunch64_done wrt rip]
78a072e1b56619e3230735ae073668311232ec94vboxsync mov rax, VMX_VMCS_HOST_RIP ; Return address (too difficult to continue after VMLAUNCH?).
78a072e1b56619e3230735ae073668311232ec94vboxsync vmwrite rax, r10
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Note: assumes success!
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Save the Guest CPU context pointer.
78a072e1b56619e3230735ae073668311232ec94vboxsync%ifdef ASM_CALL64_GCC
78a072e1b56619e3230735ae073668311232ec94vboxsync ; fResume already in rdi
78a072e1b56619e3230735ae073668311232ec94vboxsync ; pCtx already in rsi
78a072e1b56619e3230735ae073668311232ec94vboxsync mov rbx, rdx ; pCache
78a072e1b56619e3230735ae073668311232ec94vboxsync%else
78a072e1b56619e3230735ae073668311232ec94vboxsync mov rdi, rcx ; fResume
78a072e1b56619e3230735ae073668311232ec94vboxsync mov rsi, rdx ; pCtx
78a072e1b56619e3230735ae073668311232ec94vboxsync mov rbx, r8 ; pCache
78a072e1b56619e3230735ae073668311232ec94vboxsync%endif
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Save segment registers.
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Note: MYPUSHSEGS trashes rdx & rcx, so we moved it here (msvc amd64 case).
78a072e1b56619e3230735ae073668311232ec94vboxsync MYPUSHSEGS xAX, ax
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync%ifdef VMX_USE_CACHED_VMCS_ACCESSES
78a072e1b56619e3230735ae073668311232ec94vboxsync mov ecx, [xBX + VMCSCACHE.Write.cValidEntries]
78a072e1b56619e3230735ae073668311232ec94vboxsync cmp ecx, 0
78a072e1b56619e3230735ae073668311232ec94vboxsync je .no_cached_writes
78a072e1b56619e3230735ae073668311232ec94vboxsync mov edx, ecx
78a072e1b56619e3230735ae073668311232ec94vboxsync mov ecx, 0
78a072e1b56619e3230735ae073668311232ec94vboxsync jmp .cached_write
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsyncALIGN(16)
78a072e1b56619e3230735ae073668311232ec94vboxsync.cached_write:
78a072e1b56619e3230735ae073668311232ec94vboxsync mov eax, [xBX + VMCSCACHE.Write.aField + xCX * 4]
78a072e1b56619e3230735ae073668311232ec94vboxsync vmwrite xAX, [xBX + VMCSCACHE.Write.aFieldVal + xCX * 8]
78a072e1b56619e3230735ae073668311232ec94vboxsync inc xCX
78a072e1b56619e3230735ae073668311232ec94vboxsync cmp xCX, xDX
78a072e1b56619e3230735ae073668311232ec94vboxsync jl .cached_write
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync mov dword [xBX + VMCSCACHE.Write.cValidEntries], 0
78a072e1b56619e3230735ae073668311232ec94vboxsync.no_cached_writes:
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Save the pCache pointer.
78a072e1b56619e3230735ae073668311232ec94vboxsync push xBX
78a072e1b56619e3230735ae073668311232ec94vboxsync%endif
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync%ifndef VBOX_WITH_AUTO_MSR_LOAD_RESTORE
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Save the host MSRs and load the guest MSRs.
78a072e1b56619e3230735ae073668311232ec94vboxsync LOADGUESTMSR MSR_K8_LSTAR, CPUMCTX.msrLSTAR
78a072e1b56619e3230735ae073668311232ec94vboxsync LOADGUESTMSR MSR_K6_STAR, CPUMCTX.msrSTAR
78a072e1b56619e3230735ae073668311232ec94vboxsync LOADGUESTMSR MSR_K8_SF_MASK, CPUMCTX.msrSFMASK
78a072e1b56619e3230735ae073668311232ec94vboxsync LOADGUESTMSR MSR_K8_KERNEL_GS_BASE, CPUMCTX.msrKERNELGSBASE
78a072e1b56619e3230735ae073668311232ec94vboxsync%else
78a072e1b56619e3230735ae073668311232ec94vboxsync%ifdef VBOX_WITH_OLD_VTX_CODE
78a072e1b56619e3230735ae073668311232ec94vboxsync ; The KERNEL_GS_BASE MSR does not work reliably with auto load/store. See @bugref{6208}
78a072e1b56619e3230735ae073668311232ec94vboxsync LOADGUESTMSR MSR_K8_KERNEL_GS_BASE, CPUMCTX.msrKERNELGSBASE
78a072e1b56619e3230735ae073668311232ec94vboxsync%endif
78a072e1b56619e3230735ae073668311232ec94vboxsync%endif
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Save the pCtx pointer.
78a072e1b56619e3230735ae073668311232ec94vboxsync push xSI
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Save LDTR.
78a072e1b56619e3230735ae073668311232ec94vboxsync xor eax, eax
78a072e1b56619e3230735ae073668311232ec94vboxsync sldt ax
78a072e1b56619e3230735ae073668311232ec94vboxsync push xAX
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync%ifndef VMX_SKIP_TR
78a072e1b56619e3230735ae073668311232ec94vboxsync ; The TR limit is reset to 0x67; restore it manually.
78a072e1b56619e3230735ae073668311232ec94vboxsync str eax
78a072e1b56619e3230735ae073668311232ec94vboxsync push xAX
78a072e1b56619e3230735ae073668311232ec94vboxsync%endif
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; VT-x only saves the base of the GDTR & IDTR and resets the limit to 0xffff; we must restore the limit correctly!
78a072e1b56619e3230735ae073668311232ec94vboxsync%ifndef VMX_SKIP_GDTR_IDTR
78a072e1b56619e3230735ae073668311232ec94vboxsync sub xSP, xCB * 2
78a072e1b56619e3230735ae073668311232ec94vboxsync sgdt [xSP]
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync sub xSP, xCB * 2
78a072e1b56619e3230735ae073668311232ec94vboxsync sidt [xSP]
78a072e1b56619e3230735ae073668311232ec94vboxsync%endif
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Load CR2 if necessary (may be expensive as writing CR2 is a synchronizing instruction).
78a072e1b56619e3230735ae073668311232ec94vboxsync mov rbx, qword [xSI + CPUMCTX.cr2]
78a072e1b56619e3230735ae073668311232ec94vboxsync mov rdx, cr2
78a072e1b56619e3230735ae073668311232ec94vboxsync cmp rbx, rdx
78a072e1b56619e3230735ae073668311232ec94vboxsync je .skipcr2write
78a072e1b56619e3230735ae073668311232ec94vboxsync mov cr2, rbx
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync.skipcr2write:
78a072e1b56619e3230735ae073668311232ec94vboxsync mov eax, VMX_VMCS_HOST_RSP
78a072e1b56619e3230735ae073668311232ec94vboxsync vmwrite xAX, xSP
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Note: assumes success!
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Don't mess with ESP anymore!!!
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Restore Guest's general purpose registers.
78a072e1b56619e3230735ae073668311232ec94vboxsync mov rax, qword [xSI + CPUMCTX.eax]
78a072e1b56619e3230735ae073668311232ec94vboxsync mov rbx, qword [xSI + CPUMCTX.ebx]
78a072e1b56619e3230735ae073668311232ec94vboxsync mov rcx, qword [xSI + CPUMCTX.ecx]
78a072e1b56619e3230735ae073668311232ec94vboxsync mov rdx, qword [xSI + CPUMCTX.edx]
78a072e1b56619e3230735ae073668311232ec94vboxsync mov rbp, qword [xSI + CPUMCTX.ebp]
78a072e1b56619e3230735ae073668311232ec94vboxsync mov r8, qword [xSI + CPUMCTX.r8]
78a072e1b56619e3230735ae073668311232ec94vboxsync mov r9, qword [xSI + CPUMCTX.r9]
78a072e1b56619e3230735ae073668311232ec94vboxsync mov r10, qword [xSI + CPUMCTX.r10]
78a072e1b56619e3230735ae073668311232ec94vboxsync mov r11, qword [xSI + CPUMCTX.r11]
78a072e1b56619e3230735ae073668311232ec94vboxsync mov r12, qword [xSI + CPUMCTX.r12]
78a072e1b56619e3230735ae073668311232ec94vboxsync mov r13, qword [xSI + CPUMCTX.r13]
78a072e1b56619e3230735ae073668311232ec94vboxsync mov r14, qword [xSI + CPUMCTX.r14]
78a072e1b56619e3230735ae073668311232ec94vboxsync mov r15, qword [xSI + CPUMCTX.r15]
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Resume or start?
78a072e1b56619e3230735ae073668311232ec94vboxsync cmp xDI, 0 ; fResume
78a072e1b56619e3230735ae073668311232ec94vboxsync je .vmlaunch64_launch
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Restore edi & esi.
78a072e1b56619e3230735ae073668311232ec94vboxsync mov rdi, qword [xSI + CPUMCTX.edi]
78a072e1b56619e3230735ae073668311232ec94vboxsync mov rsi, qword [xSI + CPUMCTX.esi]
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync vmresume
78a072e1b56619e3230735ae073668311232ec94vboxsync jmp .vmlaunch64_done; ; Here if vmresume detected a failure.
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync.vmlaunch64_launch:
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Restore rdi & rsi.
78a072e1b56619e3230735ae073668311232ec94vboxsync mov rdi, qword [xSI + CPUMCTX.edi]
78a072e1b56619e3230735ae073668311232ec94vboxsync mov rsi, qword [xSI + CPUMCTX.esi]
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync vmlaunch
78a072e1b56619e3230735ae073668311232ec94vboxsync jmp .vmlaunch64_done; ; Here if vmlaunch detected a failure.
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsyncALIGNCODE(16)
78a072e1b56619e3230735ae073668311232ec94vboxsync.vmlaunch64_done:
78a072e1b56619e3230735ae073668311232ec94vboxsync jc near .vmxstart64_invalid_vmcs_ptr
78a072e1b56619e3230735ae073668311232ec94vboxsync jz near .vmxstart64_start_failed
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Restore base and limit of the IDTR & GDTR
78a072e1b56619e3230735ae073668311232ec94vboxsync%ifndef VMX_SKIP_GDTR_IDTR
78a072e1b56619e3230735ae073668311232ec94vboxsync lidt [xSP]
78a072e1b56619e3230735ae073668311232ec94vboxsync add xSP, xCB * 2
78a072e1b56619e3230735ae073668311232ec94vboxsync lgdt [xSP]
78a072e1b56619e3230735ae073668311232ec94vboxsync add xSP, xCB * 2
78a072e1b56619e3230735ae073668311232ec94vboxsync%endif
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync push xDI
78a072e1b56619e3230735ae073668311232ec94vboxsync%ifndef VMX_SKIP_TR
78a072e1b56619e3230735ae073668311232ec94vboxsync mov xDI, [xSP + xCB * 3] ; pCtx (*3 to skip the saved xDI, LDTR, TR)
78a072e1b56619e3230735ae073668311232ec94vboxsync%else
78a072e1b56619e3230735ae073668311232ec94vboxsync mov xDI, [xSP + xCB * 2] ; pCtx (*2 to skip the saved xDI, LDTR)
78a072e1b56619e3230735ae073668311232ec94vboxsync%endif
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync mov qword [xDI + CPUMCTX.eax], rax
78a072e1b56619e3230735ae073668311232ec94vboxsync mov qword [xDI + CPUMCTX.ebx], rbx
78a072e1b56619e3230735ae073668311232ec94vboxsync mov qword [xDI + CPUMCTX.ecx], rcx
78a072e1b56619e3230735ae073668311232ec94vboxsync mov qword [xDI + CPUMCTX.edx], rdx
78a072e1b56619e3230735ae073668311232ec94vboxsync mov qword [xDI + CPUMCTX.esi], rsi
78a072e1b56619e3230735ae073668311232ec94vboxsync mov qword [xDI + CPUMCTX.ebp], rbp
78a072e1b56619e3230735ae073668311232ec94vboxsync mov qword [xDI + CPUMCTX.r8], r8
78a072e1b56619e3230735ae073668311232ec94vboxsync mov qword [xDI + CPUMCTX.r9], r9
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync mov qword [xDI + CPUMCTX.r10], r10
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync mov qword [xDI + CPUMCTX.r11], r11
78a072e1b56619e3230735ae073668311232ec94vboxsync mov qword [xDI + CPUMCTX.r12], r12
78a072e1b56619e3230735ae073668311232ec94vboxsync mov qword [xDI + CPUMCTX.r13], r13
78a072e1b56619e3230735ae073668311232ec94vboxsync mov qword [xDI + CPUMCTX.r14], r14
78a072e1b56619e3230735ae073668311232ec94vboxsync mov qword [xDI + CPUMCTX.r15], r15
78a072e1b56619e3230735ae073668311232ec94vboxsync%ifndef VBOX_WITH_OLD_VTX_CODE
78a072e1b56619e3230735ae073668311232ec94vboxsync mov rax, cr2
78a072e1b56619e3230735ae073668311232ec94vboxsync mov qword [xDI + CPUMCTX.cr2], rax
78a072e1b56619e3230735ae073668311232ec94vboxsync%endif
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync pop xAX ; The guest edi we pushed above
78a072e1b56619e3230735ae073668311232ec94vboxsync mov qword [xDI + CPUMCTX.edi], rax
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync%ifndef VMX_SKIP_TR
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Restore TSS selector; must mark it as not busy before using ltr (!)
78a072e1b56619e3230735ae073668311232ec94vboxsync ; ASSUME that this is supposed to be 'BUSY'. (saves 20-30 ticks on the T42p).
78a072e1b56619e3230735ae073668311232ec94vboxsync ; @todo get rid of sgdt
78a072e1b56619e3230735ae073668311232ec94vboxsync pop xBX ; Saved TR
78a072e1b56619e3230735ae073668311232ec94vboxsync sub xSP, xCB * 2
78a072e1b56619e3230735ae073668311232ec94vboxsync sgdt [xSP]
78a072e1b56619e3230735ae073668311232ec94vboxsync mov xAX, xBX
78a072e1b56619e3230735ae073668311232ec94vboxsync and al, 0F8h ; Mask away TI and RPL bits, get descriptor offset.
78a072e1b56619e3230735ae073668311232ec94vboxsync add xAX, [xSP + 2] ; eax <- GDTR.address + descriptor offset.
78a072e1b56619e3230735ae073668311232ec94vboxsync and dword [xAX + 4], ~0200h ; Clear busy flag (2nd type2 bit).
78a072e1b56619e3230735ae073668311232ec94vboxsync ltr bx
78a072e1b56619e3230735ae073668311232ec94vboxsync add xSP, xCB * 2
78a072e1b56619e3230735ae073668311232ec94vboxsync%endif
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync pop xAX ; Saved LDTR
78a072e1b56619e3230735ae073668311232ec94vboxsync cmp xAX, 0
78a072e1b56619e3230735ae073668311232ec94vboxsync je .skipldtwrite64
78a072e1b56619e3230735ae073668311232ec94vboxsync lldt ax
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync.skipldtwrite64:
78a072e1b56619e3230735ae073668311232ec94vboxsync pop xSI ; pCtx (needed in rsi by the macros below)
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync%ifndef VBOX_WITH_AUTO_MSR_LOAD_RESTORE
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Save the guest MSRs and load the host MSRs.
78a072e1b56619e3230735ae073668311232ec94vboxsync LOADHOSTMSREX MSR_K8_KERNEL_GS_BASE, CPUMCTX.msrKERNELGSBASE
78a072e1b56619e3230735ae073668311232ec94vboxsync LOADHOSTMSREX MSR_K8_SF_MASK, CPUMCTX.msrSFMASK
78a072e1b56619e3230735ae073668311232ec94vboxsync LOADHOSTMSREX MSR_K6_STAR, CPUMCTX.msrSTAR
78a072e1b56619e3230735ae073668311232ec94vboxsync LOADHOSTMSREX MSR_K8_LSTAR, CPUMCTX.msrLSTAR
78a072e1b56619e3230735ae073668311232ec94vboxsync%else
78a072e1b56619e3230735ae073668311232ec94vboxsync%ifdef VBOX_WITH_OLD_VTX_CODE
78a072e1b56619e3230735ae073668311232ec94vboxsync ; The KERNEL_GS_BASE MSR does not work reliably with auto load/store. See @bugref{6208}
78a072e1b56619e3230735ae073668311232ec94vboxsync LOADHOSTMSREX MSR_K8_KERNEL_GS_BASE, CPUMCTX.msrKERNELGSBASE
78a072e1b56619e3230735ae073668311232ec94vboxsync%endif
78a072e1b56619e3230735ae073668311232ec94vboxsync%endif
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync%ifdef VMX_USE_CACHED_VMCS_ACCESSES
78a072e1b56619e3230735ae073668311232ec94vboxsync pop xDX ; Saved pCache
ca7f7f38dae7697e6b3046bf4d80dfc98eb59210vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync mov ecx, [xDX + VMCSCACHE.Read.cValidEntries]
78a072e1b56619e3230735ae073668311232ec94vboxsync cmp ecx, 0 ; Can't happen
78a072e1b56619e3230735ae073668311232ec94vboxsync je .no_cached_reads
78a072e1b56619e3230735ae073668311232ec94vboxsync jmp .cached_read
78a072e1b56619e3230735ae073668311232ec94vboxsync
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsyncALIGN(16)
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync.cached_read:
78a072e1b56619e3230735ae073668311232ec94vboxsync dec xCX
78a072e1b56619e3230735ae073668311232ec94vboxsync mov eax, [xDX + VMCSCACHE.Read.aField + xCX * 4]
78a072e1b56619e3230735ae073668311232ec94vboxsync vmread [xDX + VMCSCACHE.Read.aFieldVal + xCX * 8], xAX
78a072e1b56619e3230735ae073668311232ec94vboxsync cmp xCX, 0
78a072e1b56619e3230735ae073668311232ec94vboxsync jnz .cached_read
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync.no_cached_reads:
78a072e1b56619e3230735ae073668311232ec94vboxsync
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync%ifdef VBOX_WITH_OLD_VTX_CODE
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Restore CR2 into VMCS-cache field (for EPT).
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync mov xAX, cr2
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync mov [xDX + VMCSCACHE.cr2], xAX
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync%endif
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync%endif
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync ; Restore segment registers.
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync MYPOPSEGS xAX, ax
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync ; Restore general purpose registers.
78a072e1b56619e3230735ae073668311232ec94vboxsync MYPOPAD
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync mov eax, VINF_SUCCESS
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync.vmstart64_end:
78a072e1b56619e3230735ae073668311232ec94vboxsync popf
78a072e1b56619e3230735ae073668311232ec94vboxsync pop xBP
78a072e1b56619e3230735ae073668311232ec94vboxsync ret
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync.vmxstart64_invalid_vmcs_ptr:
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Restore base and limit of the IDTR & GDTR.
78a072e1b56619e3230735ae073668311232ec94vboxsync%ifndef VMX_SKIP_GDTR_IDTR
78a072e1b56619e3230735ae073668311232ec94vboxsync lidt [xSP]
78a072e1b56619e3230735ae073668311232ec94vboxsync add xSP, xCB * 2
78a072e1b56619e3230735ae073668311232ec94vboxsync lgdt [xSP]
78a072e1b56619e3230735ae073668311232ec94vboxsync add xSP, xCB * 2
78a072e1b56619e3230735ae073668311232ec94vboxsync%endif
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync%ifndef VMX_SKIP_TR
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Restore TSS selector; must mark it as not busy before using ltr (!)
78a072e1b56619e3230735ae073668311232ec94vboxsync ; ASSUME that this is supposed to be 'BUSY'. (saves 20-30 ticks on the T42p).
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync ; @todo get rid of sgdt
78a072e1b56619e3230735ae073668311232ec94vboxsync pop xBX ; Saved TR
78a072e1b56619e3230735ae073668311232ec94vboxsync sub xSP, xCB * 2
78a072e1b56619e3230735ae073668311232ec94vboxsync sgdt [xSP]
78a072e1b56619e3230735ae073668311232ec94vboxsync mov xAX, xBX
78a072e1b56619e3230735ae073668311232ec94vboxsync and al, 0F8h ; Mask away TI and RPL bits, get descriptor offset.
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync add xAX, [xSP + 2] ; eax <- GDTR.address + descriptor offset.
78a072e1b56619e3230735ae073668311232ec94vboxsync and dword [xAX + 4], ~0200h ; Clear busy flag (2nd type2 bit).
78a072e1b56619e3230735ae073668311232ec94vboxsync ltr bx
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync add xSP, xCB * 2
78a072e1b56619e3230735ae073668311232ec94vboxsync%endif
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync pop xAX ; Saved LDTR
78a072e1b56619e3230735ae073668311232ec94vboxsync lldt ax ; Don't bother with conditional restoration in the error case.
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync pop xSI ; pCtx (needed in rsi by the macros below)
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync%ifndef VBOX_WITH_AUTO_MSR_LOAD_RESTORE
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Load the host MSRs. Don't bother saving the guest MSRs as vmlaunch/vmresume failed.
78a072e1b56619e3230735ae073668311232ec94vboxsync LOADHOSTMSR MSR_K8_KERNEL_GS_BASE
78a072e1b56619e3230735ae073668311232ec94vboxsync LOADHOSTMSR MSR_K8_SF_MASK
78a072e1b56619e3230735ae073668311232ec94vboxsync LOADHOSTMSR MSR_K6_STAR
78a072e1b56619e3230735ae073668311232ec94vboxsync LOADHOSTMSR MSR_K8_LSTAR
78a072e1b56619e3230735ae073668311232ec94vboxsync%else
78a072e1b56619e3230735ae073668311232ec94vboxsync%ifdef VBOX_WITH_OLD_VTX_CODE
78a072e1b56619e3230735ae073668311232ec94vboxsync ; The KERNEL_GS_BASE MSR does not work reliably with auto load/store. See @bugref{6208}
78a072e1b56619e3230735ae073668311232ec94vboxsync LOADHOSTMSR MSR_K8_KERNEL_GS_BASE
78a072e1b56619e3230735ae073668311232ec94vboxsync%endif
78a072e1b56619e3230735ae073668311232ec94vboxsync%endif
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync%ifdef VMX_USE_CACHED_VMCS_ACCESSES
78a072e1b56619e3230735ae073668311232ec94vboxsync add xSP, xCB ; pCache
78a072e1b56619e3230735ae073668311232ec94vboxsync%endif
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Restore segment registers.
78a072e1b56619e3230735ae073668311232ec94vboxsync MYPOPSEGS xAX, ax
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Restore all general purpose host registers.
78a072e1b56619e3230735ae073668311232ec94vboxsync MYPOPAD
78a072e1b56619e3230735ae073668311232ec94vboxsync mov eax, VERR_VMX_INVALID_VMCS_PTR_TO_START_VM
78a072e1b56619e3230735ae073668311232ec94vboxsync jmp .vmstart64_end
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync.vmxstart64_start_failed:
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Restore base and limit of the IDTR & GDTR.
78a072e1b56619e3230735ae073668311232ec94vboxsync%ifndef VMX_SKIP_GDTR_IDTR
78a072e1b56619e3230735ae073668311232ec94vboxsync lidt [xSP]
78a072e1b56619e3230735ae073668311232ec94vboxsync add xSP, xCB * 2
78a072e1b56619e3230735ae073668311232ec94vboxsync lgdt [xSP]
78a072e1b56619e3230735ae073668311232ec94vboxsync add xSP, xCB * 2
78a072e1b56619e3230735ae073668311232ec94vboxsync%endif
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync%ifndef VMX_SKIP_TR
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Restore TSS selector; must mark it as not busy before using ltr (!)
78a072e1b56619e3230735ae073668311232ec94vboxsync ; ASSUME that this is supposed to be 'BUSY'. (saves 20-30 ticks on the T42p).
78a072e1b56619e3230735ae073668311232ec94vboxsync ; @todo get rid of sgdt
78a072e1b56619e3230735ae073668311232ec94vboxsync pop xBX ; Saved TR
78a072e1b56619e3230735ae073668311232ec94vboxsync sub xSP, xCB * 2
78a072e1b56619e3230735ae073668311232ec94vboxsync sgdt [xSP]
78a072e1b56619e3230735ae073668311232ec94vboxsync mov xAX, xBX
78a072e1b56619e3230735ae073668311232ec94vboxsync and al, 0F8h ; Mask away TI and RPL bits, get descriptor offset.
78a072e1b56619e3230735ae073668311232ec94vboxsync add xAX, [xSP + 2] ; eax <- GDTR.address + descriptor offset.
78a072e1b56619e3230735ae073668311232ec94vboxsync and dword [xAX + 4], ~0200h ; Clear busy flag (2nd type2 bit).
78a072e1b56619e3230735ae073668311232ec94vboxsync ltr bx
78a072e1b56619e3230735ae073668311232ec94vboxsync add xSP, xCB * 2
78a072e1b56619e3230735ae073668311232ec94vboxsync%endif
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync pop xAX ; Saved LDTR
78a072e1b56619e3230735ae073668311232ec94vboxsync lldt ax ; Don't bother with conditional restoration in the error case.
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync pop xSI ; pCtx (needed in rsi by the macros below).
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync%ifndef VBOX_WITH_AUTO_MSR_LOAD_RESTORE
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Load the host MSRs. Don't bother saving the guest MSRs as vmlaunch/vmresume failed.
78a072e1b56619e3230735ae073668311232ec94vboxsync LOADHOSTMSR MSR_K8_KERNEL_GS_BASE
78a072e1b56619e3230735ae073668311232ec94vboxsync LOADHOSTMSR MSR_K8_SF_MASK
78a072e1b56619e3230735ae073668311232ec94vboxsync LOADHOSTMSR MSR_K6_STAR
78a072e1b56619e3230735ae073668311232ec94vboxsync LOADHOSTMSR MSR_K8_LSTAR
78a072e1b56619e3230735ae073668311232ec94vboxsync%else
78a072e1b56619e3230735ae073668311232ec94vboxsync%ifdef VBOX_WITH_OLD_VTX_CODE
78a072e1b56619e3230735ae073668311232ec94vboxsync ; The KERNEL_GS_BASE MSR does not work reliably with auto load/store. See @bugref{6208}
78a072e1b56619e3230735ae073668311232ec94vboxsync LOADHOSTMSR MSR_K8_KERNEL_GS_BASE
78a072e1b56619e3230735ae073668311232ec94vboxsync%endif
78a072e1b56619e3230735ae073668311232ec94vboxsync%endif
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync%ifdef VMX_USE_CACHED_VMCS_ACCESSES
78a072e1b56619e3230735ae073668311232ec94vboxsync add xSP, xCB ; pCache
78a072e1b56619e3230735ae073668311232ec94vboxsync%endif
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Restore segment registers.
78a072e1b56619e3230735ae073668311232ec94vboxsync MYPOPSEGS xAX, ax
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Restore all general purpose host registers.
78a072e1b56619e3230735ae073668311232ec94vboxsync MYPOPAD
78a072e1b56619e3230735ae073668311232ec94vboxsync mov eax, VERR_VMX_UNABLE_TO_START_VM
78a072e1b56619e3230735ae073668311232ec94vboxsync jmp .vmstart64_end
78a072e1b56619e3230735ae073668311232ec94vboxsyncENDPROC MY_NAME(VMXR0StartVM64)
78a072e1b56619e3230735ae073668311232ec94vboxsync%endif ; RT_ARCH_AMD64
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync;/**
78a072e1b56619e3230735ae073668311232ec94vboxsync; * Prepares for and executes VMRUN (32 bits guests)
78a072e1b56619e3230735ae073668311232ec94vboxsync; *
78a072e1b56619e3230735ae073668311232ec94vboxsync; * @returns VBox status code
e068057c82b010bc7cc663e8f57ac3ef1890a33cvboxsync; * @param HCPhysVMCB Physical address of host VMCB
3f6d4775faa373634b2f3fc2a90fc517733f6fd6vboxsync; * @param HCPhysVMCB Physical address of guest VMCB
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync; * @param pCtx Guest context
0614bee07b5f88aa8803df43fde6d7185a9a7fffvboxsync; */
0614bee07b5f88aa8803df43fde6d7185a9a7fffvboxsyncALIGNCODE(16)
0614bee07b5f88aa8803df43fde6d7185a9a7fffvboxsyncBEGINPROC MY_NAME(SVMR0VMRun)
78a072e1b56619e3230735ae073668311232ec94vboxsync%ifdef RT_ARCH_AMD64 ; fake a cdecl stack frame
78a072e1b56619e3230735ae073668311232ec94vboxsync %ifdef ASM_CALL64_GCC
78a072e1b56619e3230735ae073668311232ec94vboxsync push rdx
78a072e1b56619e3230735ae073668311232ec94vboxsync push rsi
78a072e1b56619e3230735ae073668311232ec94vboxsync push rdi
78a072e1b56619e3230735ae073668311232ec94vboxsync %else
78a072e1b56619e3230735ae073668311232ec94vboxsync push r8
78a072e1b56619e3230735ae073668311232ec94vboxsync push rdx
78a072e1b56619e3230735ae073668311232ec94vboxsync push rcx
78a072e1b56619e3230735ae073668311232ec94vboxsync %endif
78a072e1b56619e3230735ae073668311232ec94vboxsync push 0
78a072e1b56619e3230735ae073668311232ec94vboxsync%endif
78a072e1b56619e3230735ae073668311232ec94vboxsync push xBP
78a072e1b56619e3230735ae073668311232ec94vboxsync mov xBP, xSP
78a072e1b56619e3230735ae073668311232ec94vboxsync pushf
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Save all general purpose host registers.
78a072e1b56619e3230735ae073668311232ec94vboxsync MYPUSHAD
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Save the Guest CPU context pointer.
78a072e1b56619e3230735ae073668311232ec94vboxsync mov xSI, [xBP + xCB * 2 + RTHCPHYS_CB * 2] ; pCtx
78a072e1b56619e3230735ae073668311232ec94vboxsync push xSI ; push for saving the state at the end
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Save host fs, gs, sysenter msr etc.
78a072e1b56619e3230735ae073668311232ec94vboxsync mov xAX, [xBP + xCB * 2] ; pVMCBHostPhys (64 bits physical address; x86: take low dword only)
78a072e1b56619e3230735ae073668311232ec94vboxsync push xAX ; save for the vmload after vmrun
78a072e1b56619e3230735ae073668311232ec94vboxsync vmsave
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Setup eax for VMLOAD.
78a072e1b56619e3230735ae073668311232ec94vboxsync mov xAX, [xBP + xCB * 2 + RTHCPHYS_CB] ; pVMCBPhys (64 bits physical address; take low dword only)
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Restore Guest's general purpose registers.
78a072e1b56619e3230735ae073668311232ec94vboxsync ; eax is loaded from the VMCB by VMRUN.
78a072e1b56619e3230735ae073668311232ec94vboxsync mov ebx, [xSI + CPUMCTX.ebx]
78a072e1b56619e3230735ae073668311232ec94vboxsync mov ecx, [xSI + CPUMCTX.ecx]
78a072e1b56619e3230735ae073668311232ec94vboxsync mov edx, [xSI + CPUMCTX.edx]
78a072e1b56619e3230735ae073668311232ec94vboxsync mov edi, [xSI + CPUMCTX.edi]
78a072e1b56619e3230735ae073668311232ec94vboxsync mov ebp, [xSI + CPUMCTX.ebp]
78a072e1b56619e3230735ae073668311232ec94vboxsync mov esi, [xSI + CPUMCTX.esi]
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Clear the global interrupt flag & execute sti to make sure external interrupts cause a world switch.
78a072e1b56619e3230735ae073668311232ec94vboxsync clgi
78a072e1b56619e3230735ae073668311232ec94vboxsync sti
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Load guest fs, gs, sysenter msr etc.
78a072e1b56619e3230735ae073668311232ec94vboxsync vmload
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Run the VM.
78a072e1b56619e3230735ae073668311232ec94vboxsync vmrun
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; eax is in the VMCB already; we can use it here.
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Save guest fs, gs, sysenter msr etc.
78a072e1b56619e3230735ae073668311232ec94vboxsync vmsave
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Load host fs, gs, sysenter msr etc.
78a072e1b56619e3230735ae073668311232ec94vboxsync pop xAX ; Pushed above
78a072e1b56619e3230735ae073668311232ec94vboxsync vmload
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Set the global interrupt flag again, but execute cli to make sure IF=0.
78a072e1b56619e3230735ae073668311232ec94vboxsync cli
78a072e1b56619e3230735ae073668311232ec94vboxsync stgi
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync pop xAX ; pCtx
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync mov [ss:xAX + CPUMCTX.ebx], ebx
78a072e1b56619e3230735ae073668311232ec94vboxsync mov [ss:xAX + CPUMCTX.ecx], ecx
78a072e1b56619e3230735ae073668311232ec94vboxsync mov [ss:xAX + CPUMCTX.edx], edx
78a072e1b56619e3230735ae073668311232ec94vboxsync mov [ss:xAX + CPUMCTX.esi], esi
78a072e1b56619e3230735ae073668311232ec94vboxsync mov [ss:xAX + CPUMCTX.edi], edi
78a072e1b56619e3230735ae073668311232ec94vboxsync mov [ss:xAX + CPUMCTX.ebp], ebp
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Restore general purpose registers.
78a072e1b56619e3230735ae073668311232ec94vboxsync MYPOPAD
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync mov eax, VINF_SUCCESS
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync popf
78a072e1b56619e3230735ae073668311232ec94vboxsync pop xBP
78a072e1b56619e3230735ae073668311232ec94vboxsync%ifdef RT_ARCH_AMD64
78a072e1b56619e3230735ae073668311232ec94vboxsync add xSP, 4*xCB
78a072e1b56619e3230735ae073668311232ec94vboxsync%endif
78a072e1b56619e3230735ae073668311232ec94vboxsync ret
78a072e1b56619e3230735ae073668311232ec94vboxsyncENDPROC MY_NAME(SVMR0VMRun)
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync%ifdef RT_ARCH_AMD64
78a072e1b56619e3230735ae073668311232ec94vboxsync;/**
78a072e1b56619e3230735ae073668311232ec94vboxsync; * Prepares for and executes VMRUN (64 bits guests)
78a072e1b56619e3230735ae073668311232ec94vboxsync; *
78a072e1b56619e3230735ae073668311232ec94vboxsync; * @returns VBox status code
78a072e1b56619e3230735ae073668311232ec94vboxsync; * @param HCPhysVMCB Physical address of host VMCB
78a072e1b56619e3230735ae073668311232ec94vboxsync; * @param HCPhysVMCB Physical address of guest VMCB
78a072e1b56619e3230735ae073668311232ec94vboxsync; * @param pCtx Guest context
78a072e1b56619e3230735ae073668311232ec94vboxsync; */
78a072e1b56619e3230735ae073668311232ec94vboxsyncALIGNCODE(16)
78a072e1b56619e3230735ae073668311232ec94vboxsyncBEGINPROC MY_NAME(SVMR0VMRun64)
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Fake a cdecl stack frame
78a072e1b56619e3230735ae073668311232ec94vboxsync %ifdef ASM_CALL64_GCC
78a072e1b56619e3230735ae073668311232ec94vboxsync push rdx
78a072e1b56619e3230735ae073668311232ec94vboxsync push rsi
78a072e1b56619e3230735ae073668311232ec94vboxsync push rdi
78a072e1b56619e3230735ae073668311232ec94vboxsync %else
78a072e1b56619e3230735ae073668311232ec94vboxsync push r8
78a072e1b56619e3230735ae073668311232ec94vboxsync push rdx
78a072e1b56619e3230735ae073668311232ec94vboxsync push rcx
78a072e1b56619e3230735ae073668311232ec94vboxsync %endif
78a072e1b56619e3230735ae073668311232ec94vboxsync push 0
78a072e1b56619e3230735ae073668311232ec94vboxsync push rbp
78a072e1b56619e3230735ae073668311232ec94vboxsync mov rbp, rsp
78a072e1b56619e3230735ae073668311232ec94vboxsync pushf
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Manual save and restore:
78a072e1b56619e3230735ae073668311232ec94vboxsync ; - General purpose registers except RIP, RSP, RAX
78a072e1b56619e3230735ae073668311232ec94vboxsync ;
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Trashed:
78a072e1b56619e3230735ae073668311232ec94vboxsync ; - CR2 (we don't care)
78a072e1b56619e3230735ae073668311232ec94vboxsync ; - LDTR (reset to 0)
78a072e1b56619e3230735ae073668311232ec94vboxsync ; - DRx (presumably not changed at all)
78a072e1b56619e3230735ae073668311232ec94vboxsync ; - DR7 (reset to 0x400)
78a072e1b56619e3230735ae073668311232ec94vboxsync ;
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Save all general purpose host registers.
78a072e1b56619e3230735ae073668311232ec94vboxsync MYPUSHAD
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Save the Guest CPU context pointer.
78a072e1b56619e3230735ae073668311232ec94vboxsync mov rsi, [rbp + xCB * 2 + RTHCPHYS_CB * 2] ; pCtx
78a072e1b56619e3230735ae073668311232ec94vboxsync push rsi ; push for saving the state at the end
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Save host fs, gs, sysenter msr etc.
78a072e1b56619e3230735ae073668311232ec94vboxsync mov rax, [rbp + xCB * 2] ; pVMCBHostPhys (64 bits physical address; x86: take low dword only)
78a072e1b56619e3230735ae073668311232ec94vboxsync push rax ; Save for the vmload after vmrun
78a072e1b56619e3230735ae073668311232ec94vboxsync vmsave
08c4185261c17943cff6cc94522579696eeeb478vboxsync
08c4185261c17943cff6cc94522579696eeeb478vboxsync ; Setup eax for VMLOAD.
08c4185261c17943cff6cc94522579696eeeb478vboxsync mov rax, [rbp + xCB * 2 + RTHCPHYS_CB] ; pVMCBPhys (64 bits physical address; take low dword only)
08c4185261c17943cff6cc94522579696eeeb478vboxsync
08c4185261c17943cff6cc94522579696eeeb478vboxsync ; Restore Guest's general purpose registers.
08c4185261c17943cff6cc94522579696eeeb478vboxsync ; rax is loaded from the VMCB by VMRUN.
08c4185261c17943cff6cc94522579696eeeb478vboxsync mov rbx, qword [xSI + CPUMCTX.ebx]
08c4185261c17943cff6cc94522579696eeeb478vboxsync mov rcx, qword [xSI + CPUMCTX.ecx]
08c4185261c17943cff6cc94522579696eeeb478vboxsync mov rdx, qword [xSI + CPUMCTX.edx]
08c4185261c17943cff6cc94522579696eeeb478vboxsync mov rdi, qword [xSI + CPUMCTX.edi]
78a072e1b56619e3230735ae073668311232ec94vboxsync mov rbp, qword [xSI + CPUMCTX.ebp]
78a072e1b56619e3230735ae073668311232ec94vboxsync mov r8, qword [xSI + CPUMCTX.r8]
78a072e1b56619e3230735ae073668311232ec94vboxsync mov r9, qword [xSI + CPUMCTX.r9]
78a072e1b56619e3230735ae073668311232ec94vboxsync mov r10, qword [xSI + CPUMCTX.r10]
78a072e1b56619e3230735ae073668311232ec94vboxsync mov r11, qword [xSI + CPUMCTX.r11]
78a072e1b56619e3230735ae073668311232ec94vboxsync mov r12, qword [xSI + CPUMCTX.r12]
78a072e1b56619e3230735ae073668311232ec94vboxsync mov r13, qword [xSI + CPUMCTX.r13]
78a072e1b56619e3230735ae073668311232ec94vboxsync mov r14, qword [xSI + CPUMCTX.r14]
78a072e1b56619e3230735ae073668311232ec94vboxsync mov r15, qword [xSI + CPUMCTX.r15]
78a072e1b56619e3230735ae073668311232ec94vboxsync mov rsi, qword [xSI + CPUMCTX.esi]
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Clear the global interrupt flag & execute sti to make sure external interrupts cause a world switch.
78a072e1b56619e3230735ae073668311232ec94vboxsync clgi
78a072e1b56619e3230735ae073668311232ec94vboxsync sti
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Load guest fs, gs, sysenter msr etc.
78a072e1b56619e3230735ae073668311232ec94vboxsync vmload
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Run the VM.
78a072e1b56619e3230735ae073668311232ec94vboxsync vmrun
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; rax is in the VMCB already; we can use it here.
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Save guest fs, gs, sysenter msr etc.
78a072e1b56619e3230735ae073668311232ec94vboxsync vmsave
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Load host fs, gs, sysenter msr etc.
78a072e1b56619e3230735ae073668311232ec94vboxsync pop rax ; pushed above
78a072e1b56619e3230735ae073668311232ec94vboxsync vmload
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync ; Set the global interrupt flag again, but execute cli to make sure IF=0.
78a072e1b56619e3230735ae073668311232ec94vboxsync cli
78a072e1b56619e3230735ae073668311232ec94vboxsync stgi
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync pop rax ; pCtx
78a072e1b56619e3230735ae073668311232ec94vboxsync
78a072e1b56619e3230735ae073668311232ec94vboxsync mov qword [rax + CPUMCTX.ebx], rbx
78a072e1b56619e3230735ae073668311232ec94vboxsync mov qword [rax + CPUMCTX.ecx], rcx
78a072e1b56619e3230735ae073668311232ec94vboxsync mov qword [rax + CPUMCTX.edx], rdx
78a072e1b56619e3230735ae073668311232ec94vboxsync mov qword [rax + CPUMCTX.esi], rsi
78a072e1b56619e3230735ae073668311232ec94vboxsync mov qword [rax + CPUMCTX.edi], rdi
78a072e1b56619e3230735ae073668311232ec94vboxsync mov qword [rax + CPUMCTX.ebp], rbp
78a072e1b56619e3230735ae073668311232ec94vboxsync mov qword [rax + CPUMCTX.r8], r8
78a072e1b56619e3230735ae073668311232ec94vboxsync mov qword [rax + CPUMCTX.r9], r9
08c4185261c17943cff6cc94522579696eeeb478vboxsync mov qword [rax + CPUMCTX.r10], r10
08c4185261c17943cff6cc94522579696eeeb478vboxsync mov qword [rax + CPUMCTX.r11], r11
08c4185261c17943cff6cc94522579696eeeb478vboxsync mov qword [rax + CPUMCTX.r12], r12
08c4185261c17943cff6cc94522579696eeeb478vboxsync mov qword [rax + CPUMCTX.r13], r13
08c4185261c17943cff6cc94522579696eeeb478vboxsync mov qword [rax + CPUMCTX.r14], r14
08c4185261c17943cff6cc94522579696eeeb478vboxsync mov qword [rax + CPUMCTX.r15], r15
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync
08c4185261c17943cff6cc94522579696eeeb478vboxsync ; Restore general purpose registers.
08c4185261c17943cff6cc94522579696eeeb478vboxsync MYPOPAD
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync
3f6d4775faa373634b2f3fc2a90fc517733f6fd6vboxsync mov eax, VINF_SUCCESS
3f6d4775faa373634b2f3fc2a90fc517733f6fd6vboxsync
3f6d4775faa373634b2f3fc2a90fc517733f6fd6vboxsync popf
3f6d4775faa373634b2f3fc2a90fc517733f6fd6vboxsync pop rbp
3f6d4775faa373634b2f3fc2a90fc517733f6fd6vboxsync add rsp, 4 * xCB
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync ret
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsyncENDPROC MY_NAME(SVMR0VMRun64)
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync%endif ; RT_ARCH_AMD64
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync
f001a45ec92f71f1e4c1015485fc1ddf84e8059cvboxsync