HWACCMR0.cpp revision b45d66c0e496e2fd861479202f3d43aad592bd14
628393acb2b68337836dd6c2a69ff3b331fc84dbvboxsync * HWACCM - Host Context Ring 0.
628393acb2b68337836dd6c2a69ff3b331fc84dbvboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
628393acb2b68337836dd6c2a69ff3b331fc84dbvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
628393acb2b68337836dd6c2a69ff3b331fc84dbvboxsync * available from http://www.virtualbox.org. This file is free software;
628393acb2b68337836dd6c2a69ff3b331fc84dbvboxsync * you can redistribute it and/or modify it under the terms of the GNU
628393acb2b68337836dd6c2a69ff3b331fc84dbvboxsync * General Public License (GPL) as published by the Free Software
628393acb2b68337836dd6c2a69ff3b331fc84dbvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
628393acb2b68337836dd6c2a69ff3b331fc84dbvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
628393acb2b68337836dd6c2a69ff3b331fc84dbvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
628393acb2b68337836dd6c2a69ff3b331fc84dbvboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
628393acb2b68337836dd6c2a69ff3b331fc84dbvboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
628393acb2b68337836dd6c2a69ff3b331fc84dbvboxsync * additional information or have any questions.
628393acb2b68337836dd6c2a69ff3b331fc84dbvboxsync/*******************************************************************************
628393acb2b68337836dd6c2a69ff3b331fc84dbvboxsync* Header Files *
628393acb2b68337836dd6c2a69ff3b331fc84dbvboxsync*******************************************************************************/
628393acb2b68337836dd6c2a69ff3b331fc84dbvboxsync/*******************************************************************************
628393acb2b68337836dd6c2a69ff3b331fc84dbvboxsync* Internal Functions *
628393acb2b68337836dd6c2a69ff3b331fc84dbvboxsync*******************************************************************************/
628393acb2b68337836dd6c2a69ff3b331fc84dbvboxsyncstatic DECLCALLBACK(void) HWACCMR0EnableCPU(RTCPUID idCpu, void *pvUser1, void *pvUser2);
628393acb2b68337836dd6c2a69ff3b331fc84dbvboxsyncstatic DECLCALLBACK(void) HWACCMR0DisableCPU(RTCPUID idCpu, void *pvUser1, void *pvUser2);
628393acb2b68337836dd6c2a69ff3b331fc84dbvboxsyncstatic DECLCALLBACK(void) HWACCMR0InitCPU(RTCPUID idCpu, void *pvUser1, void *pvUser2);
628393acb2b68337836dd6c2a69ff3b331fc84dbvboxsyncstatic int hwaccmr0CheckCpuRcArray(int *paRc, unsigned cErrorCodes, RTCPUID *pidCpu);
628393acb2b68337836dd6c2a69ff3b331fc84dbvboxsync/*******************************************************************************
628393acb2b68337836dd6c2a69ff3b331fc84dbvboxsync* Local Variables *
628393acb2b68337836dd6c2a69ff3b331fc84dbvboxsync*******************************************************************************/
bool fVMXConfigured;
bool fSVMConfigured;
bool fSupported;
} msr;
} vmx;
bool fSupported;
} svm;
} cpuid;
int rc;
if (ASMHasCpuId())
ASMCpuId(0x80000001, &u32Dummy, &u32Dummy, &HWACCMR0Globals.cpuid.u32AMDFeatureECX, &HWACCMR0Globals.cpuid.u32AMDFeatureEDX);
/* We need to check if VT-x has been properly initialized on all CPUs. Some BIOSes do a lousy job. */
if ( (HWACCMR0Globals.vmx.msr.feature_ctrl & (MSR_IA32_FEATURE_CONTROL_VMXON|MSR_IA32_FEATURE_CONTROL_LOCK))
void *pvScatchPage;
return rc;
*(uint32_t *)pvScatchPage = MSR_IA32_VMX_BASIC_INFO_VMCS_ID(HWACCMR0Globals.vmx.msr.vmx_basic_info);
/* KVM leaves the CPU in VMX root mode. Not only is this not allowed, it will crash the host when we enter raw mode, because
* (b) turning off paging causes a #GP (unavoidable when switching from long to 32 bits mode or 32 bits to PAE)
VMXDisable();
/* Restore CR4 again; don't leave the X86_CR4_VMXE flag set if it wasn't so before (some software could incorrectly think it's in VMX mode) */
#ifdef LOG_ENABLED
/* We need to check if AMD-V has been properly initialized on all CPUs. Some BIOSes might do a poor job. */
ASMCpuId(0x8000000A, &HWACCMR0Globals.svm.u32Rev, &HWACCMR0Globals.svm.u32MaxASID, &u32Dummy, &u32Dummy);
return VINF_SUCCESS;
for (unsigned i=0;i<cErrorCodes;i++)
if (RTMpIsCpuOnline(i))
*pidCpu = i;
return rc;
return rc;
#ifdef LOG_ENABLED
Assert(idCpu == (RTCPUID)RTMpCpuIdToSetIndex(idCpu)); /// @todo fix idCpu == index assumption (rainy day)
ASMWrMsr(MSR_IA32_FEATURE_CONTROL, HWACCMR0Globals.vmx.msr.feature_ctrl | MSR_IA32_FEATURE_CONTROL_VMXON | MSR_IA32_FEATURE_CONTROL_LOCK);
if (ASMAtomicCmpXchgU32((volatile uint32_t *)&HWACCMR0Globals.enmHwAccmState, enmNewHwAccmState, HWACCMSTATE_UNINITIALIZED))
return VINF_SUCCESS;
if (RTMpIsCpuOnline(i))
int rc = RTR0MemObjAllocCont(&HWACCMR0Globals.aCpuInfo[i].pMemObj, 1 << PAGE_SHIFT, true /* executable R0 mapping */);
return rc;
#ifdef LOG_ENABLED
SUPR0Printf("address %x phys %x\n", pvR0, (uint32_t)RTR0MemObjGetPagePhysAddr(HWACCMR0Globals.aCpuInfo[i].pMemObj, 0));
return rc;
return VINF_SUCCESS;
return VERR_ACCESS_DENIED;
void *pvPageCpu;
Assert(idCpu == (RTCPUID)RTMpCpuIdToSetIndex(idCpu)); /// @todo fix idCpu == index assumption (rainy day)
AssertFailed();
void *pvPageCpu;
Assert(idCpu == (RTCPUID)RTMpCpuIdToSetIndex(idCpu)); /// @todo fix idCpu == index assumption (rainy day)
#ifdef LOG_ENABLED
return rc;
#ifdef LOG_ENABLED
return rc;
#ifdef LOG_ENABLED
return rc;
int rc;
return rc;
return rc;
return rc;
return VINF_SUCCESS;
int rc;
return rc;
/** @note It's rather tricky with longjmps done by e.g. Log statements or the page fault handler. */
/* We must restore the host FPU here to make absolutely sure we don't leave the guest FPU state active
int rc;
return rc;
return VINF_SUCCESS;
return VINF_SUCCESS;
#ifdef VBOX_STRICT
unsigned cch;
const char *psz;
uint64_t u32Base = ((uintptr_t)Desc->Gen.u32BaseHigh3 << 32ULL) | Desc->Gen.u8BaseHigh2 << 24ULL | Desc->Gen.u8BaseHigh1 << 16ULL | Desc->Gen.u16BaseLow;
uint32_t u32Base = Desc->Gen.u8BaseHigh2 << 24 | Desc->Gen.u8BaseHigh1 << 16 | Desc->Gen.u16BaseLow;
} aFlags[] =
if (pszAdd)
(RTSEL)pCtx->cs, pCtx->csHid.u32Base, pCtx->csHid.u32Limit, pCtx->csHid.Attr.u, pCtx->dr0, pCtx->dr1,
(RTSEL)pCtx->ds, pCtx->dsHid.u32Base, pCtx->dsHid.u32Limit, pCtx->dsHid.Attr.u, pCtx->dr2, pCtx->dr3,
(RTSEL)pCtx->es, pCtx->esHid.u32Base, pCtx->esHid.u32Limit, pCtx->esHid.Attr.u, pCtx->dr4, pCtx->dr5,
(RTSEL)pCtx->fs, pCtx->fsHid.u32Base, pCtx->fsHid.u32Limit, pCtx->fsHid.Attr.u, pCtx->dr6, pCtx->dr7));
(RTSEL)pCtx->gs, pCtx->gsHid.u32Base, pCtx->gsHid.u32Limit, pCtx->gsHid.Attr.u, pCtx->cr0, pCtx->cr2,