VM.cpp revision a1c3c7a41597f197e13b5de45327d1459a772d50
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * VM - Virtual Machine
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * Copyright (C) 2006-2010 Oracle Corporation
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * available from http://www.virtualbox.org. This file is free software;
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * you can redistribute it and/or modify it under the terms of the GNU
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * General Public License (GPL) as published by the Free Software
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync/** @page pg_vm VM API
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * This is the encapsulating bit. It provides the APIs that Main and VBoxBFE
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * use to create a VMM instance for running a guest in. It also provides
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * facilities for queuing request for execution in EMT (serialization purposes
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * mostly) and for reporting error back to the VMM user (Main/VBoxBFE).
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * @section sec_vm_design Design Critique / Things To Do
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * In hindsight this component is a big design mistake, all this stuff really
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * belongs in the VMM component. It just seemed like a kind of ok idea at a
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * time when the VMM bit was a kind of vague. 'VM' also happened to be the name
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * of the per-VM instance structure (see vm.h), so it kind of made sense.
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * However as it turned out, VMM(.cpp) is almost empty all it provides in ring-3
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * is some minor functionally and some "routing" services.
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * Fixing this is just a matter of some more or less straight forward
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * refactoring, the question is just when someone will get to it. Moving the EMT
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * would be a good start.
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync/*******************************************************************************
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync* Header Files *
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync*******************************************************************************/
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync/*******************************************************************************
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync* Structures and Typedefs *
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync*******************************************************************************/
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * VM destruction callback registration record.
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsynctypedef struct VMATDTOR
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync /** Pointer to the next record in the list. */
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync /** Pointer to the callback function. */
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync /** The user argument. */
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync/** Pointer to a VM destruction callback registration record. */
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync/*******************************************************************************
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync* Global Variables *
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync*******************************************************************************/
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync/** Pointer to the list of VMs. */
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync/** Pointer to the list of at VM destruction callbacks. */
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync/** Lock the g_pVMAtDtorHead list. */
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync#define VM_ATDTOR_LOCK() do { } while (0)
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync/** Unlock the g_pVMAtDtorHead list. */
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync#define VM_ATDTOR_UNLOCK() do { } while (0)
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync/*******************************************************************************
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync* Internal Functions *
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync*******************************************************************************/
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsyncstatic int vmR3CreateUVM(uint32_t cCpus, PCVMM2USERMETHODS pVmm2UserMethods, PUVM *ppUVM);
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsyncstatic int vmR3CreateU(PUVM pUVM, uint32_t cCpus, PFNCFGMCONSTRUCTOR pfnCFGMConstructor, void *pvUserCFGM);
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsyncstatic int vmR3InitDoCompleted(PVM pVM, VMINITCOMPLETED enmWhat);
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsyncstatic DECLCALLBACK(size_t) vmR3LogPrefixCallback(PRTLOGGER pLogger, char *pchBuf, size_t cchBuf, void *pvUser);
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsyncstatic void vmR3DestroyUVM(PUVM pUVM, uint32_t cMilliesEMTWait);
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsyncstatic bool vmR3ValidateStateTransition(VMSTATE enmStateOld, VMSTATE enmStateNew);
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsyncstatic void vmR3DoAtState(PVM pVM, PUVM pUVM, VMSTATE enmStateNew, VMSTATE enmStateOld);
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsyncstatic int vmR3TrySetState(PVM pVM, const char *pszWho, unsigned cTransitions, ...);
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsyncstatic void vmR3SetStateLocked(PVM pVM, PUVM pUVM, VMSTATE enmStateNew, VMSTATE enmStateOld);
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsyncstatic void vmR3SetState(PVM pVM, VMSTATE enmStateNew, VMSTATE enmStateOld);
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsyncstatic int vmR3SetErrorU(PUVM pUVM, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...);
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * Do global VMM init.
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * @returns VBox status code.
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * Only once.
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync static bool volatile s_fDone = false;
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * We're done.
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * Creates a virtual machine by calling the supplied configuration constructor.
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * On successful returned the VM is powered, i.e. VMR3PowerOn() should be
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * called to start the execution.
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * @returns 0 on success.
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * @returns VBox error code on failure.
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * @param cCpus Number of virtual CPUs for the new VM.
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * @param pVmm2UserMethods An optional method table that the VMM can use
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * to make the user perform various action, like
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * for instance state saving.
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * @param pfnVMAtError Pointer to callback function for setting VM
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * errors. This was added as an implicit call to
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * VMR3AtErrorRegister() since there is no way the
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * caller can get to the VM handle early enough to
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * do this on its own.
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * This is called in the context of an EMT.
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * @param pvUserVM The user argument passed to pfnVMAtError.
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * @param pfnCFGMConstructor Pointer to callback function for constructing the VM configuration tree.
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * This is called in the context of an EMT0.
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * @param pvUserCFGM The user argument passed to pfnCFGMConstructor.
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * @param ppVM Where to store the 'handle' of the created VM.
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsyncVMMR3DECL(int) VMR3Create(uint32_t cCpus, PCVMM2USERMETHODS pVmm2UserMethods,
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync PFNCFGMCONSTRUCTOR pfnCFGMConstructor, void *pvUserCFGM,
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync LogFlow(("VMR3Create: cCpus=%RU32 pVmm2UserMethods=%p pfnVMAtError=%p pvUserVM=%p pfnCFGMConstructor=%p pvUserCFGM=%p ppVM=%p\n",
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync cCpus, pVmm2UserMethods, pfnVMAtError, pvUserVM, pfnCFGMConstructor, pvUserCFGM, ppVM));
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync AssertPtrReturn(pVmm2UserMethods, VERR_INVALID_POINTER);
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync AssertReturn(pVmm2UserMethods->u32Magic == VMM2USERMETHODS_MAGIC, VERR_INVALID_PARAMETER);
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync AssertReturn(pVmm2UserMethods->u32Version == VMM2USERMETHODS_VERSION, VERR_INVALID_PARAMETER);
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync AssertPtrNullReturn(pVmm2UserMethods->pfnSaveState, VERR_INVALID_POINTER);
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync AssertPtrNullReturn(pVmm2UserMethods->pfnNotifyEmtInit, VERR_INVALID_POINTER);
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync AssertPtrNullReturn(pVmm2UserMethods->pfnNotifyEmtTerm, VERR_INVALID_POINTER);
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync AssertPtrNullReturn(pVmm2UserMethods->pfnNotifyPdmtInit, VERR_INVALID_POINTER);
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync AssertPtrNullReturn(pVmm2UserMethods->pfnNotifyPdmtTerm, VERR_INVALID_POINTER);
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync AssertReturn(pVmm2UserMethods->u32EndMagic == VMM2USERMETHODS_MAGIC, VERR_INVALID_PARAMETER);
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync AssertPtrNullReturn(pfnVMAtError, VERR_INVALID_POINTER);
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync AssertPtrNullReturn(pfnCFGMConstructor, VERR_INVALID_POINTER);
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * Because of the current hackiness of the applications
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * we'll have to initialize global stuff from here.
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * Later the applications will take care of this in a proper way.
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync static bool fGlobalInitDone = false;
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * Validate input.
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync AssertLogRelMsgReturn(cCpus > 0 && cCpus <= VMM_MAX_CPU_COUNT, ("%RU32\n", cCpus), VERR_TOO_MANY_CPUS);
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * Create the UVM so we can register the at-error callback
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * and consolidate a bit of cleanup code.
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync int rc = vmR3CreateUVM(cCpus, pVmm2UserMethods, &pUVM);
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync rc = VMR3AtErrorRegisterU(pUVM, pfnVMAtError, pvUserVM);
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * Initialize the support library creating the session for this VM.
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * Call vmR3CreateU in the EMT thread and wait for it to finish.
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * Note! VMCPUID_ANY is used here because VMR3ReqQueueU would have trouble
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * submitting a request to a specific VCPU without a pVM. So, to make
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * sure init is running on EMT(0), vmR3EmulationThreadWithId makes sure
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * that only EMT(0) is servicing VMCPUID_ANY requests when pVM is NULL.
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync rc = VMR3ReqCallU(pUVM, VMCPUID_ANY, &pReq, RT_INDEFINITE_WAIT, VMREQFLAGS_VBOX_STATUS,
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync (PFNRT)vmR3CreateU, 4, pUVM, cCpus, pfnCFGMConstructor, pvUserCFGM);
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync LogFlow(("VMR3Create: returns VINF_SUCCESS *ppVM=%p\n", *ppVM));
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync AssertMsgFailed(("VMR3ReqCallU failed rc=%Rrc\n", rc));
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * An error occurred during VM creation. Set the error message directly
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * using the initial callback, as the callback list might not exist yet.
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync const char *pszError;
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync pszError = N_("VirtualBox can't operate in VMX root mode. "
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync "Please disable the KVM kernel extension, recompile your kernel and reboot");
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync pszError = N_("VirtualBox can't operate in VMX root mode. Please close all other virtualization programs.");
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync pszError = N_("VT-x/AMD-V is either not available on your host or disabled. "
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync "This hardware extension is required by the VM configuration");
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync pszError = N_("VirtualBox can't enable the AMD-V extension. "
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync "Please disable the KVM kernel extension, recompile your kernel and reboot");
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync pszError = N_("VirtualBox can't enable the AMD-V extension. Please close all other virtualization programs.");
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync pszError = N_("One of the kernel modules was not successfully loaded. Make sure "
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync "that no kernel modules from an older version of VirtualBox exist. "
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync "Then try to recompile and reload the kernel modules by executing "
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync "'/etc/init.d/vboxdrv setup' as root");
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync pszError = N_("VT-x/AMD-V is either not available on your host or disabled. "
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync "VirtualBox requires this hardware extension to emulate more than one "
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync "guest CPU");
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync pszError = N_("Because the host kernel is too old, VirtualBox cannot enable the VT-x "
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync "extension. Either upgrade your kernel to Linux 2.6.13 or later or disable "
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync "the VT-x extension in the VM settings. Note that without VT-x you have "
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync "to reduce the number of guest CPUs to one");
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync pszError = N_("Because the host kernel is too old, VirtualBox cannot enable the VT-x "
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync "extension. Either upgrade your kernel or disable the VT-x extension in the "
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync "VM settings. Note that without VT-x you have to reduce the number of guest "
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync "CPUs to one");
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync pszError = N_("A virtual device is configured in the VM settings but the device "
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync "implementation is missing.\n"
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync "A possible reason for this error is a missing extension pack. Note "
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync "that as of VirtualBox 4.0, certain features (for example USB 2.0 "
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync "support and remote desktop) are only available from an 'extension "
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync "pack' which must be downloaded and installed separately");
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * An error occurred at support library initialization time (before the
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * VM could be created). Set the error message directly using the
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync * initial callback, as the callback list doesn't exist yet.
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync const char *pszError;
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync pszError = N_("VirtualBox kernel driver not loaded. The vboxdrv kernel module "
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync "was either not loaded or /dev/vboxdrv is not set up properly. "
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync "Re-setup the kernel module by executing "
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync "'/etc/init.d/vboxdrv setup' as root");
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync pszError = N_("VirtualBox kernel driver not loaded");
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync pszError = N_("VirtualBox kernel driver cannot be opened");
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync /* This should only happen if the executable wasn't hardened - bad code/build. */
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync pszError = N_("VirtualBox kernel driver not accessible, permission problem. "
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync "Re-install VirtualBox. If you are building it yourself, you "
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync "should make sure it installed correctly and that the setuid "
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync "bit is set on the executables calling VMR3Create.");
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync /* This should only happen when mixing builds or with the usual /dev/vboxdrv access issues. */
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync pszError = N_("VirtualBox KEXT is not accessible, permission problem. "
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync "If you have built VirtualBox yourself, make sure that you do not "
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync "have the vboxdrv KEXT from a different build or installation loaded.");
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync pszError = N_("VirtualBox kernel driver is not accessible, permission problem. "
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync "If you have built VirtualBox yourself, make sure that you do "
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync "not have the vboxdrv kernel module from a different build or "
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync "installation loaded. Also, make sure the vboxdrv udev rule gives "
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync "you the permission you need to access the device.");
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync pszError = N_("VirtualBox kernel driver is not accessible, permission problem.");
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync# else /* solaris, freebsd, ++. */
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync pszError = N_("VirtualBox kernel module is not accessible, permission problem. "
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync "If you have built VirtualBox yourself, make sure that you do "
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync "not have the vboxdrv kernel module from a different install loaded.");
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync case VERR_INVALID_HANDLE: /** @todo track down and fix this error. */
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync pszError = N_("VirtualBox kernel driver not installed. The vboxdrv kernel module "
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync "was either not loaded or /dev/vboxdrv was not created for some "
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync "reason. Re-setup the kernel module by executing "
cb702d6d593134e47854c00a7fa1156fe48a14ccvboxsync "'/etc/init.d/vboxdrv setup' as root");
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync pszError = N_("VirtualBox kernel driver not installed");
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync pszError = N_("VirtualBox support library out of memory");
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync pszError = N_("The VirtualBox support driver which is running is from a different "
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync "version of VirtualBox. You can correct this by stopping all "
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync "running instances of VirtualBox and reinstalling the software.");
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync pszError = N_("Unknown error initializing kernel driver");
a9a79301a7d78abffc51521473bbb5a1e08028c5vboxsync AssertMsgFailed(("Add error message for rc=%d (%Rrc)\n", rc, rc));
return rc;
uint32_t i;
for (i = 0; i < cCpus; i++)
for (i = 0; i < cCpus; i++)
for (i = 0; i < cCpus; i++)
for (i = 0; i < cCpus; i++)
return VINF_SUCCESS;
for (i = 0; i < cCpus; i++)
return rc;
static int vmR3CreateU(PUVM pUVM, uint32_t cCpus, PFNCFGMCONSTRUCTOR pfnCFGMConstructor, void *pvUserCFGM)
AssertLogRelMsgRC(rc, ("Configuration error: Querying \"NumCPUs\" as integer failed, rc=%Rrc\n", rc));
AssertLogRelMsgFailed(("Configuration error: \"NumCPUs\"=%RU32 and VMR3CreateVM::cCpus=%RU32 does not match!\n",
AssertLogRelMsgRC(rc, ("Configuration error: Querying \"CpuExecutionCap\" as integer failed, rc=%Rrc\n", rc));
AssertLogRelMsg(RT_SUCCESS(rc) && rc != VERR_CFGM_VALUE_NOT_FOUND, ("Configuration error: Querying \"Name\" failed, rc=%Rrc\n", rc));
AssertLogRelMsg(RT_SUCCESS(rc) && rc != VERR_CFGM_VALUE_NOT_FOUND, ("Configuration error: Querying \"UUID\" failed, rc=%Rrc\n", rc));
#ifdef VBOX_WITH_DEBUGGER
#ifdef LOG_ENABLED
return VINF_SUCCESS;
#ifdef VBOX_WITH_DEBUGGER
return rc;
return rc;
int rc;
return rc;
STAM_REG(pVM, &pVM->StatTotalInGC, STAMTYPE_PROFILE_ADV, "/PROF/VM/InGC", STAMUNIT_TICKS_PER_CALL, "Profiling the total time spent in GC.");
STAM_REG(pVM, &pVM->StatSwitcherToGC, STAMTYPE_PROFILE_ADV, "/PROF/VM/SwitchToGC", STAMUNIT_TICKS_PER_CALL, "Profiling switching to GC.");
STAM_REG(pVM, &pVM->StatSwitcherToHC, STAMTYPE_PROFILE_ADV, "/PROF/VM/SwitchToHC", STAMUNIT_TICKS_PER_CALL, "Profiling switching to HC.");
STAM_REG(pVM, &pVM->StatSwitcherSaveRegs, STAMTYPE_PROFILE_ADV, "/VM/Switcher/ToGC/SaveRegs", STAMUNIT_TICKS_PER_CALL,"Profiling switching to GC.");
STAM_REG(pVM, &pVM->StatSwitcherSysEnter, STAMTYPE_PROFILE_ADV, "/VM/Switcher/ToGC/SysEnter", STAMUNIT_TICKS_PER_CALL,"Profiling switching to GC.");
STAM_REG(pVM, &pVM->StatSwitcherDebug, STAMTYPE_PROFILE_ADV, "/VM/Switcher/ToGC/Debug", STAMUNIT_TICKS_PER_CALL,"Profiling switching to GC.");
STAM_REG(pVM, &pVM->StatSwitcherCR0, STAMTYPE_PROFILE_ADV, "/VM/Switcher/ToGC/CR0", STAMUNIT_TICKS_PER_CALL, "Profiling switching to GC.");
STAM_REG(pVM, &pVM->StatSwitcherCR4, STAMTYPE_PROFILE_ADV, "/VM/Switcher/ToGC/CR4", STAMUNIT_TICKS_PER_CALL, "Profiling switching to GC.");
STAM_REG(pVM, &pVM->StatSwitcherLgdt, STAMTYPE_PROFILE_ADV, "/VM/Switcher/ToGC/Lgdt", STAMUNIT_TICKS_PER_CALL, "Profiling switching to GC.");
STAM_REG(pVM, &pVM->StatSwitcherLidt, STAMTYPE_PROFILE_ADV, "/VM/Switcher/ToGC/Lidt", STAMUNIT_TICKS_PER_CALL, "Profiling switching to GC.");
STAM_REG(pVM, &pVM->StatSwitcherLldt, STAMTYPE_PROFILE_ADV, "/VM/Switcher/ToGC/Lldt", STAMUNIT_TICKS_PER_CALL, "Profiling switching to GC.");
STAM_REG(pVM, &pVM->StatSwitcherTSS, STAMTYPE_PROFILE_ADV, "/VM/Switcher/ToGC/TSS", STAMUNIT_TICKS_PER_CALL, "Profiling switching to GC.");
STAM_REG(pVM, &pVM->StatSwitcherJmpCR3, STAMTYPE_PROFILE_ADV, "/VM/Switcher/ToGC/JmpCR3", STAMUNIT_TICKS_PER_CALL,"Profiling switching to GC.");
STAM_REG(pVM, &pVM->StatSwitcherRstrRegs, STAMTYPE_PROFILE_ADV, "/VM/Switcher/ToGC/RstrRegs", STAMUNIT_TICKS_PER_CALL,"Profiling switching to GC.");
rc = STAMR3RegisterF(pVM, &pUVM->aCpus[idCpu].vm.s.StatHaltYield, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_NS_PER_CALL, "Profiling halted state yielding.", "/PROF/VM/CPU%d/Halt/Yield", idCpu);
rc = STAMR3RegisterF(pVM, &pUVM->aCpus[idCpu].vm.s.StatHaltBlock, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_NS_PER_CALL, "Profiling halted state blocking.", "/PROF/VM/CPU%d/Halt/Block", idCpu);
rc = STAMR3RegisterF(pVM, &pUVM->aCpus[idCpu].vm.s.StatHaltBlockOverslept, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_NS_PER_CALL, "Time wasted by blocking too long.", "/PROF/VM/CPU%d/Halt/BlockOverslept", idCpu);
rc = STAMR3RegisterF(pVM, &pUVM->aCpus[idCpu].vm.s.StatHaltBlockInsomnia, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_NS_PER_CALL, "Time slept when returning to early.","/PROF/VM/CPU%d/Halt/BlockInsomnia", idCpu);
rc = STAMR3RegisterF(pVM, &pUVM->aCpus[idCpu].vm.s.StatHaltBlockOnTime, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_NS_PER_CALL, "Time slept on time.", "/PROF/VM/CPU%d/Halt/BlockOnTime", idCpu);
rc = STAMR3RegisterF(pVM, &pUVM->aCpus[idCpu].vm.s.StatHaltTimers, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_NS_PER_CALL, "Profiling halted state timer tasks.", "/PROF/VM/CPU%d/Halt/Timers", idCpu);
STAM_REG(pVM, &pUVM->vm.s.StatReqAllocNew, STAMTYPE_COUNTER, "/VM/Req/AllocNew", STAMUNIT_OCCURENCES, "Number of VMR3ReqAlloc returning a new packet.");
STAM_REG(pVM, &pUVM->vm.s.StatReqAllocRaces, STAMTYPE_COUNTER, "/VM/Req/AllocRaces", STAMUNIT_OCCURENCES, "Number of VMR3ReqAlloc causing races.");
STAM_REG(pVM, &pUVM->vm.s.StatReqAllocRecycled, STAMTYPE_COUNTER, "/VM/Req/AllocRecycled", STAMUNIT_OCCURENCES, "Number of VMR3ReqAlloc returning a recycled packet.");
STAM_REG(pVM, &pUVM->vm.s.StatReqFree, STAMTYPE_COUNTER, "/VM/Req/Free", STAMUNIT_OCCURENCES, "Number of VMR3ReqFree calls.");
STAM_REG(pVM, &pUVM->vm.s.StatReqFreeOverflow, STAMTYPE_COUNTER, "/VM/Req/FreeOverflow", STAMUNIT_OCCURENCES, "Number of times the request was actually freed.");
STAM_REG(pVM, &pUVM->vm.s.StatReqProcessed, STAMTYPE_COUNTER, "/VM/Req/Processed", STAMUNIT_OCCURENCES, "Number of processed requests (any queue).");
STAM_REG(pVM, &pUVM->vm.s.StatReqMoreThan1, STAMTYPE_COUNTER, "/VM/Req/MoreThan1", STAMUNIT_OCCURENCES, "Number of times there are more than one request on the queue when processing it.");
STAM_REG(pVM, &pUVM->vm.s.StatReqPushBackRaces, STAMTYPE_COUNTER, "/VM/Req/PushBackRaces", STAMUNIT_OCCURENCES, "Number of push back races.");
return VINF_SUCCESS;
return rc;
return rc;
return rc;
return rc;
static DECLCALLBACK(size_t) vmR3LogPrefixCallback(PRTLOGGER pLogger, char *pchBuf, size_t cchBuf, void *pvUser)
if (pUVCpu)
return rc;
return VINF_SUCCESS;
int rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_DESCENDING | VMMEMTRENDEZVOUS_FLAGS_STOP_ON_ERROR,
return rc;
return rc;
return VERR_INTERNAL_ERROR_3;
return VINF_EM_SUSPEND;
int rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_DESCENDING | VMMEMTRENDEZVOUS_FLAGS_STOP_ON_ERROR,
return rc;
return rc;
return VINF_EM_RESUME;
int rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_DESCENDING | VMMEMTRENDEZVOUS_FLAGS_STOP_ON_ERROR,
return rc;
int rc;
switch (enmVMState)
case VMSTATE_RUNNING_LS:
case VMSTATE_SUSPENDED_EXT_LS:
case VMSTATE_DEBUGGING_LS:
case VMSTATE_OFF_LS:
case VMSTATE_FATAL_ERROR_LS:
case VMSTATE_POWERING_OFF_LS:
case VMSTATE_RESETTING_LS:
return rc;
return VERR_INTERNAL_ERROR_3;
*pfSuspended = true;
return VINF_EM_SUSPEND;
*pfSuspended = true;
else if (rc > 0)
return rc;
return rc;
static DECLCALLBACK(int) vmR3Save(PVM pVM, uint32_t cMsMaxDowntime, const char *pszFilename, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser,
bool fSkipStateChanges)
LogFlow(("vmR3Save: pVM=%p cMsMaxDowntime=%u pszFilename=%p:{%s} pStreamOps=%p pvStreamOpsUser=%p enmAfter=%d pfnProgress=%p pvProgressUser=%p ppSSM=%p\n",
pVM, cMsMaxDowntime, pszFilename, pszFilename, pStreamOps, pvStreamOpsUser, enmAfter, pfnProgress, pvProgressUser, ppSSM));
if (!fSkipStateChanges)
rc = SSMR3Save(pVM, pszFilename, pStreamOps, pvStreamOpsUser, enmAfter, pfnProgress, pvProgressUser);
if (!fSkipStateChanges)
return rc;
bool fSkipStateChanges)
&& pSSM)
rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_DESCENDING | VMMEMTRENDEZVOUS_FLAGS_STOP_ON_ERROR,
RTThreadSleep(250); /** @todo Live Migration: fix this polling wait by some smart use of multiple release event semaphores.. */
rc2 = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ONCE, vmR3LiveDoStep1Cleanup, pfSuspended);
return rc;
VMMR3DECL(int) VMR3Save(PVM pVM, const char *pszFilename, bool fContinueAfterwards, PFNVMPROGRESS pfnProgress, void *pvUser, bool *pfSuspended)
LogFlow(("VMR3Save: pVM=%p pszFilename=%p:{%s} fContinueAfterwards=%RTbool pfnProgress=%p pvUser=%p pfSuspended=%p\n",
*pfSuspended = false;
return rc;
VMMR3DECL(int) VMR3SaveFT(PVM pVM, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser, bool *pfSuspended,
bool fSkipStateChanges)
*pfSuspended = false;
return rc;
VMMR3DECL(int) VMR3Teleport(PVM pVM, uint32_t cMsMaxDowntime, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser,
LogFlow(("VMR3Teleport: pVM=%p cMsMaxDowntime=%u pStreamOps=%p pvStreamOps=%p pfnProgress=%p pvProgressUser=%p\n",
*pfSuspended = false;
return rc;
static DECLCALLBACK(int) vmR3Load(PVM pVM, const char *pszFilename, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser,
bool fSkipStateChanges)
LogFlow(("vmR3Load: pVM=%p pszFilename=%p:{%s} pStreamOps=%p pvStreamOpsUser=%p pfnProgress=%p pvProgressUser=%p fTeleporting=%RTbool\n",
pVM, pszFilename, pszFilename, pStreamOps, pvStreamOpsUser, pfnProgress, pvProgressUser, fTeleporting));
if (!fSkipStateChanges)
return rc;
rc = SSMR3Load(pVM, pszFilename, pStreamOps, pvStreamOpsUser, SSMAFTER_RESUME, pfnProgress, pvProgressUser);
if (!fSkipStateChanges)
if (!fSkipStateChanges)
return rc;
VMMR3DECL(int) VMR3LoadFromFile(PVM pVM, const char *pszFilename, PFNVMPROGRESS pfnProgress, void *pvUser)
pVM, pszFilename, (uintptr_t)NULL /*pStreamOps*/, (uintptr_t)NULL /*pvStreamOpsUser*/, pfnProgress, pvUser,
return rc;
LogFlow(("VMR3LoadFromStream: pVM=%p pStreamOps=%p pvStreamOpsUser=%p pfnProgress=%p pvProgressUser=%p\n",
return rc;
return rc;
return rc;
return VINF_EM_OFF;
int rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_DESCENDING | VMMEMTRENDEZVOUS_FLAGS_STOP_ON_ERROR,
return rc;
if (!pVM)
return VERR_INVALID_VM_HANDLE;
return rc;
return VINF_SUCCESS;
#ifdef VBOX_WITH_STATISTICS
#ifdef VBOX_WITH_DEBUGGER
return VINF_EM_TERMINATE;
NULL);
unsigned cReqs = 0;
AssertMsg(!pReqHead, ("This isn't supposed to happen! VMR3Destroy caller has to serialize this.\n"));
if (!pReqHead)
AssertMsg(!pReqHead, ("This isn't supposed to happen! VMR3Destroy caller has to serialize this.\n"));
if (!pReqHead)
#ifdef LOG_ENABLED
if (pVMPrev)
while (pCur)
return VERR_INVALID_PARAMETER;
if (!pVMAtDtor)
return VERR_NO_MEMORY;
return VINF_SUCCESS;
while (pCur)
if (pPrev)
return VINF_SUCCESS;
return VERR_INVALID_PARAMETER;
#ifdef VBOX_STRICT
return rc;
#ifdef LOG_ENABLED
: VINF_EM_SUSPEND; /** @todo VINF_EM_SUSPEND has lower priority than VINF_EM_RESET, so fix races. Perhaps add a new code for this combined case. */
int rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_DESCENDING | VMMEMTRENDEZVOUS_FLAGS_STOP_ON_ERROR,
return rc;
return cRefs;
if (!pUVM)
if (!cRefs)
return cRefs;
return pUuid;
return VMSTATE_TERMINATED;
switch (enmState)
#ifdef VBOX_STRICT
switch (enmStateOld)
case VMSTATE_CREATING:
AssertMsgReturn(enmStateNew == VMSTATE_CREATED, ("%s -> %s\n", VMR3GetStateName(enmStateOld), VMR3GetStateName(enmStateNew)), false);
case VMSTATE_CREATED:
case VMSTATE_LOADING:
case VMSTATE_POWERING_ON:
case VMSTATE_RESUMING:
case VMSTATE_RUNNING:
case VMSTATE_RUNNING_LS:
case VMSTATE_RUNNING_FT:
case VMSTATE_RESETTING:
AssertMsgReturn(enmStateNew == VMSTATE_RUNNING, ("%s -> %s\n", VMR3GetStateName(enmStateOld), VMR3GetStateName(enmStateNew)), false);
case VMSTATE_RESETTING_LS:
case VMSTATE_SUSPENDING:
AssertMsgReturn(enmStateNew == VMSTATE_SUSPENDED, ("%s -> %s\n", VMR3GetStateName(enmStateOld), VMR3GetStateName(enmStateNew)), false);
case VMSTATE_SUSPENDING_LS:
case VMSTATE_SUSPENDED:
case VMSTATE_SUSPENDED_LS:
case VMSTATE_SUSPENDED_EXT_LS:
case VMSTATE_SAVING:
AssertMsgReturn(enmStateNew == VMSTATE_SUSPENDED, ("%s -> %s\n", VMR3GetStateName(enmStateOld), VMR3GetStateName(enmStateNew)), false);
case VMSTATE_DEBUGGING:
case VMSTATE_DEBUGGING_LS:
case VMSTATE_POWERING_OFF:
AssertMsgReturn(enmStateNew == VMSTATE_OFF, ("%s -> %s\n", VMR3GetStateName(enmStateOld), VMR3GetStateName(enmStateNew)), false);
case VMSTATE_POWERING_OFF_LS:
case VMSTATE_OFF:
AssertMsgReturn(enmStateNew == VMSTATE_DESTROYING, ("%s -> %s\n", VMR3GetStateName(enmStateOld), VMR3GetStateName(enmStateNew)), false);
case VMSTATE_OFF_LS:
AssertMsgReturn(enmStateNew == VMSTATE_OFF, ("%s -> %s\n", VMR3GetStateName(enmStateOld), VMR3GetStateName(enmStateNew)), false);
case VMSTATE_FATAL_ERROR:
AssertMsgReturn(enmStateNew == VMSTATE_POWERING_OFF, ("%s -> %s\n", VMR3GetStateName(enmStateOld), VMR3GetStateName(enmStateNew)), false);
case VMSTATE_FATAL_ERROR_LS:
case VMSTATE_GURU_MEDITATION:
case VMSTATE_LOAD_FAILURE:
AssertMsgReturn(enmStateNew == VMSTATE_POWERING_OFF, ("%s -> %s\n", VMR3GetStateName(enmStateOld), VMR3GetStateName(enmStateNew)), false);
case VMSTATE_DESTROYING:
AssertMsgReturn(enmStateNew == VMSTATE_TERMINATED, ("%s -> %s\n", VMR3GetStateName(enmStateOld), VMR3GetStateName(enmStateNew)), false);
case VMSTATE_TERMINATED:
AssertMsgFailedReturn(("%s -> %s\n", VMR3GetStateName(enmStateOld), VMR3GetStateName(enmStateNew)), false);
LogRel(("Changing the VM state from '%s' to '%s'.\n", VMR3GetStateName(enmStateOld), VMR3GetStateName(enmStateNew)));
#ifdef VBOX_STRICT
for (unsigned i = 0; i < cTransitions; i++)
for (unsigned i = 0; i < cTransitions; i++)
pszWho, VMR3GetStateName(enmStateOld), VMR3GetStateName(enmStateNew), VMR3GetStateName(enmStateCur)));
pszWho, VMR3GetStateName(enmStateOld), VMR3GetStateName(enmStateNew), VMR3GetStateName(enmStateCur)));
for (unsigned i = 0; i < cTransitions; i++)
AssertMsgFailed(("%s - state=%s, see release log for full details. Check the cTransitions passed us.\n",
return rc;
* immediately by the VMM and not by VMEmt.cpp when it's all over.
if (!pNew)
return VERR_NO_MEMORY;
return VINF_SUCCESS;
while ( pCur
if (!pCur)
return VERR_FILE_NOT_FOUND;
if (pPrev)
return VINF_SUCCESS;
if (!pNew)
return VERR_NO_MEMORY;
return VINF_SUCCESS;
while ( pCur
if (!pCur)
return VERR_FILE_NOT_FOUND;
if (pPrev)
return VINF_SUCCESS;
static void vmR3SetErrorWorkerDoCall(PVM pVM, PVMATERROR pCur, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...)
AssertReleaseMsgFailed(("And we have a winner! You get to implement Ring-0 and GC VMSetErrorV! Contracts!\n"));
const char *pszMessage;
if (pErr)
return rc;
DECLCALLBACK(void) vmR3SetErrorUV(PUVM pUVM, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list *pArgs)
#ifdef LOG_ENABLED
bool fCalledSomeone = false;
fCalledSomeone = true;
VMMR3DECL(int) VMR3AtRuntimeErrorRegister(PVM pVM, PFNVMATRUNTIMEERROR pfnAtRuntimeError, void *pvUser)
LogFlow(("VMR3AtRuntimeErrorRegister: pfnAtRuntimeError=%p pvUser=%p\n", pfnAtRuntimeError, pvUser));
if (!pNew)
return VERR_NO_MEMORY;
return VINF_SUCCESS;
VMMR3DECL(int) VMR3AtRuntimeErrorDeregister(PVM pVM, PFNVMATRUNTIMEERROR pfnAtRuntimeError, void *pvUser)
LogFlow(("VMR3AtRuntimeErrorDeregister: pfnAtRuntimeError=%p pvUser=%p\n", pfnAtRuntimeError, pvUser));
while ( pCur
if (!pCur)
return VERR_FILE_NOT_FOUND;
if (pPrev)
return VINF_SUCCESS;
static DECLCALLBACK(VBOXSTRICTRC) vmR3SetRuntimeErrorChangeState(PVM pVM, PVMCPU pVCpu, void *pvUser)
return rc;
return VINF_EM_SUSPEND;
static int vmR3SetRuntimeErrorCommon(PVM pVM, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list *pVa)
int rc;
rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_DESCENDING | VMMEMTRENDEZVOUS_FLAGS_STOP_ON_ERROR,
return rc;
static int vmR3SetRuntimeErrorCommonF(PVM pVM, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...)
return rc;
AssertReleaseMsgFailed(("And we have a winner! You get to implement Ring-0 and GC VMSetRuntimeErrorV! Congrats!\n"));
if (pErr)
DECLCALLBACK(int) vmR3SetRuntimeError(PVM pVM, uint32_t fFlags, const char *pszErrorId, char *pszMessage)
return rc;
DECLCALLBACK(int) vmR3SetRuntimeErrorV(PVM pVM, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list *pVa)
return pUVCpu
: NIL_VMCPUID;
if (!pUVCpu)
return NIL_RTNATIVETHREAD;
if (!pUVCpu)
return NIL_RTNATIVETHREAD;
if (!pUVCpu)
return NIL_RTTHREAD;
if (!pUVCpu)
return NIL_RTTHREAD;
VMMR3DECL(int) VMR3GetCpuCoreAndPackageIdFromCpuId(PVM pVM, VMCPUID idCpu, uint32_t *pidCpuCore, uint32_t *pidCpuPackage)
return VERR_INVALID_CPU_ID;
#ifdef VBOX_WITH_MULTI_CORE
*pidCpuPackage = 0;
*pidCpuCore = 0;
return VINF_SUCCESS;
return VINF_EM_WAIT_SIPI;
return VINF_SUCCESS;
return VINF_SUCCESS;