VMMR0.cpp revision 3b0a65a0331c9477954a2b74f38bb4b9dc2fc6d3
1832N/A * available from http://www.virtualbox.org. This file is free software;
1832N/A#include "VMMInternal.h"
1832N/A#ifdef RT_OS_SOLARIS
1832N/A#ifdef VBOX_WITH_DTRACE_R0
#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
#ifdef VBOX_WITH_PCI_PASSTHROUGH
#ifdef VBOX_WITH_TRIPLE_FAULT_HACK
return VINF_SUCCESS;
#ifdef VBOX_WITH_TRIPLE_FAULT_HACK
#ifdef VBOX_WITH_PCI_PASSTHROUGH
PciRawR0Term();
IntNetR0Term();
#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
HMR0Term();
GMMR0Term();
GVMMR0Term();
return rc;
IntNetR0Term();
#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
#ifdef VBOX_WITH_PCI_PASSTHROUGH
PciRawR0Term();
HMR0Term();
#ifdef VBOX_WITH_TRIPLE_FAULT_HACK
GMMR0Term();
GVMMR0Term();
return VERR_VMM_R0_VERSION_MISMATCH;
return VERR_VMM_R0_VERSION_MISMATCH;
return VERR_INVALID_PARAMETER;
#ifdef LOG_ENABLED
if (pR0Logger)
LogCom(("vmmR0InitVM: offScratch=%d fFlags=%#x fDestFlags=%#x\n", pR0Logger->Logger.offScratch, pR0Logger->Logger.fFlags, pR0Logger->Logger.fDestFlags));
LogCom(("vmmR0InitVM: returned successfully from direct logger call (2). offScratch=%d\n", pR0Logger->Logger.offScratch));
&& !RTTimerCanDoHighResolution())
#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
#ifdef VBOX_WITH_PCI_PASSTHROUGH
return rc;
#ifdef VBOX_WITH_PCI_PASSTHROUGH
return rc;
#ifdef VBOX_WITH_PCI_PASSTHROUGH
#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
return VINF_SUCCESS;
return rc;
return VINF_SUCCESS;
switch (enmEvent)
case RTTHREADCTXEVENT_RESUMED:
#ifdef VBOX_WITH_STATISTICS
switch (rc)
case VINF_SUCCESS:
case VINF_EM_RAW_INTERRUPT:
case VINF_EM_RAW_GUEST_TRAP:
case VINF_EM_RAW_RING_SWITCH:
case VINF_EM_RAW_IRET_TRAP:
case VINF_IOM_R3_IOPORT_READ:
case VINF_IOM_R3_IOPORT_WRITE:
case VINF_IOM_R3_MMIO_READ:
case VINF_IOM_R3_MMIO_WRITE:
case VINF_PATCH_EMULATE_INSTR:
case VINF_CSAM_PENDING_ACTION:
case VINF_PGM_SYNC_CR3:
case VINF_PATM_PATCH_INT3:
case VINF_PATM_PATCH_TRAP_PF:
case VINF_PATM_PATCH_TRAP_GP:
case VINF_EM_RESCHEDULE_REM:
case VINF_EM_RAW_TO_R3:
case VINF_VMM_CALL_HOST:
case VMMCALLRING3_PDM_LOCK:
case VMMCALLRING3_PGM_LOCK:
case VINF_PGM_CHANGE_MODE:
case VINF_EM_PENDING_REQUEST:
return VERR_NOT_SUPPORTED;
* The return code is stored in pVM->vmm.s.iLastGZRc.
switch (enmOperation)
case VMMR0_DO_RAW_RUN:
GVMMR0SchedUpdatePeriodicPreemptionTimer(pVM, pVCpu->idHostCpu, TMCalcHostTimerFrequency(pVM, pVCpu));
bool fVTxDisabled;
#ifdef VBOX_WITH_STATISTICS
case VMMR0_DO_HM_RUN:
GVMMR0SchedUpdatePeriodicPreemptionTimer(pVM, pVCpu->idHostCpu, TMCalcHostTimerFrequency(pVM, pVCpu));
#ifdef LOG_ENABLED
if ( pR0Logger
int rc;
bool fPreemptRestored = false;
if (!HMR0SuspendPending())
fPreemptRestored = true;
if (!fPreemptRestored)
#ifdef VBOX_WITH_STATISTICS
case VMMR0_DO_NOP:
DECLINLINE(bool) vmmR0IsValidSession(PVM pVM, PSUPDRVSESSION pClaimedSession, PSUPDRVSESSION pSession)
if (!pSession)
if (pVM)
static int vmmR0EntryExWorker(PVM pVM, VMCPUID idCpu, VMMR0OPERATION enmOperation, PSUPVMMR0REQHDR pReqHdr, uint64_t u64Arg, PSUPDRVSESSION pSession)
if (pVM)
return VERR_INVALID_POINTER;
return VERR_INVALID_POINTER;
return VERR_INVALID_PARAMETER;
return VERR_INVALID_PARAMETER;
switch (enmOperation)
case VMMR0_DO_GVMM_CREATE_VM:
return VERR_INVALID_PARAMETER;
case VMMR0_DO_GVMM_DESTROY_VM:
return VERR_INVALID_PARAMETER;
if (!pVM)
return VERR_INVALID_PARAMETER;
case VMMR0_DO_GVMM_SCHED_HALT:
if (pReqHdr)
return VERR_INVALID_PARAMETER;
return VERR_INVALID_PARAMETER;
case VMMR0_DO_GVMM_SCHED_POKE:
return VERR_INVALID_PARAMETER;
if (u64Arg)
return VERR_INVALID_PARAMETER;
case VMMR0_DO_GVMM_SCHED_POLL:
return VERR_INVALID_PARAMETER;
if (u64Arg)
return VERR_INVALID_PARAMETER;
if (u64Arg)
return VERR_INVALID_PARAMETER;
case VMMR0_DO_VMMR0_INIT:
case VMMR0_DO_VMMR0_TERM:
case VMMR0_DO_HM_ENABLE:
case VMMR0_DO_HM_SETUP_VM:
case VMMR0_DO_CALL_HYPERVISOR:
int rc;
bool fVTxDisabled;
return VERR_PGM_NO_CR3_SHADOW_ROOT;
return rc;
return rc;
return VERR_INVALID_CPU_ID;
return VERR_INVALID_CPU_ID;
return VERR_INVALID_CPU_ID;
if (idCpu != 0)
return VERR_INVALID_CPU_ID;
if (u64Arg)
return VERR_INVALID_PARAMETER;
if (u64Arg)
return VERR_INVALID_PARAMETER;
if (u64Arg)
return VERR_INVALID_PARAMETER;
case VMMR0_DO_GMM_FREE_PAGES:
if (u64Arg)
return VERR_INVALID_PARAMETER;
if (u64Arg)
return VERR_INVALID_PARAMETER;
if (u64Arg)
return VERR_INVALID_PARAMETER;
return VERR_INVALID_CPU_ID;
if (u64Arg)
return VERR_INVALID_PARAMETER;
if (u64Arg)
return VERR_INVALID_PARAMETER;
if (u64Arg)
return VERR_INVALID_PARAMETER;
case VMMR0_DO_GMM_SEED_CHUNK:
if (pReqHdr)
return VERR_INVALID_PARAMETER;
return VERR_INVALID_CPU_ID;
if (u64Arg)
return VERR_INVALID_PARAMETER;
return VERR_INVALID_CPU_ID;
if (u64Arg)
return VERR_INVALID_PARAMETER;
return VERR_INVALID_CPU_ID;
if ( u64Arg
|| pReqHdr)
return VERR_INVALID_PARAMETER;
#ifdef VBOX_WITH_PAGE_SHARING
return VERR_INVALID_CPU_ID;
if ( u64Arg
|| pReqHdr)
return VERR_INVALID_PARAMETER;
# ifdef DEBUG_sandervl
/* Make sure that log flushes can jump back to ring-3; annoying to get an incomplete log (this is risky though as the code doesn't take this into account). */
rc = vmmR0CallRing3SetJmp(&pVCpu->vmm.s.CallRing3JmpBufR0, GMMR0CheckSharedModules, pVM, pVCpu); /* this may resume code. */
|| (rc == VINF_VMM_CALL_HOST && pVCpu->vmm.s.enmCallRing3Operation == VMMCALLRING3_VMM_LOGGER_FLUSH));
return rc;
if (u64Arg)
return VERR_INVALID_PARAMETER;
if (u64Arg)
return VERR_INVALID_PARAMETER;
if (u64Arg)
return VERR_INVALID_PARAMETER;
case VMMR0_DO_GCFGM_SET_VALUE:
return VERR_INVALID_PARAMETER;
return VERR_INVALID_PARAMETER;
int rc;
return rc;
return VERR_INVALID_PARAMETER;
return VERR_INVALID_PARAMETER;
case VMMR0_DO_INTNET_OPEN:
return VERR_INVALID_PARAMETER;
case VMMR0_DO_INTNET_IF_CLOSE:
if (u64Arg || !pReqHdr || !vmmR0IsValidSession(pVM, ((PINTNETIFCLOSEREQ)pReqHdr)->pSession, pSession) || idCpu != NIL_VMCPUID)
return VERR_INVALID_PARAMETER;
if (u64Arg || !pReqHdr || !vmmR0IsValidSession(pVM, ((PINTNETIFGETBUFFERPTRSREQ)pReqHdr)->pSession, pSession) || idCpu != NIL_VMCPUID)
return VERR_INVALID_PARAMETER;
if (u64Arg || !pReqHdr || !vmmR0IsValidSession(pVM, ((PINTNETIFSETPROMISCUOUSMODEREQ)pReqHdr)->pSession, pSession) || idCpu != NIL_VMCPUID)
return VERR_INVALID_PARAMETER;
if (u64Arg || !pReqHdr || !vmmR0IsValidSession(pVM, ((PINTNETIFSETMACADDRESSREQ)pReqHdr)->pSession, pSession) || idCpu != NIL_VMCPUID)
return VERR_INVALID_PARAMETER;
if (u64Arg || !pReqHdr || !vmmR0IsValidSession(pVM, ((PINTNETIFSETACTIVEREQ)pReqHdr)->pSession, pSession) || idCpu != NIL_VMCPUID)
return VERR_INVALID_PARAMETER;
case VMMR0_DO_INTNET_IF_SEND:
if (u64Arg || !pReqHdr || !vmmR0IsValidSession(pVM, ((PINTNETIFSENDREQ)pReqHdr)->pSession, pSession) || idCpu != NIL_VMCPUID)
return VERR_INVALID_PARAMETER;
case VMMR0_DO_INTNET_IF_WAIT:
if (u64Arg || !pReqHdr || !vmmR0IsValidSession(pVM, ((PINTNETIFWAITREQ)pReqHdr)->pSession, pSession) || idCpu != NIL_VMCPUID)
return VERR_INVALID_PARAMETER;
if (u64Arg || !pReqHdr || !vmmR0IsValidSession(pVM, ((PINTNETIFWAITREQ)pReqHdr)->pSession, pSession) || idCpu != NIL_VMCPUID)
return VERR_INVALID_PARAMETER;
#ifdef VBOX_WITH_PCI_PASSTHROUGH
case VMMR0_DO_PCIRAW_REQ:
if (u64Arg || !pReqHdr || !vmmR0IsValidSession(pVM, ((PPCIRAWSENDREQ)pReqHdr)->pSession, pSession) || idCpu != NIL_VMCPUID)
return VERR_INVALID_PARAMETER;
case VMMR0_DO_NOP:
case VMMR0_DO_SLOW_NOP:
return VINF_SUCCESS;
case VMMR0_DO_TESTS:
return VINF_SUCCESS;
#if HC_ARCH_BITS == 32 && defined(VBOX_WITH_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
return VERR_INVALID_CPU_ID;
return VERR_NOT_SUPPORTED;
typedef struct VMMR0ENTRYEXARGS
VMMR0DECL(int) VMMR0EntryEx(PVM pVM, VMCPUID idCpu, VMMR0OPERATION enmOperation, PSUPVMMR0REQHDR pReq, uint64_t u64Arg, PSUPDRVSESSION pSession)
switch (enmOperation)
case VMMR0_DO_GMM_FREE_PAGES:
case VMMR0_DO_VMMR0_INIT:
case VMMR0_DO_VMMR0_TERM:
#ifdef RT_ARCH_X86
#ifdef LOG_ENABLED
# ifdef DEBUG
# ifdef DEBUG
if (pVCpu)
# ifdef RT_ARCH_X86
# ifdef DEBUG
# ifdef DEBUG
#ifdef LOG_ENABLED
#ifdef LOG_ENABLED
if (pVM)
if (pVCpu)
#ifdef RT_ARCH_X86
#ifdef RT_OS_LINUX
DECLEXPORT(void) RTCALL RTAssertMsg1Weak(const char *pszExpr, unsigned uLine, const char *pszFile, const char *pszFunction)
if (pVM)
return cbChars;
if (pLog)
if (pLog)
if (pVM)
RTStrPrintfV(pVM->vmm.s.szRing0AssertMsg2, sizeof(pVM->vmm.s.szRing0AssertMsg2), pszFormat, vaCopy);