HM.cpp revision ae20b83f0c94402a3e3ac021c3d4e5f827e4905c
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel * HM - Intel/AMD VM Hardware Support Manager.
8379ee46ec93e390435dc32135a00a26bb5d77b7Brendan Mmiller * Copyright (C) 2006-2013 Oracle Corporation
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel * This file is part of VirtualBox Open Source Edition (OSE), as
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel * available from http://www.virtualbox.org. This file is free software;
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel * you can redistribute it and/or modify it under the terms of the GNU
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel * General Public License (GPL) as published by the Free Software
8379ee46ec93e390435dc32135a00a26bb5d77b7Brendan Mmiller * Foundation, in version 2 as it comes in the "COPYING" file of the
8379ee46ec93e390435dc32135a00a26bb5d77b7Brendan Mmiller * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
8379ee46ec93e390435dc32135a00a26bb5d77b7Brendan Mmiller * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel/*******************************************************************************
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel* Header Files *
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel*******************************************************************************/
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel/*******************************************************************************
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel* Global Variables *
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel*******************************************************************************/
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel# define EXIT_REASON(def, val, str) #def " - " #val " - " str
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel/** Exit reason descriptions for VT-x, used to describe statistics. */
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feaselstatic const char * const g_apszVTxExitReasons[MAX_EXITREASON_STAT] =
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_XCPT_NMI , 0, "Exception or non-maskable interrupt (NMI)."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_EXT_INT , 1, "External interrupt."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_TRIPLE_FAULT , 2, "Triple fault."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_INIT_SIGNAL , 3, "INIT signal."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_SIPI , 4, "Start-up IPI (SIPI)."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_IO_SMI_IRQ , 5, "I/O system-management interrupt (SMI)."),
8379ee46ec93e390435dc32135a00a26bb5d77b7Brendan Mmiller EXIT_REASON(VMX_EXIT_SMI_IRQ , 6, "Other SMI."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_INT_WINDOW , 7, "Interrupt window."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_TASK_SWITCH , 9, "Task switch."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_CPUID , 10, "Guest software attempted to execute CPUID."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_HLT , 12, "Guest software attempted to execute HLT."),
8379ee46ec93e390435dc32135a00a26bb5d77b7Brendan Mmiller EXIT_REASON(VMX_EXIT_INVD , 13, "Guest software attempted to execute INVD."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_INVLPG , 14, "Guest software attempted to execute INVLPG."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_RDPMC , 15, "Guest software attempted to execute RDPMC."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_RDTSC , 16, "Guest software attempted to execute RDTSC."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_RSM , 17, "Guest software attempted to execute RSM in SMM."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_VMCALL , 18, "Guest software executed VMCALL."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_VMCLEAR , 19, "Guest software executed VMCLEAR."),
8379ee46ec93e390435dc32135a00a26bb5d77b7Brendan Mmiller EXIT_REASON(VMX_EXIT_VMLAUNCH , 20, "Guest software executed VMLAUNCH."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_VMPTRLD , 21, "Guest software executed VMPTRLD."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_VMPTRST , 22, "Guest software executed VMPTRST."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_VMREAD , 23, "Guest software executed VMREAD."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_VMRESUME , 24, "Guest software executed VMRESUME."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_VMWRITE , 25, "Guest software executed VMWRITE."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_VMXOFF , 26, "Guest software executed VMXOFF."),
8379ee46ec93e390435dc32135a00a26bb5d77b7Brendan Mmiller EXIT_REASON(VMX_EXIT_VMXON , 27, "Guest software executed VMXON."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_MOV_CRX , 28, "Control-register accesses."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_MOV_DRX , 29, "Debug-register accesses."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_PORT_IO , 30, "I/O instruction."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_RDMSR , 31, "RDMSR. Guest software attempted to execute RDMSR."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_WRMSR , 32, "WRMSR. Guest software attempted to execute WRMSR."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_ERR_INVALID_GUEST_STATE, 33, "VM-entry failure due to invalid guest state."),
8379ee46ec93e390435dc32135a00a26bb5d77b7Brendan Mmiller EXIT_REASON(VMX_EXIT_ERR_MSR_LOAD , 34, "VM-entry failure due to MSR loading."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_MWAIT , 36, "Guest software executed MWAIT."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_MTF , 37, "Monitor Trap Flag."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_MONITOR , 39, "Guest software attempted to execute MONITOR."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_PAUSE , 40, "Guest software attempted to execute PAUSE."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_ERR_MACHINE_CHECK , 41, "VM-entry failure due to machine-check."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_TPR_BELOW_THRESHOLD, 43, "TPR below threshold. Guest software executed MOV to CR8."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_APIC_ACCESS , 44, "APIC access. Guest software attempted to access memory at a physical address on the APIC-access page."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_XDTR_ACCESS , 46, "Access to GDTR or IDTR. Guest software attempted to execute LGDT, LIDT, SGDT, or SIDT."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_TR_ACCESS , 47, "Access to LDTR or TR. Guest software attempted to execute LLDT, LTR, SLDT, or STR."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_EPT_VIOLATION , 48, "EPT violation. An attempt to access memory with a guest-physical address was disallowed by the configuration of the EPT paging structures."),
8379ee46ec93e390435dc32135a00a26bb5d77b7Brendan Mmiller EXIT_REASON(VMX_EXIT_EPT_MISCONFIG , 49, "EPT misconfiguration. An attempt to access memory with a guest-physical address encountered a misconfigured EPT paging-structure entry."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_INVEPT , 50, "INVEPT. Guest software attempted to execute INVEPT."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_RDTSCP , 51, "RDTSCP. Guest software attempted to execute RDTSCP."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_PREEMPT_TIMER , 52, "VMX-preemption timer expired."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_INVVPID , 53, "INVVPID. Guest software attempted to execute INVVPID."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_WBINVD , 54, "WBINVD. Guest software attempted to execute WBINVD."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_XSETBV , 55, "XSETBV. Guest software attempted to execute XSETBV."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_RDRAND , 57, "RDRAND. Guest software attempted to execute RDRAND."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_INVPCID , 58, "INVPCID. Guest software attempted to execute INVPCID."),
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel EXIT_REASON(VMX_EXIT_VMFUNC , 59, "VMFUNC. Guest software attempted to execute VMFUNC.")
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feasel/** Exit reason descriptions for AMD-V, used to describe statistics. */
32aeec1af4fec00c1b5417c22aca03391e6f8584Jake Feaselstatic const char * const g_apszAmdVExitReasons[MAX_EXITREASON_STAT] =
EXIT_REASON(SVM_EXIT_CR0_SEL_WRITE ,101, "Write to CR0 that changed any bits other than CR0.TS or CR0.MP."),
EXIT_REASON(SVM_EXIT_IOIO ,123, "IN/OUT accessing protected port (EXITINFO1 field provides more information)."),
EXIT_REASON(SVM_EXIT_FERR_FREEZE ,126, "FP legacy handling enabled, and processor is frozen in an x87/mmx instruction waiting for an interrupt"),
EXIT_REASON(SVM_EXIT_NPF ,1024, "Nested paging: host-level page fault occurred (EXITINFO1 contains fault errorcode; EXITINFO2 contains the guest physical address causing the fault)."),
return rc;
//pVM->hm.s.vmx.fSupported = false;
//pVM->hm.s.svm.fSupported = false;
//pVM->hm.s.vmx.fEnabled = false;
//pVM->hm.s.svm.fEnabled = false;
//pVM->hm.s.fNestedPaging = false;
bool fHMForced;
#ifdef VBOX_WITH_RAW_MODE
AssertLogRelMsgReturn(!fHMForced || pVM->fHMEnabled, ("Configuration error: HM forced but not enabled!\n"),
# if defined(RT_OS_DARWIN)
fHMForced = true;
AssertLogRelMsgReturn(pVM->cCpus == 1 || pVM->fHMEnabled, ("Configuration error: SMP requires HM to be enabled!\n"),
fHMForced = true;
fHMForced = true;
/** @cfgm{/HM/EnableNestedPaging, bool, false}
/** @cfgm{/HM/EnableLargePages, bool, false}
/** @cfgm{/HM/EnableVPID, bool, false}
/** @cfgm{/HM/TPRPatchingEnabled, bool, false}
#ifdef VBOX_ENABLE_64_BITS_GUESTS
/** @cfgm{/HM/MaxResumeLoops, uint32_t}
rc = CFGMR3QueryU32Def(pCfgHM, "MaxResumeLoops", &pVM->hm.s.cMaxResumeLoops, 0 /* set by R0 later */);
#ifdef RT_OS_LINUX
if (fHMForced)
LogRel(("HMR3Init: Falling back to raw-mode: The host kernel does not support VT-x.%s\n", pszMinReq));
AssertLogRelMsgFailedReturn(("SUPR3QueryVTCaps didn't return either AMD-V or VT-x flag set (%#x)!\n", fCaps),
const char *pszMsg;
switch (rc)
case VERR_UNSUPPORTED_CPU:
case VERR_VMX_NO_VMX:
case VERR_SVM_NO_SVM:
case VERR_SVM_DISABLED:
if (!pszMsg)
return VINF_SUCCESS;
return VINF_SUCCESS;
#ifdef VBOX_WITH_STATISTICS
STAM_REG(pVM, &pVM->hm.s.StatTprPatchSuccess, STAMTYPE_COUNTER, "/HM/TPR/Patch/Success", STAMUNIT_OCCURENCES, "Number of times an instruction was successfully patched.");
STAM_REG(pVM, &pVM->hm.s.StatTprPatchFailure, STAMTYPE_COUNTER, "/HM/TPR/Patch/Failed", STAMUNIT_OCCURENCES, "Number of unsuccessful patch attempts.");
STAM_REG(pVM, &pVM->hm.s.StatTprReplaceSuccess, STAMTYPE_COUNTER, "/HM/TPR/Replace/Success",STAMUNIT_OCCURENCES, "Number of times an instruction was successfully patched.");
STAM_REG(pVM, &pVM->hm.s.StatTprReplaceFailure, STAMTYPE_COUNTER, "/HM/TPR/Replace/Failed", STAMUNIT_OCCURENCES, "Number of unsuccessful patch attempts.");
int rc;
rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.StatPoke, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL,
rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.StatSpinPoke, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL,
rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.StatSpinPokeFailed, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL,
"/PROF/CPU%d/HM/PokeWaitFailed", i);
rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.StatEntry, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL,
rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.StatExit1, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL,
"/PROF/CPU%d/HM/SwitchFromGC_1", i);
rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.StatExit2, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL,
"/PROF/CPU%d/HM/SwitchFromGC_2", i);
rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.StatExitIO, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL,
rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.StatExitMovCRx, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL,
rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.StatExitXcptNmi, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL,
rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.StatLoadGuestState, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL,
"/PROF/CPU%d/HM/StatLoadGuestState", i);
rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.StatInGC, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL,
# if HC_ARCH_BITS == 32 && defined(VBOX_ENABLE_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
"/PROF/CPU%d/HM/Switcher3264", i);
# ifdef HM_PROFILE_EXIT_DISPATCH
"/PROF/CPU%d/HM/ExitDispatch", i);
# define HM_REG_COUNTER(a, b) \
rc = STAMR3RegisterF(pVM, a, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Profiling of HM", b, i); \
#if HC_ARCH_BITS == 32 && defined(VBOX_ENABLE_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
const char * const *papszDesc = ASMIsIntelCpu() ? &g_apszVTxExitReasons[0] : &g_apszAmdVExitReasons[0];
for (int j = 0; j < MAX_EXITREASON_STAT; j++)
if (papszDesc[j])
rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.StatExitReasonNpf, STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_OCCURENCES,
# ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
rc = MMHyperAlloc(pVM, sizeof(STAMCOUNTER) * 256, 8, MM_TAG_HM, (void **)&pVCpu->hm.s.paStatInjectedIrqs);
# ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
STAMR3RegisterF(pVM, &pVCpu->hm.s.paStatInjectedIrqs[j], STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_OCCURENCES,
#ifdef VBOX_WITH_CRASHDUMP_MAGIC
return VINF_SUCCESS;
switch (enmWhat)
case VMINITCOMPLETED_RING3:
case VMINITCOMPLETED_RING0:
return VINF_SUCCESS;
#ifdef VBOX_WITH_RAW_MODE
int rc;
return VINF_SUCCESS;
case VERR_VMX_NO_VMX:
case VERR_SVM_IN_USE:
case VERR_SVM_NO_SVM:
case VERR_SVM_DISABLED:
return VMSetError(pVM, pVM->hm.s.lLastError, RT_SRC_POS, "HM ring-0 init failed: %Rrc", pVM->hm.s.lLastError);
return rc;
return rc;
int rc;
#ifndef VBOX_WITH_OLD_VTX_CODE
LogRel(("HM: VMCS size = %x\n", MSR_IA32_VMX_BASIC_INFO_VMCS_SIZE(pVM->hm.s.vmx.msr.vmx_basic_info)));
LogRel(("HM: VMCS physical address limit = %s\n", MSR_IA32_VMX_BASIC_INFO_VMCS_PHYS_WIDTH(pVM->hm.s.vmx.msr.vmx_basic_info) ? "< 4 GB" : "None"));
LogRel(("HM: VMCS memory type = %x\n", MSR_IA32_VMX_BASIC_INFO_VMCS_MEM_TYPE(pVM->hm.s.vmx.msr.vmx_basic_info)));
LogRel(("HM: Dual-monitor treatment = %d\n", MSR_IA32_VMX_BASIC_INFO_VMCS_DUAL_MON(pVM->hm.s.vmx.msr.vmx_basic_info)));
if (MSR_IA32_VMX_MISC_PREEMPT_TSC_BIT(pVM->hm.s.vmx.msr.vmx_misc) == pVM->hm.s.vmx.cPreemptTimerShift)
LogRel(("HM: MSR_IA32_VMX_MISC_PREEMPT_TSC_BIT = %x\n", MSR_IA32_VMX_MISC_PREEMPT_TSC_BIT(pVM->hm.s.vmx.msr.vmx_misc)));
LogRel(("HM: MSR_IA32_VMX_MISC_ACTIVITY_STATES = %x\n", MSR_IA32_VMX_MISC_ACTIVITY_STATES(pVM->hm.s.vmx.msr.vmx_misc)));
LogRel(("HM: MSR_IA32_VMX_MISC_CR3_TARGET = %x\n", MSR_IA32_VMX_MISC_CR3_TARGET(pVM->hm.s.vmx.msr.vmx_misc)));
LogRel(("HM: MSR_IA32_VMX_MISC_MAX_MSR = %x\n", MSR_IA32_VMX_MISC_MAX_MSR(pVM->hm.s.vmx.msr.vmx_misc)));
LogRel(("HM: MSR_IA32_VMX_MISC_MSEG_ID = %x\n", MSR_IA32_VMX_MISC_MSEG_ID(pVM->hm.s.vmx.msr.vmx_misc)));
* Disallow RDTSCP in the guest if there is no secondary process-based VM execution controls as otherwise
* RDTSCP would cause a #UD. There might be no CPUs out there where this happens, as RDTSCP was introduced
* in Nehalems and secondary VM exec. controls should be supported in all of them, but nonetheless it's Intel...
memset(pVM->hm.s.vmx.pRealModeTSS->IntRedirBitmap, 0, sizeof(pVM->hm.s.vmx.pRealModeTSS->IntRedirBitmap));
pVM->hm.s.vmx.pNonPagingModeEPTPageTable = (PX86PD)((char *)pVM->hm.s.vmx.pRealModeTSS + PAGE_SIZE * 3);
| X86_PDE4M_G;
LogRel(("HM: CPU[%ld] Last instruction error %x\n", i, pVM->aCpus[i].hm.s.vmx.lasterror.u32InstrError));
#if RT_ARCH_X86
LogRel(("HM: Using the VMX-preemption timer (cPreemptTimerShift=%u)\n", pVM->hm.s.vmx.cPreemptTimerShift));
return VINF_SUCCESS;
LogRel(("HM: AMD cpu with erratum 170 family %x model %x stepping %x\n", u32Family, u32Model, u32Stepping));
if (fSvmFeatures)
return VINF_SUCCESS;
#if HC_ARCH_BITS == 32 && defined(VBOX_ENABLE_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
int rc;
case PGMMODE_32_BIT:
case PGMMODE_PAE:
case PGMMODE_PAE_NX:
AssertFailed();
# ifdef DEBUG
VMMR3_INT_DECL(void) HMR3PagingModeChanged(PVM pVM, PVMCPU pVCpu, PGMMODE enmShadowMode, PGMMODE enmGuestMode)
#ifdef VBOX_WITH_OLD_VTX_CODE
Log(("HMR3PagingModeChanged missed %s->%s transition (prev %s)\n", PGMGetModeName(pVCpu->hm.s.vmx.enmPrevGuestMode),
PGMGetModeName(pVCpu->hm.s.vmx.enmCurrGuestMode), PGMGetModeName(pVCpu->hm.s.vmx.enmLastSeenGuestMode)));
#ifdef VBOX_WITH_STATISTICS
#ifdef VBOX_WITH_CRASHDUMP_MAGIC
#ifdef VBOX_WITH_CRASHDUMP_MAGIC
return VINF_SUCCESS;
int rc;
#ifdef LOG_ENABLED
rc = DBGFR3DisasInstrEx(pVM->pUVM, pVCpu->idCpu, CPUMGetGuestCS(pVCpu), pInstrGC, DBGF_DISAS_FLAGS_DEFAULT_MODE,
#ifdef LOG_ENABLED
rc = DBGFR3DisasInstrEx(pVM->pUVM, pVCpu->idCpu, CPUMGetGuestCS(pVCpu), pInstrGC, DBGF_DISAS_FLAGS_DEFAULT_MODE,
return VINF_SUCCESS;
int rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ONE_BY_ONE, hmR3RemovePatches, (void *)(uintptr_t)idCpu);
return VINF_SUCCESS;
/* We own the IOM lock here and could cause a deadlock by waiting for a VCPU that is blocking on the IOM lock. */
return rc;
return VINF_SUCCESS;
return VINF_SUCCESS;
if (pPatch)
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
if (pPatch)
return VINF_SUCCESS;
return VINF_SUCCESS;
bool fUsesEax = (pDis->Param2.fUse == DISUSE_REG_GEN32 && pDis->Param2.Base.idxGenReg == DISGREG_EAX);
if (!fUsesEax)
if (!fUsesEax)
if (!fUsesEax)
*(RTRCUINTPTR *)&aPatch[off] = ((RTRCUINTPTR)pCtx->eip + cbOp) - ((RTRCUINTPTR)pVM->hm.s.pFreeGuestPatchMem + off + 4);
#ifdef LOG_ENABLED
rc = DBGFR3DisasInstrEx(pVM->pUVM, pVCpu->idCpu, pCtx->cs.Sel, GCPtrInstr, DBGF_DISAS_FLAGS_DEFAULT_MODE,
*(RTRCUINTPTR *)&pPatch->aNewOpcode[1] = ((RTRCUINTPTR)pVM->hm.s.pFreeGuestPatchMem) - ((RTRCUINTPTR)pCtx->eip + 5);
return VINF_SUCCESS;
return VINF_SUCCESS;
return rc;
return VINF_EM_RESCHEDULE_REM;
return VINF_SUCCESS;
/* Note! The context supplied by REM is partial. If we add more checks here, be sure to verify that REM provides this info! */
* The VMM device heap is a requirement for emulating real mode or protected mode without paging with the unrestricted
if (fSupportsRealMode)
* Update: Implemented in EM.cpp, see #ifdef EM_NOTIFY_HM. */
if ( !pVM->hm.s.fNestedPaging /* requires a fake PD for real *and* protected mode without paging - stored in the VMM device heap */
|| CPUMIsGuestInRealModeEx(pCtx)) /* requires a fake TSS for real mode - stored in the VMM device heap */
/* Note: We ignore the NE bit here on purpose; see vmmr0\hmr0.cpp for details. */
if (fSupportsRealMode)
/* Note: We ignore the PE & PG bits here on purpose; we emulate real and protected mode without paging. */
#ifdef VBOX_WITH_OLD_VTX_CODE
return VERR_NOT_FOUND;
switch (enmType)
case HMPENDINGIO_PORT_READ:
&u32Val,
case HMPENDINGIO_PORT_WRITE:
return rcStrict;
switch (iStatusCode)
LogRel(("HM: CPU%d Current pointer %RGp vs %RGp\n", i, pVM->aCpus[i].hm.s.vmx.lasterror.u64VMCSPhys, pVM->aCpus[i].hm.s.vmx.HCPhysVmcs));
LogRel(("HM: CPU%d Current VMCS version %x\n", i, pVM->aCpus[i].hm.s.vmx.lasterror.u32VMCSRevision));
LogRel(("VERR_VMX_UNABLE_TO_START_VM: VM-entry allowed %x\n", pVM->hm.s.vmx.msr.vmx_entry.n.allowed1));
LogRel(("VERR_VMX_UNABLE_TO_START_VM: VM-entry disallowed %x\n", pVM->hm.s.vmx.msr.vmx_entry.n.disallowed0));
int rc;
#ifdef VBOX_HM_WITH_GUEST_PATCHING
return VINF_SUCCESS;
int rc;
#ifdef VBOX_HM_WITH_GUEST_PATCHING
return VINF_SUCCESS;