VirtualBox

Changeset 36041 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Feb 21, 2011 4:04:53 PM (14 years ago)
Author:
vboxsync
Message:

Main/VMM: Use UVM w/ refcounting - part 1.

Location:
trunk/src/VBox
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/include/ConsoleImpl.h

    r35965 r36041  
    271271        }
    272272        /** Decreases the number of callers before the instance is destroyed. */
    273         void release()
     273        void releaseCaller()
    274274        {
    275275            AssertReturnVoid(SUCCEEDED(mRC));
     
    279279        /** Restores the number of callers after by #release(). #rc() must be
    280280         *  rechecked to ensure the operation succeeded. */
    281         void add()
     281        void addYY()
    282282        {
    283283            AssertReturnVoid(!SUCCEEDED(mRC));
     
    293293    private:
    294294        DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP(AutoVMCallerBase)
    295         DECLARE_CLS_NEW_DELETE_NOOP(AutoVMCallerBase)
    296295    };
    297296
     297#if 0
    298298    /**
    299299     *  Helper class that protects sections of code using the mpVM pointer by
     
    311311     *
    312312     *  @sa SafeVMPtr, SafeVMPtrQuiet
     313     *  @obsolete Use SafeVMPtr
    313314     */
    314315    typedef AutoVMCallerBase<false, false> AutoVMCaller;
     316#endif
    315317
    316318    /**
     
    318320     *
    319321     *  @note Temporarily locks the argument for writing.
     322    *  @obsolete Use SafeVMPtrQuiet
    320323     */
    321324    typedef AutoVMCallerBase<true, false> AutoVMCallerQuiet;
     
    326329     *
    327330     *  @note Temporarily locks the argument for writing.
     331     *  @obsolete Use SafeVMPtr
    328332     */
    329333    typedef AutoVMCallerBase<false, true> AutoVMCallerWeak;
     
    335339     *
    336340     *  @note Temporarily locks the argument for writing.
     341     *  @obsolete Use SafeVMPtrQuiet
    337342     */
    338343    typedef AutoVMCallerBase<true, true> AutoVMCallerQuietWeak;
     
    346351        typedef AutoVMCallerBase<taQuiet, true> Base;
    347352    public:
    348         SafeVMPtrBase(Console *aThat) : Base(aThat), mpVM(NULL)
     353        SafeVMPtrBase(Console *aThat) : Base(aThat), mpVM(NULL), mpUVM(NULL)
    349354        {
    350355            if (SUCCEEDED(Base::mRC))
    351             {
    352                 mpVM = aThat->mpVM;
    353                 if (!mpVM)
    354                     Base::mRC = E_FAIL; /** @todo use setError here. */
    355             }
     356                Base::mRC = aThat->safeVMPtrRetainer(&mpVM, &mpUVM, taQuiet);
     357        }
     358        ~SafeVMPtrBase()
     359        {
     360            if (SUCCEEDED(Base::mRC))
     361                release();
    356362        }
    357363        /** Smart SaveVMPtr to PVM cast operator */
     
    359365        /** Direct PVM access for printf()-like functions */
    360366        PVM raw() const { return mpVM; }
     367        /** Direct PUVM access for printf()-like functions */
     368        PUVM rawUVM() const { return mpUVM; }
     369        /** Release the handles. */
     370        void release()
     371        {
     372            AssertReturnVoid(SUCCEEDED(Base::mRC));
     373            Base::mThat->safeVMPtrReleaser(&mpVM, &mpUVM);
     374            Base::releaseCaller();
     375        }
     376
    361377    private:
    362         PVM mpVM;
     378        PVM     mpVM;
     379        PUVM    mpUVM;
    363380        DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP(SafeVMPtrBase)
    364         DECLARE_CLS_NEW_DELETE_NOOP(SafeVMPtrBase)
    365381    };
    366382
     
    438454
    439455    HRESULT addVMCaller(bool aQuiet = false, bool aAllowNullVM = false);
    440     void releaseVMCaller();
     456    void    releaseVMCaller();
     457    HRESULT safeVMPtrRetainer(PVM *a_ppVM, PUVM *a_ppUVM, bool aQuiet);
     458    void    safeVMPtrReleaser(PVM *a_ppVM, PUVM *a_ppUVM);
    441459
    442460    HRESULT consoleInitReleaseLog(const ComPtr<IMachine> aMachine);
     
    515533                                                         HRESULT *phrc);
    516534    static DECLCALLBACK(int) changeRemovableMedium(Console *pThis,
     535                                                   PVM pVM,
    517536                                                   const char *pcszDevice,
    518537                                                   unsigned uInstance,
     
    531550    static DECLCALLBACK(void) vmstateChangeCallback(PVM aVM, VMSTATE aState,
    532551                                                    VMSTATE aOldState, void *aUser);
    533     static DECLCALLBACK(int) unplugCpu(Console *pThis, unsigned uCpu);
    534     static DECLCALLBACK(int) plugCpu(Console *pThis, unsigned uCpu);
    535     HRESULT doMediumChange(IMediumAttachment *aMediumAttachment, bool fForce);
    536     HRESULT doCPURemove(ULONG aCpu);
    537     HRESULT doCPUAdd(ULONG aCpu);
    538 
    539     HRESULT doNetworkAdapterChange(const char *pszDevice, unsigned uInstance,
     552    static DECLCALLBACK(int) unplugCpu(Console *pThis, PVM pVM, unsigned uCpu);
     553    static DECLCALLBACK(int) plugCpu(Console *pThis, PVM pVM, unsigned uCpu);
     554    HRESULT doMediumChange(IMediumAttachment *aMediumAttachment, bool fForce, PVM pVM);
     555    HRESULT doCPURemove(ULONG aCpu, PVM pVM);
     556    HRESULT doCPUAdd(ULONG aCpu, PVM pVM);
     557
     558    HRESULT doNetworkAdapterChange(PVM pVM, const char *pszDevice, unsigned uInstance,
    540559                                   unsigned uLun, INetworkAdapter *aNetworkAdapter);
    541     static DECLCALLBACK(int) changeNetworkAttachment(Console *pThis, const char *pszDevice,
     560    static DECLCALLBACK(int) changeNetworkAttachment(Console *pThis, PVM pVM, const char *pszDevice,
    542561                                                     unsigned uInstance, unsigned uLun,
    543562                                                     INetworkAdapter *aNetworkAdapter);
     
    547566    HRESULT detachUSBDevice(USBDeviceList::iterator &aIt);
    548567
    549     static DECLCALLBACK(int) usbAttachCallback(Console *that, IUSBDevice *aHostDevice, PCRTUUID aUuid,
     568    static DECLCALLBACK(int) usbAttachCallback(Console *that, PVM pVM, IUSBDevice *aHostDevice, PCRTUUID aUuid,
    550569                       bool aRemote, const char *aAddress, ULONG aMaskedIfs);
    551     static DECLCALLBACK(int) usbDetachCallback(Console *that, USBDeviceList::iterator *aIt, PCRTUUID aUuid);
     570    static DECLCALLBACK(int) usbDetachCallback(Console *that, PVM pVM, USBDeviceList::iterator *aIt, PCRTUUID aUuid);
    552571#endif
    553572
     
    559578                                                          const char *pszErrorFmt, va_list va);
    560579
    561     static DECLCALLBACK(void) setVMRuntimeErrorCallbackF(PVM pVM, void *pvUser, uint32_t fFatal,
    562                                const char *pszErrorId,
    563                                const char *pszFormat, ...);
    564     static DECLCALLBACK(void) setVMRuntimeErrorCallback(PVM pVM, void *pvUser, uint32_t fFatal,
    565                                const char *pszErrorId,
    566                                const char *pszFormat, va_list va);
     580    static void                 setVMRuntimeErrorCallbackF(PVM pVM, void *pvUser, uint32_t fFatal,
     581                                                          const char *pszErrorId, const char *pszFormat, ...);
     582    static DECLCALLBACK(void)   setVMRuntimeErrorCallback(PVM pVM, void *pvUser, uint32_t fFatal,
     583                                                          const char *pszErrorId, const char *pszFormat, va_list va);
    567584
    568585    HRESULT                     captureUSBDevices(PVM pVM);
     
    613630    HRESULT                     teleporterSrcReadACK(TeleporterStateSrc *pState, const char *pszWhich, const char *pszNAckMsg = NULL);
    614631    HRESULT                     teleporterSrcSubmitCommand(TeleporterStateSrc *pState, const char *pszCommand, bool fWaitForAck = true);
    615     HRESULT                     teleporterTrg(PVM pVM, IMachine *pMachine, Utf8Str *pErrorMsg, bool fStartPaused,
     632    HRESULT                     teleporterTrg(PUVM pUVM, IMachine *pMachine, Utf8Str *pErrorMsg, bool fStartPaused,
    616633                                              Progress *pProgress, bool *pfPowerOffOnFailure);
    617634    static DECLCALLBACK(int)    teleporterTrgServeConnection(RTSOCKET Sock, void *pvUser);
     
    645662    SharedFolderMap m_mapSharedFolders;             // the console instances
    646663
    647     /** The VM instance handle. */
    648     PVM mpVM;
     664    /** The user mode VM handle. */
     665    PUVM mpUVM;
    649666    /** Holds the number of "readonly" mpVM callers (users) */
    650667    uint32_t mVMCallers;
  • trunk/src/VBox/Main/src-client/ConsoleImpl.cpp

    r35965 r36041  
    137137 *
    138138 * If \a aUsesVMPtr parameter is true, the task structure will also add itself
    139  * as a Console::mpVM caller with the same meaning as above. See
     139 * as a Console::mpUVM caller with the same meaning as above. See
    140140 * Console::addVMCaller() for more info.
    141141 */
     
    150150          mProgress(aProgress),
    151151          mServerProgress(aServerProgress),
    152           mVMCallerAdded(false)
     152          mpVM(NULL),
     153          mRC(E_FAIL),
     154          mpSafeVMPtr(NULL)
    153155    {
    154156        AssertReturnVoid(aConsole);
     
    158160        if (aUsesVMPtr)
    159161        {
    160             mRC = aConsole->addVMCaller();
    161             if (SUCCEEDED(mRC))
    162                 mVMCallerAdded = true;
     162            mpSafeVMPtr = new Console::SafeVMPtr(aConsole);
     163            if (mpSafeVMPtr->isOk())
     164                mpVM = mpSafeVMPtr->raw();
     165            else
     166                mRC = mpSafeVMPtr->rc();
    163167        }
    164168    }
     
    166170    ~VMTask()
    167171    {
    168         if (mVMCallerAdded)
    169             mConsole->releaseVMCaller();
     172        releaseVMCaller();
    170173    }
    171174
     
    176179    void releaseVMCaller()
    177180    {
    178         AssertReturnVoid(mVMCallerAdded);
    179         mConsole->releaseVMCaller();
    180         mVMCallerAdded = false;
    181     }
    182 
    183     const ComObjPtr<Console> mConsole;
    184     AutoCaller mConsoleCaller;
    185     const ComObjPtr<Progress> mProgress;
    186     Utf8Str mErrorMsg;
    187     const ComPtr<IProgress> mServerProgress;
     181        if (mpSafeVMPtr)
     182        {
     183            delete mpSafeVMPtr;
     184            mpSafeVMPtr = NULL;
     185        }
     186    }
     187
     188    const ComObjPtr<Console>    mConsole;
     189    AutoCaller                  mConsoleCaller;
     190    const ComObjPtr<Progress>   mProgress;
     191    Utf8Str                     mErrorMsg;
     192    const ComPtr<IProgress>     mServerProgress;
     193    PVM                         mpVM;
    188194
    189195private:
    190 
    191     HRESULT mRC;
    192     bool mVMCallerAdded : 1;
     196    HRESULT                     mRC;
     197    Console::SafeVMPtr         *mpSafeVMPtr;
    193198};
    194199
     
    350355    : mSavedStateDataLoaded(false)
    351356    , mConsoleVRDPServer(NULL)
    352     , mpVM(NULL)
     357    , mpUVM(NULL)
    353358    , mVMCallers(0)
    354359    , mVMZeroCallersSem(NIL_RTSEMEVENT)
     
    567572
    568573    /* power down the VM if necessary */
    569     if (mpVM)
     574    if (mpUVM)
    570575    {
    571576        powerDown();
    572         Assert(mpVM == NULL);
     577        Assert(mpUVM == NULL);
    573578    }
    574579
     
    19081913        return setInvalidMachineStateError();
    19091914
    1910     /* protect mpVM */
    1911     AutoVMCaller autoVMCaller(this);
    1912     if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
     1915    /* protect mpUVM */
     1916    SafeVMPtr ptrVM(this);
     1917    if (!ptrVM.isOk())
     1918        return ptrVM.rc();
    19131919
    19141920    /* leave the lock before a VMR3* call (EMT will call us back)! */
    19151921    alock.leave();
    19161922
    1917     int vrc = VMR3Reset(mpVM);
     1923    int vrc = VMR3Reset(ptrVM);
    19181924
    19191925    HRESULT rc = RT_SUCCESS(vrc) ? S_OK :
     
    19271933}
    19281934
    1929 DECLCALLBACK(int) Console::unplugCpu(Console *pThis, unsigned uCpu)
    1930 {
    1931     LogFlowFunc(("pThis=%p uCpu=%u\n", pThis, uCpu));
     1935/*static*/ DECLCALLBACK(int) Console::unplugCpu(Console *pThis, PVM pVM, unsigned uCpu)
     1936{
     1937    LogFlowFunc(("pThis=%p pVM=%p uCpu=%u\n", pThis, pVM, uCpu));
    19321938
    19331939    AssertReturn(pThis, VERR_INVALID_PARAMETER);
    19341940
    1935     int vrc = PDMR3DeviceDetach(pThis->mpVM, "acpi", 0, uCpu, 0);
     1941    int vrc = PDMR3DeviceDetach(pVM, "acpi", 0, uCpu, 0);
    19361942    Log(("UnplugCpu: rc=%Rrc\n", vrc));
    19371943
     
    19391945}
    19401946
    1941 HRESULT Console::doCPURemove(ULONG aCpu)
     1947HRESULT Console::doCPURemove(ULONG aCpu, PVM pVM)
    19421948{
    19431949    HRESULT rc = S_OK;
     
    19521958
    19531959    AssertReturn(m_pVMMDev, E_FAIL);
    1954     PPDMIVMMDEVPORT pDevPort = m_pVMMDev->getVMMDevPort();
    1955     AssertReturn(pDevPort, E_FAIL);
     1960    PPDMIVMMDEVPORT pVmmDevPort = m_pVMMDev->getVMMDevPort();
     1961    AssertReturn(pVmmDevPort, E_FAIL);
    19561962
    19571963    if (   mMachineState != MachineState_Running
     
    19611967        return setInvalidMachineStateError();
    19621968
    1963     /* protect mpVM */
    1964     AutoVMCaller autoVMCaller(this);
    1965     if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
    1966 
    19671969    /* Check if the CPU is present */
    19681970    BOOL fCpuAttached;
    19691971    rc = mMachine->GetCPUStatus(aCpu, &fCpuAttached);
    1970     if (FAILED(rc)) return rc;
    1971 
     1972    if (FAILED(rc))
     1973        return rc;
    19721974    if (!fCpuAttached)
    1973         return setError(E_FAIL,
    1974                         tr("CPU %d is not attached"), aCpu);
     1975        return setError(E_FAIL, tr("CPU %d is not attached"), aCpu);
    19751976
    19761977    /* Leave the lock before any EMT/VMMDev call. */
    19771978    alock.release();
     1979    bool fLocked = true;
    19781980
    19791981    /* Check if the CPU is unlocked */
    19801982    PPDMIBASE pBase;
    1981     int vrc = PDMR3QueryDeviceLun(mpVM, "acpi", 0, aCpu, &pBase);
    1982     bool fLocked = true;
     1983    int vrc = PDMR3QueryDeviceLun(pVM, "acpi", 0, aCpu, &pBase);
    19831984    if (RT_SUCCESS(vrc))
    19841985    {
     1986        Assert(pBase);
     1987        PPDMIACPIPORT pApicPort = PDMIBASE_QUERY_INTERFACE(pBase, PDMIACPIPORT);
     1988
     1989        /* Notify the guest if possible. */
    19851990        uint32_t idCpuCore, idCpuPackage;
    1986 
    1987         /* Notify the guest if possible. */
    1988         vrc = VMR3GetCpuCoreAndPackageIdFromCpuId(mpVM, aCpu, &idCpuCore, &idCpuPackage);
    1989         AssertRC(vrc);
    1990 
    1991         Assert(pBase);
    1992 
    1993         PPDMIACPIPORT pPort = PDMIBASE_QUERY_INTERFACE(pBase, PDMIACPIPORT);
    1994 
    1995         vrc = pDevPort->pfnCpuHotUnplug(pDevPort, idCpuCore, idCpuPackage);
     1991        vrc = VMR3GetCpuCoreAndPackageIdFromCpuId(pVM, aCpu, &idCpuCore, &idCpuPackage); AssertRC(vrc);
    19961992        if (RT_SUCCESS(vrc))
     1993            vrc = pVmmDevPort->pfnCpuHotUnplug(pVmmDevPort, idCpuCore, idCpuPackage);
     1994        if (RT_SUCCESS(vrc))
    19971995        {
    19981996            unsigned cTries = 100;
    1999 
    20001997            do
    20011998            {
    2002                 /* It will take some time until the event is processed in the guest. Wait  */
    2003                 vrc = pPort ? pPort->pfnGetCpuStatus(pPort, aCpu, &fLocked) : VERR_INVALID_POINTER;
    2004 
     1999                /* It will take some time until the event is processed in the guest. Wait...  */
     2000                vrc = pApicPort ? pApicPort->pfnGetCpuStatus(pApicPort, aCpu, &fLocked) : VERR_INVALID_POINTER;
    20052001                if (RT_SUCCESS(vrc) && !fLocked)
    20062002                    break;
     
    20132009        {
    20142010            /* Query one time. It is possible that the user ejected the CPU. */
    2015             vrc = pPort ? pPort->pfnGetCpuStatus(pPort, aCpu, &fLocked) : VERR_INVALID_POINTER;
     2011            vrc = pApicPort ? pApicPort->pfnGetCpuStatus(pApicPort, aCpu, &fLocked) : VERR_INVALID_POINTER;
    20162012        }
    20172013    }
     
    20252021         */
    20262022        PVMREQ pReq;
    2027         vrc = VMR3ReqCall(mpVM, 0, &pReq, 0 /* no wait! */, VMREQFLAGS_VBOX_STATUS,
    2028                           (PFNRT)Console::unplugCpu, 2,
    2029                           this, aCpu);
    2030 
     2023        vrc = VMR3ReqCall(pVM, 0, &pReq, 0 /* no wait! */, VMREQFLAGS_VBOX_STATUS,
     2024                          (PFNRT)Console::unplugCpu, 3,
     2025                          this, pVM, aCpu);
    20312026        if (vrc == VERR_TIMEOUT || RT_SUCCESS(vrc))
    20322027        {
     
    20412036        {
    20422037            /* Detach it from the VM  */
    2043             vrc = VMR3HotUnplugCpu(mpVM, aCpu);
     2038            vrc = VMR3HotUnplugCpu(pVM, aCpu);
    20442039            AssertRC(vrc);
    20452040        }
     
    20572052}
    20582053
    2059 DECLCALLBACK(int) Console::plugCpu(Console *pThis, unsigned uCpu)
     2054/*static*/ DECLCALLBACK(int) Console::plugCpu(Console *pThis, PVM pVM, unsigned uCpu)
    20602055{
    20612056    LogFlowFunc(("pThis=%p uCpu=%u\n", pThis, uCpu));
     
    20632058    AssertReturn(pThis, VERR_INVALID_PARAMETER);
    20642059
    2065     int rc = VMR3HotPlugCpu(pThis->mpVM, uCpu);
     2060    int rc = VMR3HotPlugCpu(pVM, uCpu);
    20662061    AssertRC(rc);
    20672062
    2068     PCFGMNODE pInst = CFGMR3GetChild(CFGMR3GetRoot(pThis->mpVM), "Devices/acpi/0/");
     2063    PCFGMNODE pInst = CFGMR3GetChild(CFGMR3GetRoot(pVM), "Devices/acpi/0/");
    20692064    AssertRelease(pInst);
    20702065    /* nuke anything which might have been left behind. */
     
    20832078     */
    20842079    PPDMIBASE pBase;
    2085     rc = PDMR3DeviceAttach(pThis->mpVM, "acpi", 0, uCpu, 0, &pBase); RC_CHECK();
     2080    rc = PDMR3DeviceAttach(pVM, "acpi", 0, uCpu, 0, &pBase); RC_CHECK();
    20862081
    20872082    Log(("PlugCpu: rc=%Rrc\n", rc));
     
    20942089}
    20952090
    2096 HRESULT Console::doCPUAdd(ULONG aCpu)
     2091HRESULT Console::doCPUAdd(ULONG aCpu, PVM pVM)
    20972092{
    20982093    HRESULT rc = S_OK;
     
    21172112    AssertReturn(pDevPort, E_FAIL);
    21182113
    2119     /* protect mpVM */
    2120     AutoVMCaller autoVMCaller(this);
    2121     if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
    2122 
    21232114    /* Check if the CPU is present */
    21242115    BOOL fCpuAttached;
     
    21362127     */
    21372128    PVMREQ pReq;
    2138     int vrc = VMR3ReqCall(mpVM, 0, &pReq, 0 /* no wait! */, VMREQFLAGS_VBOX_STATUS,
    2139                           (PFNRT)Console::plugCpu, 2,
    2140                           this, aCpu);
     2129    int vrc = VMR3ReqCall(pVM, 0, &pReq, 0 /* no wait! */, VMREQFLAGS_VBOX_STATUS,
     2130                          (PFNRT)Console::plugCpu, 3,
     2131                          this, pVM, aCpu);
    21412132
    21422133    /* leave the lock before a VMR3* call (EMT will call us back)! */
     
    21592150    if (RT_SUCCESS(vrc))
    21602151    {
     2152        /* Notify the guest if possible. */
    21612153        uint32_t idCpuCore, idCpuPackage;
    2162 
    2163         /* Notify the guest if possible. */
    2164         vrc = VMR3GetCpuCoreAndPackageIdFromCpuId(mpVM, aCpu, &idCpuCore, &idCpuPackage);
    2165         AssertRC(vrc);
    2166 
    2167         vrc = pDevPort->pfnCpuHotPlug(pDevPort, idCpuCore, idCpuPackage);
     2154        vrc = VMR3GetCpuCoreAndPackageIdFromCpuId(pVM, aCpu, &idCpuCore, &idCpuPackage); AssertRC(vrc);
     2155        if (RT_SUCCESS(vrc))
     2156            vrc = pDevPort->pfnCpuHotPlug(pDevPort, idCpuCore, idCpuPackage);
    21682157        /** @todo warning if the guest doesn't support it */
    21692158    }
     
    21992188    }
    22002189
    2201     /* protect mpVM */
    2202     AutoVMCaller autoVMCaller(this);
    2203     if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
     2190    /* get the VM handle. */
     2191    SafeVMPtr ptrVM(this);
     2192    if (!ptrVM.isOk())
     2193        return ptrVM.rc();
    22042194
    22052195    LogFlowThisFunc(("Sending PAUSE request...\n"));
     
    22082198    alock.leave();
    22092199
    2210     int vrc = VMR3Suspend(mpVM);
     2200    int vrc = VMR3Suspend(ptrVM);
    22112201
    22122202    HRESULT hrc = S_OK;
     
    22332223                        Global::stringifyMachineState(mMachineState));
    22342224
    2235     /* protect mpVM */
    2236     AutoVMCaller autoVMCaller(this);
    2237     if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
     2225    /* get the VM handle. */
     2226    SafeVMPtr ptrVM(this);
     2227    if (!ptrVM.isOk())
     2228        return ptrVM.rc();
    22382229
    22392230    LogFlowThisFunc(("Sending RESUME request...\n"));
     
    22432234
    22442235#ifdef VBOX_WITH_EXTPACK
    2245     int vrc = mptrExtPackManager->callAllVmPowerOnHooks(this, mpVM); /** @todo called a few times too many... */
     2236    int vrc = mptrExtPackManager->callAllVmPowerOnHooks(this, ptrVM); /** @todo called a few times too many... */
    22462237#else
    22472238    int vrc = VINF_SUCCESS;
     
    22492240    if (RT_SUCCESS(vrc))
    22502241    {
    2251         if (VMR3GetState(mpVM) == VMSTATE_CREATED)
    2252             vrc = VMR3PowerOn(mpVM); /* (PowerUpPaused) */
     2242        if (VMR3GetState(ptrVM) == VMSTATE_CREATED)
     2243            vrc = VMR3PowerOn(ptrVM); /* (PowerUpPaused) */
    22532244        else
    2254             vrc = VMR3Resume(mpVM);
     2245            vrc = VMR3Resume(ptrVM);
    22552246    }
    22562247
     
    22802271        return setInvalidMachineStateError();
    22812272
    2282     /* protect mpVM */
    2283     AutoVMCaller autoVMCaller(this);
    2284     if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
    2285 
     2273    /* get the VM handle. */
     2274    SafeVMPtr ptrVM(this);
     2275    if (!ptrVM.isOk())
     2276        return ptrVM.rc();
     2277/** @todo leave the console lock? */
     2278
     2279    /* get the acpi device interface and press the button. */
    22862280    PPDMIBASE pBase;
    2287     int vrc = PDMR3QueryDeviceLun(mpVM, "acpi", 0, 0, &pBase);
     2281    int vrc = PDMR3QueryDeviceLun(ptrVM, "acpi", 0, 0, &pBase);
    22882282    if (RT_SUCCESS(vrc))
    22892283    {
    22902284        Assert(pBase);
    22912285        PPDMIACPIPORT pPort = PDMIBASE_QUERY_INTERFACE(pBase, PDMIACPIPORT);
    2292         vrc = pPort ? pPort->pfnPowerButtonPress(pPort) : VERR_INVALID_POINTER;
     2286        if (pPort)
     2287            vrc = pPort->pfnPowerButtonPress(pPort);
     2288        else
     2289            vrc = VERR_PDM_MISSING_INTERFACE;
    22932290    }
    22942291
     
    23212318        return setInvalidMachineStateError();
    23222319
    2323     /* protect mpVM */
    2324     AutoVMCaller autoVMCaller(this);
    2325     if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
    2326 
     2320    /* get the VM handle. */
     2321    SafeVMPtr ptrVM(this);
     2322    if (!ptrVM.isOk())
     2323        return ptrVM.rc();
     2324/** @todo leave the console lock? */
     2325
     2326    /* get the acpi device interface and check if the button press was handled. */
    23272327    PPDMIBASE pBase;
    2328     int vrc = PDMR3QueryDeviceLun(mpVM, "acpi", 0, 0, &pBase);
    2329     bool handled = false;
     2328    int vrc = PDMR3QueryDeviceLun(ptrVM, "acpi", 0, 0, &pBase);
    23302329    if (RT_SUCCESS(vrc))
    23312330    {
    23322331        Assert(pBase);
    23332332        PPDMIACPIPORT pPort = PDMIBASE_QUERY_INTERFACE(pBase, PDMIACPIPORT);
    2334         vrc = pPort ? pPort->pfnGetPowerButtonHandled(pPort, &handled) : VERR_INVALID_POINTER;
     2333        if (pPort)
     2334        {
     2335            bool fHandled = false;
     2336            vrc = pPort->pfnGetPowerButtonHandled(pPort, &fHandled);
     2337            if (RT_SUCCESS(vrc))
     2338                *aHandled = fHandled;
     2339        }
     2340        else
     2341            vrc = VERR_PDM_MISSING_INTERFACE;
    23352342    }
    23362343
     
    23392346            tr("Checking if the ACPI Power Button event was handled by the guest OS failed (%Rrc)"),
    23402347            vrc);
    2341 
    2342     *aHandled = handled;
    23432348
    23442349    LogFlowThisFunc(("rc=%Rhrc\n", rc));
     
    23672372            Global::stringifyMachineState(mMachineState));
    23682373
    2369     /* protect mpVM */
    2370     AutoVMCaller autoVMCaller(this);
    2371     if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
    2372 
     2374    /* get the VM handle. */
     2375    SafeVMPtr ptrVM(this);
     2376    if (!ptrVM.isOk())
     2377        return ptrVM.rc();
     2378
     2379/** @todo leave the console lock? */
     2380
     2381    /* get the acpi device interface and query the information. */
    23732382    PPDMIBASE pBase;
    2374     int vrc = PDMR3QueryDeviceLun(mpVM, "acpi", 0, 0, &pBase);
    2375     bool entered = false;
     2383    int vrc = PDMR3QueryDeviceLun(ptrVM, "acpi", 0, 0, &pBase);
    23762384    if (RT_SUCCESS(vrc))
    23772385    {
    23782386        Assert(pBase);
    23792387        PPDMIACPIPORT pPort = PDMIBASE_QUERY_INTERFACE(pBase, PDMIACPIPORT);
    2380         vrc = pPort ? pPort->pfnGetGuestEnteredACPIMode(pPort, &entered) : VERR_INVALID_POINTER;
    2381     }
    2382 
    2383     *aEntered = RT_SUCCESS(vrc) ? entered : false;
     2388        if (pPort)
     2389        {
     2390            bool fEntered = false;
     2391            vrc = pPort->pfnGetGuestEnteredACPIMode(pPort, &fEntered);
     2392            if (RT_SUCCESS(vrc))
     2393                *aEntered = fEntered;
     2394        }
     2395        else
     2396            vrc = VERR_PDM_MISSING_INTERFACE;
     2397    }
    23842398
    23852399    LogFlowThisFuncLeave();
     
    23992413        return setInvalidMachineStateError();
    24002414
    2401     /* protect mpVM */
    2402     AutoVMCaller autoVMCaller(this);
    2403     if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
    2404 
     2415    /* get the VM handle. */
     2416    SafeVMPtr ptrVM(this);
     2417    if (!ptrVM.isOk())
     2418        return ptrVM.rc();
     2419
     2420/** @todo leave the console lock? */
     2421
     2422    /* get the acpi device interface and press the sleep button. */
    24052423    PPDMIBASE pBase;
    2406     int vrc = PDMR3QueryDeviceLun(mpVM, "acpi", 0, 0, &pBase);
     2424    int vrc = PDMR3QueryDeviceLun(ptrVM, "acpi", 0, 0, &pBase);
    24072425    if (RT_SUCCESS(vrc))
    24082426    {
    24092427        Assert(pBase);
    24102428        PPDMIACPIPORT pPort = PDMIBASE_QUERY_INTERFACE(pBase, PDMIACPIPORT);
    2411         vrc = pPort ? pPort->pfnSleepButtonPress(pPort) : VERR_INVALID_POINTER;
     2429        if (pPort)
     2430            vrc = pPort->pfnSleepButtonPress(pPort);
     2431        else
     2432            vrc = VERR_PDM_MISSING_INTERFACE;
    24122433    }
    24132434
     
    24482469    {
    24492470        HRESULT rc = Pause();
    2450         if (FAILED(rc)) return rc;
     2471        if (FAILED(rc))
     2472            return rc;
    24512473    }
    24522474
     
    24672489        rc = mControl->BeginSavingState(pProgress.asOutParam(),
    24682490                                        stateFilePath.asOutParam());
    2469         if (FAILED(rc)) break;
     2491        if (FAILED(rc))
     2492            break;
    24702493
    24712494        fBeganSavingState = true;
     
    25082531
    25092532        /* create a thread to wait until the VM state is saved */
    2510         int vrc = RTThreadCreate(NULL, Console::saveStateThread, (void *) task.get(),
     2533        int vrc = RTThreadCreate(NULL, Console::saveStateThread, (void *)task.get(),
    25112534                                 0, RTTHREADTYPE_MAIN_WORKER, 0, "VMSave");
    25122535        if (RT_FAILURE(vrc))
     
    25212544        /* return the progress to the caller */
    25222545        pProgress.queryInterfaceTo(aProgress);
    2523     }
    2524     while (0);
     2546    } while (0);
    25252547
    25262548    if (FAILED(rc) && !fTaskCreationFailed)
     
    26942716            Global::stringifyMachineState(mMachineState));
    26952717
    2696     /* protect mpVM */
    2697     AutoVMCaller autoVMCaller(this);
    2698     if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
     2718    /* Get the VM handle. */
     2719    SafeVMPtr ptrVM(this);
     2720    if (!ptrVM.isOk())
     2721        return ptrVM.rc();
    26992722
    27002723    /* Don't proceed unless we've found the usb controller. */
    27012724    PPDMIBASE pBase = NULL;
    2702     int vrc = PDMR3QueryLun(mpVM, "usb-ohci", 0, 0, &pBase);
     2725    int vrc = PDMR3QueryLun(ptrVM, "usb-ohci", 0, 0, &pBase);
    27032726    if (RT_FAILURE(vrc))
    27042727        return setError(VBOX_E_PDM_ERROR,
     
    27102733
    27112734    /* Request the device capture */
    2712     HRESULT rc = mControl->CaptureUSBDevice(aId);
    2713     if (FAILED(rc)) return rc;
    2714 
    2715     return rc;
     2735    return mControl->CaptureUSBDevice(aId);
    27162736
    27172737#else   /* !VBOX_WITH_USB */
     
    28982918    if (FAILED(rc)) return rc;
    28992919
    2900     /* protect mpVM (if not NULL) */
    2901     AutoVMCallerQuietWeak autoVMCaller(this);
    2902 
    2903     if (    mpVM
    2904          && autoVMCaller.isOk()
     2920    /* If the VM is online and supports shared folders, share this folder
     2921     * under the specified name. (Ignore any failure to obtain the VM handle.) */
     2922    SafeVMPtrQuiet ptrVM(this);
     2923    if (    ptrVM.isOk()
    29052924         && m_pVMMDev
    29062925         && m_pVMMDev->isShFlActive()
    29072926       )
    29082927    {
    2909         /* If the VM is online and supports shared folders, share this folder
    2910          * under the specified name. */
    2911 
    29122928        /* first, remove the machine or the global folder if there is any */
    29132929        SharedFolderDataMap::const_iterator it;
     
    29152931        {
    29162932            rc = removeSharedFolder(aName);
    2917             if (FAILED(rc)) return rc;
     2933            if (FAILED(rc))
     2934                return rc;
    29182935        }
    29192936
    29202937        /* second, create the given folder */
    29212938        rc = createSharedFolder(aName, SharedFolderData(aHostPath, aWritable, aAutoMount));
    2922         if (FAILED(rc)) return rc;
     2939        if (FAILED(rc))
     2940            return rc;
    29232941    }
    29242942
     
    29642982    if (FAILED(rc)) return rc;
    29652983
    2966     /* protect mpVM (if not NULL) */
    2967     AutoVMCallerQuietWeak autoVMCaller(this);
    2968 
    2969     if (    mpVM
    2970          && autoVMCaller.isOk()
     2984    /* protect the VM handle (if not NULL) */
     2985    SafeVMPtrQuiet ptrVM(this);
     2986    if (    ptrVM.isOk()
    29712987         && m_pVMMDev
    29722988         && m_pVMMDev->isShFlActive()
     
    31103126        int vrc = RTThreadCreate(NULL,
    31113127                                 Console::fntTakeSnapshotWorker,
    3112                                  (void*)pTask,
     3128                                 (void *)pTask,
    31133129                                 0,
    31143130                                 RTTHREADTYPE_MAIN_WORKER,
     
    32913307 * @param aMediumAttachment The medium attachment with the new medium state.
    32923308 * @param fForce            Force medium chance, if it is locked or not.
     3309 * @param pVM               Safe VM handle.
    32933310 *
    32943311 * @note Locks this object for writing.
    32953312 */
    3296 HRESULT Console::doMediumChange(IMediumAttachment *aMediumAttachment, bool fForce)
     3313HRESULT Console::doMediumChange(IMediumAttachment *aMediumAttachment, bool fForce, PVM pVM)
    32973314{
    32983315    AutoCaller autoCaller(this);
     
    33523369    AssertComRC(rc);
    33533370
    3354     /* protect mpVM */
    3355     AutoVMCaller autoVMCaller(this);
    3356     AssertComRCReturnRC(autoVMCaller.rc());
    3357 
    33583371    /*
    33593372     * Call worker in EMT, that's faster and safer than doing everything
     
    33623375     */
    33633376    PVMREQ pReq;
    3364     int vrc = VMR3ReqCall(mpVM,
     3377    int vrc = VMR3ReqCall(pVM,
    33653378                          VMCPUID_ANY,
    3366 &pReq,
     3379                          &pReq,
    33673380                          0 /* no wait! */,
    33683381                          VMREQFLAGS_VBOX_STATUS,
    33693382                          (PFNRT)Console::changeRemovableMedium,
    3370                           7,
     3383                          8,
    33713384                          this,
     3385                          pVM,
    33723386                          pszDevice,
    33733387                          uInstance,
     
    34113425 *
    34123426 * @param   pThis           Pointer to the Console object.
     3427 * @param   pVM             The VM handle.
    34133428 * @param   pcszDevice      The PDM device name.
    34143429 * @param   uInstance       The PDM device instance.
     
    34253440 */
    34263441DECLCALLBACK(int) Console::changeRemovableMedium(Console *pConsole,
     3442                                                 PVM pVM,
    34273443                                                 const char *pcszDevice,
    34283444                                                 unsigned uInstance,
     
    34393455    AutoCaller autoCaller(pConsole);
    34403456    AssertComRCReturn(autoCaller.rc(), VERR_ACCESS_DENIED);
    3441 
    3442     PVM pVM = pConsole->mpVM;
    34433457
    34443458    /*
     
    35593573
    35603574    /* don't trigger network change if the VM isn't running */
    3561     if (mpVM)
    3562     {
    3563         /* protect mpVM */
    3564         AutoVMCaller autoVMCaller(this);
    3565         if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
    3566 
     3575    SafeVMPtrQuiet ptrVM(this);
     3576    if (ptrVM.isOk())
     3577    {
    35673578        /* Get the properties we need from the adapter */
    35683579        BOOL fCableConnected, fTraceEnabled;
     
    35903601                const char *pszAdapterName = networkAdapterTypeToName(adapterType);
    35913602                PPDMIBASE pBase;
    3592                 int vrc = PDMR3QueryDeviceLun(mpVM, pszAdapterName, ulInstance, 0, &pBase);
     3603                int vrc = PDMR3QueryDeviceLun(ptrVM, pszAdapterName, ulInstance, 0, &pBase);
    35933604                if (RT_SUCCESS(vrc))
    35943605                {
     
    36073618                    if (RT_SUCCESS(vrc) && changeAdapter)
    36083619                    {
    3609                         VMSTATE enmVMState = VMR3GetState(mpVM);
     3620                        VMSTATE enmVMState = VMR3GetState(ptrVM);
    36103621                        if (    enmVMState == VMSTATE_RUNNING    /** @todo LiveMigration: Forbid or deal correctly with the _LS variants */
    36113622                            ||  enmVMState == VMSTATE_SUSPENDED)
     
    36173628                            }
    36183629
    3619                             rc = doNetworkAdapterChange(pszAdapterName, ulInstance, 0, aNetworkAdapter);
     3630                            rc = doNetworkAdapterChange(ptrVM, pszAdapterName, ulInstance, 0, aNetworkAdapter);
    36203631
    36213632                            if (fTraceEnabled && fCableConnected && pINetCfg)
     
    36283639                }
    36293640                else if (vrc == VERR_PDM_DEVICE_INSTANCE_NOT_FOUND)
    3630                 {
    36313641                    return setError(E_FAIL,
    36323642                            tr("The network adapter #%u is not enabled"), ulInstance);
    3633                 }
    36343643                else
    36353644                    ComAssertRC(vrc);
     
    36393648            }
    36403649        }
     3650        ptrVM.release();
    36413651    }
    36423652
     
    36553665 */
    36563666HRESULT Console::onNATRedirectRuleChange(ULONG ulInstance, BOOL aNatRuleRemove,
    3657                                  NATProtocol_T aProto, IN_BSTR aHostIp, LONG aHostPort, IN_BSTR aGuestIp, LONG aGuestPort)
     3667                                         NATProtocol_T aProto, IN_BSTR aHostIp, LONG aHostPort, IN_BSTR aGuestIp, LONG aGuestPort)
    36583668{
    36593669    LogFlowThisFunc(("\n"));
     
    36653675
    36663676    HRESULT rc = S_OK;
    3667     int vrc = VINF_SUCCESS;
    3668     PPDMINETWORKNATCONFIG pNetNatCfg = NULL;
     3677
    36693678    /* don't trigger nat engine change if the VM isn't running */
    3670     if (mpVM)
    3671     {
    3672         /* protect mpVM */
    3673         AutoVMCaller autoVMCaller(this);
    3674         if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
    3675 
    3676         ComPtr<INetworkAdapter> pNetworkAdapter;
    3677         rc = machine()->GetNetworkAdapter(ulInstance, pNetworkAdapter.asOutParam());
    3678         if (   FAILED(rc)
    3679             || pNetworkAdapter.isNull())
    3680             goto done;
    3681 
    3682         /*
    3683          * Find the adapter instance, get the config interface and update
    3684          * the link state.
    3685          */
    3686         NetworkAdapterType_T adapterType;
    3687         rc = pNetworkAdapter->COMGETTER(AdapterType)(&adapterType);
    3688         AssertComRC(rc);
    3689         if (FAILED(rc))
    3690         {
    3691             rc = E_FAIL;
    3692             goto done;
    3693         }
    3694 
    3695         const char *pszAdapterName = networkAdapterTypeToName(adapterType);
    3696         PPDMIBASE pBase;
    3697         vrc = PDMR3QueryLun(mpVM, pszAdapterName, ulInstance, 0, &pBase);
    3698         ComAssertRC(vrc);
    3699         if (RT_FAILURE(vrc))
    3700         {
    3701             rc = E_FAIL;
    3702             goto done;
    3703         }
    3704         NetworkAttachmentType_T attachmentType;
    3705         vrc = pNetworkAdapter->COMGETTER(AttachmentType)(&attachmentType);
    3706 
    3707         if (   RT_FAILURE(vrc)
    3708             || attachmentType != NetworkAttachmentType_NAT)
    3709         {
    3710             rc = (RT_FAILURE(vrc)) ? E_FAIL: rc;
    3711             goto done;
    3712         }
    3713 
    3714         /* look down for PDMINETWORKNATCONFIG interface */
    3715         while (pBase)
    3716         {
    3717             if ((pNetNatCfg = (PPDMINETWORKNATCONFIG)pBase->pfnQueryInterface(pBase, PDMINETWORKNATCONFIG_IID)))
     3679    SafeVMPtrQuiet ptrVM(this);
     3680    if (ptrVM.isOk())
     3681    {
     3682        do
     3683        {
     3684            ComPtr<INetworkAdapter> pNetworkAdapter;
     3685            rc = machine()->GetNetworkAdapter(ulInstance, pNetworkAdapter.asOutParam());
     3686            if (   FAILED(rc)
     3687                || pNetworkAdapter.isNull())
    37183688                break;
    3719             PPDMDRVINS drvins = PDMIBASE_2_PDMDRV(pBase);
    3720             pBase = drvins->pDownBase;
    3721         }
    3722         if (!pNetNatCfg)
    3723             goto done;
    3724         bool fUdp = (aProto == NATProtocol_UDP);
    3725         vrc = pNetNatCfg->pfnRedirectRuleCommand(pNetNatCfg, aNatRuleRemove, fUdp,
    3726                                                  Utf8Str(aHostIp).c_str(), aHostPort, Utf8Str(aGuestIp).c_str(),
    3727                                                  aGuestPort);
    3728         if (RT_FAILURE(vrc))
    3729             rc = E_FAIL;
    3730     }
    3731 done:
     3689
     3690            /*
     3691             * Find the adapter instance, get the config interface and update
     3692             * the link state.
     3693             */
     3694            NetworkAdapterType_T adapterType;
     3695            rc = pNetworkAdapter->COMGETTER(AdapterType)(&adapterType);
     3696            if (FAILED(rc))
     3697            {
     3698                AssertComRC(rc);
     3699                rc = E_FAIL;
     3700                break;
     3701            }
     3702
     3703            const char *pszAdapterName = networkAdapterTypeToName(adapterType);
     3704            PPDMIBASE pBase;
     3705            int vrc = PDMR3QueryLun(ptrVM, pszAdapterName, ulInstance, 0, &pBase);
     3706            if (RT_FAILURE(vrc))
     3707            {
     3708                ComAssertRC(vrc);
     3709                rc = E_FAIL;
     3710                break;
     3711            }
     3712
     3713            NetworkAttachmentType_T attachmentType;
     3714            rc = pNetworkAdapter->COMGETTER(AttachmentType)(&attachmentType);
     3715            if (   FAILED(rc)
     3716                || attachmentType != NetworkAttachmentType_NAT)
     3717            {
     3718                rc = E_FAIL;
     3719                break;
     3720            }
     3721
     3722            /* look down for PDMINETWORKNATCONFIG interface */
     3723            PPDMINETWORKNATCONFIG pNetNatCfg = NULL;
     3724            while (pBase)
     3725            {
     3726                pNetNatCfg = (PPDMINETWORKNATCONFIG)pBase->pfnQueryInterface(pBase, PDMINETWORKNATCONFIG_IID);
     3727                if (pNetNatCfg)
     3728                    break;
     3729                /** @todo r=bird: This stinks! */
     3730                PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pBase);
     3731                pBase = pDrvIns->pDownBase;
     3732            }
     3733            if (!pNetNatCfg)
     3734                break;
     3735
     3736            bool fUdp = aProto == NATProtocol_UDP;
     3737            vrc = pNetNatCfg->pfnRedirectRuleCommand(pNetNatCfg, aNatRuleRemove, fUdp,
     3738                                                     Utf8Str(aHostIp).c_str(), aHostPort, Utf8Str(aGuestIp).c_str(),
     3739                                                     aGuestPort);
     3740            if (RT_FAILURE(vrc))
     3741                rc = E_FAIL;
     3742        } while (0); /* break loop */
     3743        ptrVM.release();
     3744    }
     3745
    37323746    LogFlowThisFunc(("Leaving rc=%#x\n", rc));
    37333747    return rc;
     
    37403754 * @returns COM status code.
    37413755 *
     3756 * @parma   pVM                 The VM handle (caller hold this safely).
    37423757 * @param   pszDevice           The PDM device name.
    37433758 * @param   uInstance           The PDM device instance.
     
    37473762 * @note Locks this object for writing.
    37483763 */
    3749 HRESULT Console::doNetworkAdapterChange(const char *pszDevice,
     3764HRESULT Console::doNetworkAdapterChange(PVM pVM,
     3765                                        const char *pszDevice,
    37503766                                        unsigned uInstance,
    37513767                                        unsigned uLun,
     
    37613777    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    37623778
    3763     /* protect mpVM */
    3764     AutoVMCaller autoVMCaller(this);
    3765     if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
     3779    /* Get the VM handle. */
     3780    SafeVMPtr ptrVM(this);
     3781    if (!ptrVM.isOk())
     3782        return ptrVM.rc();
    37663783
    37673784    /*
     
    37713788     */
    37723789    PVMREQ pReq;
    3773     int vrc = VMR3ReqCall(mpVM, 0 /*idDstCpu*/, &pReq, 0 /* no wait! */, VMREQFLAGS_VBOX_STATUS,
    3774                           (PFNRT) Console::changeNetworkAttachment, 5,
    3775                           this, pszDevice, uInstance, uLun, aNetworkAdapter);
     3790    int vrc = VMR3ReqCall(pVM, 0 /*idDstCpu*/, &pReq, 0 /* no wait! */, VMREQFLAGS_VBOX_STATUS,
     3791                          (PFNRT) Console::changeNetworkAttachment, 6,
     3792                          this, ptrVM.raw(), pszDevice, uInstance, uLun, aNetworkAdapter);
    37763793
    37773794    /* leave the lock before waiting for a result (EMT will call us back!) */
     
    38053822 *
    38063823 * @param   pThis               Pointer to the Console object.
     3824 * @param   pVM                 The VM handle.
    38073825 * @param   pszDevice           The PDM device name.
    38083826 * @param   uInstance           The PDM device instance.
     
    38143832 */
    38153833DECLCALLBACK(int) Console::changeNetworkAttachment(Console *pThis,
     3834                                                   PVM pVM,
    38163835                                                   const char *pszDevice,
    38173836                                                   unsigned uInstance,
     
    38273846                  || !strcmp(pszDevice, "e1000")
    38283847                  || !strcmp(pszDevice, "virtio-net"))
    3829               && (uLun == 0)
    3830               && (uInstance < SchemaDefs::NetworkAdapterCount),
     3848              && uLun == 0
     3849              && uInstance < SchemaDefs::NetworkAdapterCount,
    38313850              ("pszDevice=%s uLun=%d uInstance=%d\n", pszDevice, uLun, uInstance));
    38323851    Log(("pszDevice=%s uLun=%d uInstance=%d\n", pszDevice, uLun, uInstance));
     
    38343853    AutoCaller autoCaller(pThis);
    38353854    AssertComRCReturn(autoCaller.rc(), VERR_ACCESS_DENIED);
    3836 
    3837     /* protect mpVM */
    3838     AutoVMCaller autoVMCaller(pThis);
    3839     if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
    3840 
    3841     PVM pVM = pThis->mpVM;
    38423855
    38433856    /*
     
    39323945
    39333946    /* don't trigger serial port change if the VM isn't running */
    3934     if (mpVM)
    3935     {
    3936         /* protect mpVM */
    3937         AutoVMCaller autoVMCaller(this);
    3938         if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
    3939 
     3947    SafeVMPtrQuiet ptrVM(this);
     3948    if (ptrVM.isOk())
     3949    {
    39403950        /* nothing to do so far */
     3951        ptrVM.release();
    39413952    }
    39423953
     
    39663977
    39673978    /* don't trigger parallel port change if the VM isn't running */
    3968     if (mpVM)
    3969     {
    3970         /* protect mpVM */
    3971         AutoVMCaller autoVMCaller(this);
    3972         if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
    3973 
     3979    SafeVMPtrQuiet ptrVM(this);
     3980    if (ptrVM.isOk())
     3981    {
    39743982        /* nothing to do so far */
     3983        ptrVM.release();
    39753984    }
    39763985
     
    40004009
    40014010    /* don't trigger storage controller change if the VM isn't running */
    4002     if (mpVM)
    4003     {
    4004         /* protect mpVM */
    4005         AutoVMCaller autoVMCaller(this);
    4006         if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
    4007 
     4011    SafeVMPtrQuiet ptrVM(this);
     4012    if (ptrVM.isOk())
     4013    {
    40084014        /* nothing to do so far */
     4015        ptrVM.release();
    40094016    }
    40104017
     
    40344041
    40354042    /* don't trigger medium change if the VM isn't running */
    4036     if (mpVM)
    4037     {
    4038         /* protect mpVM */
    4039         AutoVMCaller autoVMCaller(this);
    4040         if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
    4041 
    4042         rc = doMediumChange(aMediumAttachment, !!aForce);
     4043    SafeVMPtrQuiet ptrVM(this);
     4044    if (ptrVM.isOk())
     4045    {
     4046        rc = doMediumChange(aMediumAttachment, !!aForce, ptrVM);
     4047        ptrVM.release();
    40434048    }
    40444049
     
    40664071
    40674072    /* don't trigger CPU change if the VM isn't running */
    4068     if (mpVM)
     4073    SafeVMPtrQuiet ptrVM(this);
     4074    if (ptrVM.isOk())
    40694075    {
    40704076        if (aRemove)
    4071             rc = doCPURemove(aCPU);
     4077            rc = doCPURemove(aCPU, ptrVM);
    40724078        else
    4073             rc = doCPUAdd(aCPU);
     4079            rc = doCPUAdd(aCPU, ptrVM);
     4080        ptrVM.release();
    40744081    }
    40754082
     
    40994106
    41004107    /* don't trigger the CPU priority change if the VM isn't running */
    4101     if (mpVM)
    4102     {
    4103         /* protect mpVM */
    4104         AutoVMCaller autoVMCaller(this);
    4105         if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
    4106 
     4108    SafeVMPtrQuiet ptrVM(this);
     4109    if (ptrVM.isOk())
     4110    {
    41074111        if (   mMachineState == MachineState_Running
    41084112            || mMachineState == MachineState_Teleporting
     
    41114115        {
    41124116            /* No need to call in the EMT thread. */
    4113             rc = VMR3SetCpuExecutionCap(mpVM, aExecutionCap);
     4117            rc = VMR3SetCpuExecutionCap(ptrVM, aExecutionCap);
    41144118        }
    41154119        else
    41164120            rc = setInvalidMachineStateError();
     4121        ptrVM.release();
    41174122    }
    41184123
     
    42154220
    42164221    /* don't trigger USB controller change if the VM isn't running */
    4217     if (mpVM)
     4222    SafeVMPtrQuiet ptrVM(this);
     4223    if (ptrVM.isOk())
    42184224    {
    42194225        /// @todo implement one day.
     
    42244230        // handle it at this time... :-)
    42254231
    4226         /* protect mpVM */
    4227         AutoVMCaller autoVMCaller(this);
    4228         if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
    4229 
    42304232        /* nothing to do so far */
     4233        ptrVM.release();
    42314234    }
    42324235
     
    42884291    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    42894292
    4290     /* protect mpVM (we don't need error info, since it's a callback) */
    4291     AutoVMCallerQuiet autoVMCaller(this);
    4292     if (FAILED(autoVMCaller.rc()))
     4293    /* Get the VM pointer (we don't need error info, since it's a callback). */
     4294    SafeVMPtrQuiet ptrVM(this);
     4295    if (!ptrVM.isOk())
    42934296    {
    42944297        /* The VM may be no more operational when this message arrives
     
    42974300        LogFlowThisFunc(("Attach request ignored (mMachineState=%d).\n",
    42984301                          mMachineState));
    4299         return autoVMCaller.rc();
     4302        return ptrVM.rc();
    43004303    }
    43014304
     
    43084311
    43094312    /* Don't proceed unless there's at least one USB hub. */
    4310     if (!PDMR3USBHasHub(mpVM))
     4313    if (!PDMR3USBHasHub(ptrVM))
    43114314    {
    43124315        LogFlowThisFunc(("Attach request ignored (no USB controller).\n"));
     
    44374440
    44384441    /* don't trigger the CPU priority change if the VM isn't running */
    4439     if (mpVM)
    4440     {
    4441         /* protect mpVM */
    4442         AutoVMCaller autoVMCaller(this);
    4443         if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
    4444 
     4442    SafeVMPtrQuiet ptrVM(this);
     4443    if (ptrVM.isOk())
     4444    {
    44454445        if (   mMachineState == MachineState_Running
    44464446            || mMachineState == MachineState_Teleporting
     
    44584458            {
    44594459                int vrc;
    4460                 vrc = PDMR3AsyncCompletionBwMgrSetMaxForFile(mpVM, Utf8Str(strName).c_str(),
     4460                vrc = PDMR3AsyncCompletionBwMgrSetMaxForFile(ptrVM, Utf8Str(strName).c_str(),
    44614461                                                             cMax * _1M);
    44624462                AssertRC(vrc);
     
    44654465        else
    44664466            rc = setInvalidMachineStateError();
     4467        ptrVM.release();
    44674468    }
    44684469
     
    46834684
    46844685/**
    4685  * @note Temporarily locks this object for writing.
     4686 * @note Temporarily locks this object for writing. bird: And/or reading?
    46864687 */
    46874688HRESULT Console::onlineMergeMedium(IMediumAttachment *aMediumAttachment,
     
    46984699    HRESULT rc = S_OK;
    46994700    int vrc = VINF_SUCCESS;
    4700     PVM pVM = mpVM;
     4701
     4702    /* Get the VM - must be done before the read-locking. */
     4703    SafeVMPtr ptrVM(this);
     4704    if (!ptrVM.isOk())
     4705        return ptrVM.rc();
    47014706
    47024707    /* We will need to release the lock before doing the actual merge */
     
    47144719    }
    47154720
     4721    /** @todo AssertComRC -> AssertComRCReturn! Could potentially end up
     4722     *        using uninitialized variables here. */
    47164723    BOOL fBuiltinIoCache;
    47174724    rc = mMachine->COMGETTER(IoCacheEnabled)(&fBuiltinIoCache);
     
    47784785
    47794786    /* Pause the VM, as it might have pending IO on this drive */
    4780     VMSTATE enmVMState = VMR3GetState(pVM);
     4787    VMSTATE enmVMState = VMR3GetState(ptrVM);
    47814788    if (mMachineState == MachineState_DeletingSnapshotOnline)
    47824789    {
     
    47844791        /* disable the callback to prevent Console-level state change */
    47854792        mVMStateChangeCallbackDisabled = true;
    4786         int vrc2 = VMR3Suspend(pVM);
     4793        int vrc2 = VMR3Suspend(ptrVM);
    47874794        mVMStateChangeCallbackDisabled = false;
    47884795        AssertRCReturn(vrc2, E_FAIL);
    47894796    }
    47904797
    4791     vrc = VMR3ReqCallWait(pVM,
     4798    vrc = VMR3ReqCallWait(ptrVM,
    47924799                          VMCPUID_ANY,
    47934800                          (PFNRT)reconfigureMediumAttachment,
    47944801                          13,
    47954802                          this,
    4796                           pVM,
     4803                          ptrVM.raw(),
    47974804                          pcszDevice,
    47984805                          uInstance,
     
    48134820        /* disable the callback to prevent Console-level state change */
    48144821        mVMStateChangeCallbackDisabled = true;
    4815         int vrc2 = VMR3Resume(pVM);
     4822        int vrc2 = VMR3Resume(ptrVM);
    48164823        mVMStateChangeCallbackDisabled = false;
    48174824        if (RT_FAILURE(vrc2))
     
    48194826            /* too bad, we failed. try to sync the console state with the VMM state */
    48204827            AssertLogRelRC(vrc2);
    4821             vmstateChangeCallback(pVM, VMSTATE_SUSPENDED, enmVMState, this);
     4828            vmstateChangeCallback(ptrVM, VMSTATE_SUSPENDED, enmVMState, this);
    48224829        }
    48234830    }
     
    48304837    PPDMIBASE pIBase = NULL;
    48314838    PPDMIMEDIA pIMedium = NULL;
    4832     vrc = PDMR3QueryDriverOnLun(pVM, pcszDevice, uInstance, uLUN, "VD", &pIBase);
     4839    vrc = PDMR3QueryDriverOnLun(ptrVM, pcszDevice, uInstance, uLUN, "VD", &pIBase);
    48334840    if (RT_SUCCESS(vrc))
    48344841    {
     
    48494856
    48504857    /* Pause the VM, as it might have pending IO on this drive */
    4851     enmVMState = VMR3GetState(pVM);
     4858    enmVMState = VMR3GetState(ptrVM);
    48524859    if (mMachineState == MachineState_DeletingSnapshotOnline)
    48534860    {
     
    48554862        /* disable the callback to prevent Console-level state change */
    48564863        mVMStateChangeCallbackDisabled = true;
    4857         int vrc2 = VMR3Suspend(pVM);
     4864        int vrc2 = VMR3Suspend(ptrVM);
    48584865        mVMStateChangeCallbackDisabled = false;
    48594866        AssertRCReturn(vrc2, E_FAIL);
     
    48654872                                           ComSafeArrayInArg(aChildrenToReparent));
    48664873
    4867     vrc = VMR3ReqCallWait(pVM,
     4874    vrc = VMR3ReqCallWait(ptrVM,
    48684875                          VMCPUID_ANY,
    48694876                          (PFNRT)reconfigureMediumAttachment,
    48704877                          13,
    48714878                          this,
    4872                           pVM,
     4879                          ptrVM.raw(),
    48734880                          pcszDevice,
    48744881                          uInstance,
     
    48894896        /* disable the callback to prevent Console-level state change */
    48904897        mVMStateChangeCallbackDisabled = true;
    4891         int vrc2 = VMR3Resume(pVM);
     4898        int vrc2 = VMR3Resume(ptrVM);
    48924899        mVMStateChangeCallbackDisabled = false;
    48934900        AssertRC(vrc2);
     
    48954902        {
    48964903            /* too bad, we failed. try to sync the console state with the VMM state */
    4897             vmstateChangeCallback(pVM, VMSTATE_SUSPENDED, enmVMState, this);
     4904            vmstateChangeCallback(ptrVM, VMSTATE_SUSPENDED, enmVMState, this);
    48984905        }
    48994906    }
     
    51975204    }
    51985205
    5199     if (mpVM == NULL)
     5206    if (mpUVM == NULL)
    52005207    {
    52015208        Assert(aAllowNullVM == true);
     
    52245231    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    52255232
    5226     AssertReturnVoid(mpVM != NULL);
     5233    AssertReturnVoid(mpUVM != NULL);
    52275234
    52285235    Assert(mVMCallers > 0);
     
    52355242    }
    52365243}
     5244
     5245
     5246HRESULT Console::safeVMPtrRetainer(PVM *a_ppVM, PUVM *a_ppUVM, bool a_Quiet)
     5247{
     5248    *a_ppVM  = NULL;
     5249    *a_ppUVM = NULL;
     5250
     5251    AutoCaller autoCaller(this);
     5252    AssertComRCReturnRC(autoCaller.rc());
     5253    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     5254
     5255    /*
     5256     * Repeat the checks done by addVMCaller.
     5257     */
     5258    if (mVMDestroying) /* powerDown() is waiting for all callers to finish */
     5259        return a_Quiet
     5260            ? E_ACCESSDENIED
     5261            : setError(E_ACCESSDENIED, tr("The virtual machine is being powered down"));
     5262    PUVM pUVM = mpUVM;
     5263    if (!pUVM)
     5264        return a_Quiet
     5265            ? E_ACCESSDENIED
     5266            : setError(E_ACCESSDENIED, tr("The virtual machine is was powered off"));
     5267
     5268    /*
     5269     * Retain a reference to the user mode VM handle and get the global handle.
     5270     */
     5271    uint32_t cRefs = VMR3RetainUVM(pUVM);
     5272    if (cRefs == UINT32_MAX)
     5273        return a_Quiet
     5274            ? E_ACCESSDENIED
     5275            : setError(E_ACCESSDENIED, tr("The virtual machine is was powered off"));
     5276
     5277    PVM pVM = VMR3GetVM(pUVM);
     5278    if (!pVM)
     5279    {
     5280        VMR3ReleaseUVM(pUVM);
     5281        return a_Quiet
     5282            ? E_ACCESSDENIED
     5283            : setError(E_ACCESSDENIED, tr("The virtual machine is was powered off"));
     5284    }
     5285
     5286    /* done */
     5287    *a_ppVM  = pVM;
     5288    *a_ppUVM = pUVM;
     5289    return S_OK;
     5290}
     5291
     5292void Console::safeVMPtrReleaser(PVM *a_ppVM, PUVM *a_ppUVM)
     5293{
     5294    if (*a_ppVM && *a_ppUVM)
     5295        VMR3ReleaseUVM(*a_ppUVM);
     5296    *a_ppVM  = NULL;
     5297    *a_ppUVM = NULL;
     5298}
     5299
    52375300
    52385301/**
     
    58705933    Assert(mVMDestroying == false);
    58715934
    5872     Assert(mpVM != NULL);
     5935    PUVM     pUVM  = mpUVM;                 Assert(pUVM != NULL);
     5936    uint32_t cRefs = VMR3RetainUVM(pUVM);   Assert(cRefs != UINT32_MAX);
    58735937
    58745938    AssertMsg(   mMachineState == MachineState_Running
     
    59866050        LogFlowThisFunc(("Powering off the VM...\n"));
    59876051        alock.leave();
    5988         vrc = VMR3PowerOff(mpVM);
     6052        vrc = VMR3PowerOff(VMR3GetVM(pUVM));
    59896053#ifdef VBOX_WITH_EXTPACK
    5990         mptrExtPackManager->callAllVmPowerOffHooks(this, mpVM);
     6054        mptrExtPackManager->callAllVmPowerOffHooks(this, VMR3GetVM(pUVM));
    59916055#endif
    59926056        alock.enter();
     
    60286092        {
    60296093            PPDMIBASE pBase;
    6030             vrc = PDMR3QueryLun(mpVM, "usb-ohci", 0, 0, &pBase);
     6094            vrc = PDMR3QueryLun(VMR3GetVM(pUVM), "usb-ohci", 0, 0, &pBase);
    60316095            if (RT_SUCCESS(vrc))
    60326096            {
     
    60436107         * mVMDestroying is set which should prevent any activity. */
    60446108
    6045         /* Set mpVM to NULL early just in case if some old code is not using
    6046          * addVMCaller()/releaseVMCaller(). */
    6047         PVM pVM = mpVM;
    6048         mpVM = NULL;
     6109        /* Set mpUVM to NULL early just in case if some old code is not using
     6110         * addVMCaller()/releaseVMCaller(). (We have our own ref on pUVM.) */
     6111        VMR3ReleaseUVM(mpUVM);
     6112        mpUVM = NULL;
    60496113
    60506114        LogFlowThisFunc(("Destroying the VM...\n"));
     
    60526116        alock.leave();
    60536117
    6054         vrc = VMR3Destroy(pVM);
     6118        vrc = VMR3Destroy(VMR3GetVM(pUVM));
    60556119
    60566120        /* take the lock again */
     
    60756139        else
    60766140        {
    6077             /* bad bad bad, but what to do? */
    6078             mpVM = pVM;
     6141            /* bad bad bad, but what to do? (Give Console our UVM ref.) */
     6142            mpUVM = pUVM;
     6143            pUVM = NULL;
    60796144            rc = setError(VBOX_E_VM_ERROR,
    60806145                tr("Could not destroy the machine. (Error: %Rrc)"),
     
    60976162    }
    60986163
    6099     /* Finished with destruction. Note that if something impossible happened and
    6100      * we've failed to destroy the VM, mVMDestroying will remain true and
    6101      * mMachineState will be something like Stopping, so most Console methods
    6102      * will return an error to the caller. */
    6103     if (mpVM == NULL)
     6164    /*
     6165     * Finished with the destruction.
     6166     *
     6167     * Note that if something impossible happened and we've failed to destroy
     6168     * the VM, mVMDestroying will remain true and mMachineState will be
     6169     * something like Stopping, so most Console methods will return an error
     6170     * to the caller.
     6171     */
     6172    if (mpUVM != NULL)
     6173        VMR3ReleaseUVM(pUVM);
     6174    else
    61046175        mVMDestroying = false;
    61056176
     
    62156286    LogFlowThisFunc(("Entering\n"));
    62166287
    6217     /* protect mpVM (if not NULL) */
     6288    /* Check if we're online and keep it that way. */
     6289    SafeVMPtrQuiet ptrVM(this);
    62186290    AutoVMCallerQuietWeak autoVMCaller(this);
     6291    bool const online = ptrVM.isOk()
     6292                     && m_pVMMDev
     6293                     && m_pVMMDev->isShFlActive();
    62196294
    62206295    HRESULT rc = S_OK;
    6221 
    6222     bool online =    mpVM
    6223                   && autoVMCaller.isOk()
    6224                   && m_pVMMDev
    6225                   && m_pVMMDev->isShFlActive();
    62266296
    62276297    try
     
    63366406    {
    63376407        if (online)
    6338             setVMRuntimeErrorCallbackF(mpVM, this, 0, "BrokenSharedFolder",
     6408            setVMRuntimeErrorCallbackF(ptrVM, this, 0, "BrokenSharedFolder",
    63396409                                       N_("Broken shared folder!"));
    63406410    }
     
    63896459
    63906460    /* sanity checks */
    6391     AssertReturn(mpVM, E_FAIL);
     6461    AssertReturn(mpUVM, E_FAIL);
    63926462    AssertReturn(m_pVMMDev && m_pVMMDev->isShFlActive(), E_FAIL);
    63936463
     
    64946564
    64956565    /* sanity checks */
    6496     AssertReturn(mpVM, E_FAIL);
     6566    AssertReturn(mpUVM, E_FAIL);
    64976567    AssertReturn(m_pVMMDev && m_pVMMDev->isShFlActive(), E_FAIL);
    64986568
     
    68896959    ComAssertComRCRetRC(hrc);
    68906960
    6891     /* protect mpVM */
    6892     AutoVMCaller autoVMCaller(this);
    6893     if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
     6961    /* Get the VM handle. */
     6962    SafeVMPtr ptrVM(this);
     6963    if (!ptrVM.isOk())
     6964        return ptrVM.rc();
    68946965
    68956966    LogFlowThisFunc(("Proxying USB device '%s' {%RTuuid}...\n",
     
    69006971
    69016972/** @todo just do everything here and only wrap the PDMR3Usb call. That'll offload some notification stuff from the EMT thread. */
    6902     int vrc = VMR3ReqCallWait(mpVM, VMCPUID_ANY,
    6903                               (PFNRT)usbAttachCallback, 6, this, aHostDevice, uuid.raw(), fRemote, Address.c_str(), aMaskedIfs);
     6973    int vrc = VMR3ReqCallWait(ptrVM, VMCPUID_ANY,
     6974                              (PFNRT)usbAttachCallback, 7,
     6975                              this, ptrVM.raw(), aHostDevice, uuid.raw(), fRemote, Address.c_str(), aMaskedIfs);
    69046976
    69056977    /* restore the lock */
     
    69116983    {
    69126984        LogWarningThisFunc(("Failed to create proxy device for '%s' {%RTuuid} (%Rrc)\n",
    6913                              Address.c_str(), uuid.raw(), vrc));
     6985                            Address.c_str(), uuid.raw(), vrc));
    69146986
    69156987        switch (vrc)
     
    69457017//static
    69467018DECLCALLBACK(int)
    6947 Console::usbAttachCallback(Console *that, IUSBDevice *aHostDevice, PCRTUUID aUuid, bool aRemote, const char *aAddress, ULONG aMaskedIfs)
     7019Console::usbAttachCallback(Console *that, PVM pVM, IUSBDevice *aHostDevice, PCRTUUID aUuid, bool aRemote, const char *aAddress, ULONG aMaskedIfs)
    69487020{
    69497021    LogFlowFuncEnter();
     
    69687040    Assert(portVersion == 1 || portVersion == 2);
    69697041
    6970     int vrc = PDMR3USBCreateProxyDevice(that->mpVM, aUuid, aRemote, aAddress, pvRemoteBackend,
     7042    int vrc = PDMR3USBCreateProxyDevice(pVM, aUuid, aRemote, aAddress, pvRemoteBackend,
    69717043                                        portVersion == 1 ? VUSB_STDVER_11 : VUSB_STDVER_20, aMaskedIfs);
    69727044    if (RT_SUCCESS(vrc))
     
    70087080    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    70097081
    7010     /* protect mpVM */
    7011     AutoVMCaller autoVMCaller(this);
    7012     if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
     7082    /* Get the VM handle. */
     7083    SafeVMPtr ptrVM(this);
     7084    if (!ptrVM.isOk())
     7085        return ptrVM.rc();
    70137086
    70147087    /* if the device is attached, then there must at least one USB hub. */
    7015     AssertReturn(PDMR3USBHasHub(mpVM), E_FAIL);
     7088    AssertReturn(PDMR3USBHasHub(ptrVM), E_FAIL);
    70167089
    70177090    LogFlowThisFunc(("Detaching USB proxy device {%RTuuid}...\n",
    7018                       (*aIt)->id().raw()));
     7091                     (*aIt)->id().raw()));
    70197092
    70207093    /* leave the lock before a VMR3* call (EMT will call us back)! */
     
    70227095
    70237096/** @todo just do everything here and only wrap the PDMR3Usb call. That'll offload some notification stuff from the EMT thread. */
    7024     int vrc = VMR3ReqCallWait(mpVM, VMCPUID_ANY,
    7025                               (PFNRT) usbDetachCallback, 4, this, &aIt, (*aIt)->id().raw());
     7097    int vrc = VMR3ReqCallWait(ptrVM, VMCPUID_ANY,
     7098                              (PFNRT)usbDetachCallback, 5,
     7099                              this, ptrVM.raw(), &aIt, (*aIt)->id().raw());
    70267100    ComAssertRCRet(vrc, E_FAIL);
    70277101
     
    70407114//static
    70417115DECLCALLBACK(int)
    7042 Console::usbDetachCallback(Console *that, USBDeviceList::iterator *aIt, PCRTUUID aUuid)
     7116Console::usbDetachCallback(Console *that, PVM pVM, USBDeviceList::iterator *aIt, PCRTUUID aUuid)
    70437117{
    70447118    LogFlowFuncEnter();
     
    70647138    }
    70657139
    7066     int vrc = PDMR3USBDetachDevice(that->mpVM, aUuid);
     7140    int vrc = PDMR3USBDetachDevice(pVM, aUuid);
    70677141
    70687142    if (RT_SUCCESS(vrc))
     
    77317805
    77327806    /* sanity */
    7733     Assert(pConsole->mpVM == NULL);
     7807    Assert(pConsole->mpUVM == NULL);
    77347808
    77357809    try
     
    79568030                    /* -> ConsoleImplTeleporter.cpp */
    79578031                    bool fPowerOffOnFailure;
    7958                     rc = pConsole->teleporterTrg(pVM, pMachine, &task->mErrorMsg, task->mStartPaused,
     8032                    rc = pConsole->teleporterTrg(VMR3GetUVM(pVM), pMachine, &task->mErrorMsg, task->mStartPaused,
    79598033                                                 task->mProgress, &fPowerOffOnFailure);
    79608034                    if (FAILED(rc) && fPowerOffOnFailure)
     
    80608134             * If VMR3Create() failed it has released the VM memory.
    80618135             */
    8062             pConsole->mpVM = NULL;
     8136            VMR3ReleaseUVM(pConsole->mpUVM);
     8137            pConsole->mpUVM = NULL;
    80638138        }
    80648139
     
    81078182        ErrorInfoKeeper eik;
    81088183
    8109         Assert(pConsole->mpVM == NULL);
     8184        Assert(pConsole->mpUVM == NULL);
    81108185        vmstateChangeCallback(NULL, VMSTATE_TERMINATED, VMSTATE_CREATING,
    81118186                              pConsole);
     
    82328307static void takesnapshotProgressCancelCallback(void *pvUser)
    82338308{
    8234     PVM pVM = (PVM)pvUser;
    8235     SSMR3Cancel(pVM);
     8309    PUVM pUVM = (PUVM)pvUser;
     8310    SSMR3Cancel(VMR3GetVM(pUVM));
    82368311}
    82378312
     
    83088383            Utf8Str strSavedStateFile(pTask->bstrSavedStateFile);
    83098384
     8385            SafeVMPtr ptrVM(that);
     8386            if (!ptrVM.isOk())
     8387                throw ptrVM.rc();
     8388
    83108389            pTask->mProgress->SetNextOperation(Bstr(tr("Saving the machine state")).raw(),
    83118390                                               pTask->ulMemSize);       // operation weight, same as computed when setting up progress object
    8312             pTask->mProgress->setCancelCallback(takesnapshotProgressCancelCallback, that->mpVM);
     8391            pTask->mProgress->setCancelCallback(takesnapshotProgressCancelCallback, ptrVM.rawUVM());
    83138392
    83148393            alock.leave();
    83158394            LogFlowFunc(("VMR3Save...\n"));
    8316             int vrc = VMR3Save(that->mpVM,
     8395            int vrc = VMR3Save(ptrVM,
    83178396                               strSavedStateFile.c_str(),
    83188397                               true /*fContinueAfterwards*/,
     
    83918470                 * isn't going to need the Console lock.
    83928471                 */
    8393                 vrc = VMR3ReqCallWait(that->mpVM,
     8472                vrc = VMR3ReqCallWait(ptrVM,
    83948473                                      VMCPUID_ANY,
    83958474                                      (PFNRT)reconfigureMediumAttachment,
    83968475                                      13,
    83978476                                      that,
    8398                                       that->mpVM,
     8477                                      ptrVM.raw(),
    83998478                                      pcszDevice,
    84008479                                      lInstance,
     
    84628541            {
    84638542                LogFlowFunc(("VMR3Resume...\n"));
     8543                SafeVMPtr ptrVM(that);
    84648544                alock.leave();
    8465                 int vrc = VMR3Resume(that->mpVM);
     8545                int vrc = VMR3Resume(ptrVM);
    84668546                alock.enter();
    84678547                if (RT_FAILURE(vrc))
     
    84808560            /** @todo this could probably be made more generic and reused elsewhere. */
    84818561            /* paranoid cleanup on for a failed online snapshot. */
    8482             VMSTATE enmVMState = VMR3GetState(that->mpVM);
     8562            VMSTATE enmVMState = VMR3GetStateU(that->mpUVM);
    84838563            switch (enmVMState)
    84848564            {
     
    85198599                        Assert(pTask->lastMachineState == MachineState_Running);
    85208600                        LogFlowFunc(("VMR3Resume (on failure)...\n"));
     8601                        SafeVMPtr ptrVM(that);
    85218602                        alock.leave();
    8522                         int vrc = VMR3Resume(that->mpVM); AssertLogRelRC(vrc);
     8603                        int vrc = VMR3Resume(ptrVM); AssertLogRelRC(vrc);
    85238604                        alock.enter();
    85248605                        if (RT_FAILURE(vrc))
     
    85808661
    85818662    bool fSuspenededBySave;
    8582     int vrc = VMR3Save(that->mpVM,
     8663    int vrc = VMR3Save(task->mpVM,
    85838664                       task->mSavedStateFile.c_str(),
    85848665                       false, /*fContinueAfterwards*/
  • trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp

    r36024 r36041  
    557557     * can easily reset the VM handle on failure.
    558558     */
    559     pConsole->mpVM = pVM;
     559    PUVM pUVM = pConsole->mpUVM = VMR3GetUVM(pVM);
     560    VMR3RetainUVM(pUVM);
    560561    int vrc = pConsole->configConstructorInner(pVM, &alock);
    561562    if (RT_FAILURE(vrc))
    562         pConsole->mpVM = NULL;
     563    {
     564        pConsole->mpUVM = NULL;
     565        VMR3ReleaseUVM(pUVM);
     566    }
    563567
    564568    return vrc;
     
    31693173                    Bstr loc;
    31703174                    hrc = pMedium->COMGETTER(Location)(loc.asOutParam());               H();
    3171                     setVMRuntimeErrorCallbackF(mpVM,
    3172                                             this,
    3173                                             0,
    3174                                             "DvdOrFloppyImageInaccessible",
    3175                                             "The image file '%ls' is inaccessible and is being ignored. Please select a different image file for the virtual %s drive.",
    3176                                             loc.raw(),
    3177                                             (enmType == DeviceType_DVD) ? "DVD" : "floppy");
     3175                    setVMRuntimeErrorCallbackF(VMR3GetVM(mpUVM),
     3176                                               this,
     3177                                               0,
     3178                                               "DvdOrFloppyImageInaccessible",
     3179                                               "The image file '%ls' is inaccessible and is being ignored. Please select a different image file for the virtual %s drive.",
     3180                                               loc.raw(),
     3181                                               enmType == DeviceType_DVD ? "DVD" : "floppy");
    31783182                    pMedium = NULL;
    31793183                }
     
    33913395 *                               (makes only sense for bridged/host-only networks).
    33923396 *
    3393  *  @note Locks this object for writing.
     3397 *  @note   Locks this object for writing.
     3398 *  @thread EMT
    33943399 */
    33953400int Console::configNetwork(const char *pszDevice,
     
    34223427        AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    34233428
    3424         PVM pVM = mpVM;
     3429        PVM pVM = VMR3GetVM(mpUVM);     /* We're on an EMT, so this is safe. */
    34253430
    34263431        ComPtr<IMachine> pMachine = machine();
     
    39043909                    {
    39053910                        struct ifreq Req;
    3906 
    3907                         memset(&Req, 0, sizeof(Req));
     3911                        RT_ZERO(Req);
    39083912                        strncpy(Req.ifr_name, pszHifName, sizeof(Req.ifr_name) - 1);
    39093913                        if (ioctl(iSock, SIOCGIFFLAGS, &Req) >= 0)
    39103914                            if ((Req.ifr_flags & IFF_UP) == 0)
    3911                             {
    3912                                 setVMRuntimeErrorCallbackF(pVM, this, 0, "BridgedInterfaceDown", "Bridged interface %s is down. Guest will not be able to use this interface", pszHifName);
    3913                             }
     3915                                setVMRuntimeErrorCallbackF(pVM, this, 0, "BridgedInterfaceDown",
     3916                                                           "Bridged interface %s is down. Guest will not be able to use this interface",
     3917                                                           pszHifName);
    39143918
    39153919                        close(iSock);
  • trunk/src/VBox/Main/src-client/ConsoleImplTeleporter.cpp

    r35368 r36041  
    5454public:
    5555    ComPtr<Console>     mptrConsole;
    56     PVM                 mpVM;
     56    PUVM                mpUVM;
    5757    ComObjPtr<Progress> mptrProgress;
    5858    Utf8Str             mstrPassword;
     
    6969    /** @} */
    7070
    71     TeleporterState(Console *pConsole, PVM pVM, Progress *pProgress, bool fIsSource)
     71    TeleporterState(Console *pConsole, PUVM pUVM, Progress *pProgress, bool fIsSource)
    7272        : mptrConsole(pConsole)
    73         , mpVM(pVM)
     73        , mpUVM(pUVM)
    7474        , mptrProgress(pProgress)
    7575        , mfIsSource(fIsSource)
     
    8181        , mfIOError(false)
    8282    {
     83        VMR3RetainUVM(mpUVM);
     84    }
     85
     86    ~TeleporterState()
     87    {
     88        VMR3ReleaseUVM(mpUVM);
     89        mpUVM = NULL;
    8390    }
    8491};
     
    98105    bool                mfUnlockedMedia;
    99106
    100     TeleporterStateSrc(Console *pConsole, PVM pVM, Progress *pProgress, MachineState_T enmOldMachineState)
    101         : TeleporterState(pConsole, pVM, pProgress, true /*fIsSource*/)
     107    TeleporterStateSrc(Console *pConsole, PUVM pUVM, Progress *pProgress, MachineState_T enmOldMachineState)
     108        : TeleporterState(pConsole, pUVM, pProgress, true /*fIsSource*/)
    102109        , muPort(UINT32_MAX)
    103110        , mcMsMaxDowntime(250)
     
    124131    Utf8Str                     mErrorText;
    125132
    126     TeleporterStateTrg(Console *pConsole, PVM pVM, Progress *pProgress,
     133    TeleporterStateTrg(Console *pConsole, PUVM pUVM, Progress *pProgress,
    127134                       IMachine *pMachine, IInternalMachineControl *pControl,
    128135                       PRTTIMERLR phTimerLR, bool fStartPaused)
    129         : TeleporterState(pConsole, pVM, pProgress, false /*fIsSource*/)
     136        : TeleporterState(pConsole, pUVM, pProgress, false /*fIsSource*/)
    130137        , mpMachine(pMachine)
    131138        , mpControl(pControl)
     
    566573{
    567574    TeleporterState *pState = (TeleporterState *)pvUser;
    568     SSMR3Cancel(pState->mpVM);
     575    SSMR3Cancel(VMR3GetVM(pState->mpUVM));
    569576    if (!pState->mfIsSource)
    570577    {
     
    590597            if (SUCCEEDED(hrc) && fCanceled)
    591598            {
    592                 SSMR3Cancel(pState->mpVM);
     599                SSMR3Cancel(VMR3GetVM(pState->mpUVM));
    593600                return VERR_SSM_CANCELLED;
    594601            }
     
    678685    RTSocketRetain(pState->mhSocket);
    679686    void *pvUser = static_cast<void *>(static_cast<TeleporterState *>(pState));
    680     vrc = VMR3Teleport(pState->mpVM, pState->mcMsMaxDowntime,
    681                        &g_teleporterTcpOps, pvUser,
    682                        teleporterProgressCallback, pvUser,
     687    vrc = VMR3Teleport(VMR3GetVM(pState->mpUVM),
     688                       pState->mcMsMaxDowntime,
     689                       &g_teleporterTcpOps,         pvUser,
     690                       teleporterProgressCallback,  pvUser,
    683691                       &pState->mfSuspendedByUs);
    684692    RTSocketRelease(pState->mhSocket);
     
    758766     * and do the cleanups afterwards.
    759767     */
    760     AutoVMCaller autoVMCaller(pState->mptrConsole);
    761     HRESULT hrc = autoVMCaller.rc();
     768    SafeVMPtr ptrVM(pState->mptrConsole);
     769    HRESULT hrc = ptrVM.rc();
    762770
    763771    if (SUCCEEDED(hrc))
     
    786794    pState->mptrConsole->mptrCancelableProgress.setNull();
    787795
    788     VMSTATE const        enmVMState      = VMR3GetState(pState->mpVM);
     796    VMSTATE const        enmVMState      = VMR3GetStateU(pState->mpUVM);
    789797    MachineState_T const enmMachineState = pState->mptrConsole->mMachineState;
    790798    if (SUCCEEDED(hrc))
     
    799807        AssertLogRelMsg(enmMachineState == MachineState_TeleportingPausedVM, ("%s\n", Global::stringifyMachineState(enmMachineState)));
    800808
    801         autoVMCaller.release();
     809        ptrVM.release();
    802810
    803811        pState->mptrConsole->mVMIsAlreadyPoweringOff = true; /* (Make sure we stick in the TeleportingPausedVM state.) */
     
    878886                        {
    879887                            autoLock.leave();
    880                             int rc = VMR3Resume(pState->mpVM);
     888                            int rc = VMR3Resume(VMR3GetVM(pState->mpUVM));
    881889                            AssertLogRelMsgRC(rc, ("VMR3Resume -> %Rrc\n", rc));
    882890                            autoLock.enter();
     
    955963    ComObjPtr<Progress> ptrProgress;
    956964    HRESULT hrc = ptrProgress.createObject();
    957     if (FAILED(hrc)) return hrc;
    958     hrc = ptrProgress->init(static_cast<IConsole *>(this),
    959                             Bstr(tr("Teleporter")).raw(),
    960                             TRUE /*aCancelable*/);
    961     if (FAILED(hrc)) return hrc;
    962 
    963     TeleporterStateSrc *pState = new TeleporterStateSrc(this, mpVM, ptrProgress, mMachineState);
     965    if (SUCCEEDED(hrc))
     966        hrc = ptrProgress->init(static_cast<IConsole *>(this),
     967                                Bstr(tr("Teleporter")).raw(),
     968                                TRUE /*aCancelable*/);
     969    if (FAILED(hrc))
     970        return hrc;
     971
     972    TeleporterStateSrc *pState = new TeleporterStateSrc(this, mpUVM, ptrProgress, mMachineState);
    964973    pState->mstrPassword    = aPassword;
    965974    pState->mstrHostname    = aHostname;
     
    10021011 *
    10031012 * @returns VBox status code.
    1004  * @param   pVM                 The VM handle
     1013 * @param   pUVM                The user-mode VM handle
    10051014 * @param   pMachine            The IMachine for the virtual machine.
    10061015 * @param   pErrorMsg           Pointer to the error string for VMSetError.
     
    10151024 */
    10161025HRESULT
    1017 Console::teleporterTrg(PVM pVM, IMachine *pMachine, Utf8Str *pErrorMsg, bool fStartPaused,
     1026Console::teleporterTrg(PUVM pUVM, IMachine *pMachine, Utf8Str *pErrorMsg, bool fStartPaused,
    10181027                       Progress *pProgress, bool *pfPowerOffOnFailure)
    10191028{
    1020     LogThisFunc(("pVM=%p pMachine=%p fStartPaused=%RTbool pProgress=%p\n", pVM, pMachine, fStartPaused, pProgress));
     1029    LogThisFunc(("pUVM=%p pMachine=%p fStartPaused=%RTbool pProgress=%p\n", pUVM, pMachine, fStartPaused, pProgress));
    10211030
    10221031    *pfPowerOffOnFailure = true;
     
    10871096             * Do the job, when it returns we're done.
    10881097             */
    1089             TeleporterStateTrg theState(this, pVM, pProgress, pMachine, mControl, &hTimerLR, fStartPaused);
     1098            TeleporterStateTrg theState(this, pUVM, pProgress, pMachine, mControl, &hTimerLR, fStartPaused);
    10901099            theState.mstrPassword      = strPassword;
    10911100            theState.mhServer          = hServer;
     
    11111120                        else
    11121121                        {
    1113                             VMSTATE enmVMState = VMR3GetState(pVM);
     1122                            VMSTATE enmVMState = VMR3GetStateU(pUVM);
    11141123                            if (    enmVMState != VMSTATE_OFF
    11151124                                &&  enmVMState != VMSTATE_POWERING_OFF)
     
    13201329                break;
    13211330
    1322             int vrc2 = VMR3AtErrorRegister(pState->mpVM, Console::genericVMSetErrorCallback, &pState->mErrorText); AssertRC(vrc2);
     1331            int vrc2 = VMR3AtErrorRegisterU(pState->mpUVM,
     1332                                            Console::genericVMSetErrorCallback, &pState->mErrorText); AssertRC(vrc2);
    13231333            RTSocketRetain(pState->mhSocket); /* For concurrent access by I/O thread and EMT. */
    13241334            pState->moffStream = 0;
    13251335
    13261336            void *pvUser2 = static_cast<void *>(static_cast<TeleporterState *>(pState));
    1327             vrc = VMR3LoadFromStream(pState->mpVM, &g_teleporterTcpOps, pvUser2,
     1337            vrc = VMR3LoadFromStream(VMR3GetVM(pState->mpUVM),
     1338                                     &g_teleporterTcpOps, pvUser2,
    13281339                                     teleporterProgressCallback, pvUser2);
    13291340
    13301341            RTSocketRelease(pState->mhSocket);
    1331             vrc2 = VMR3AtErrorDeregister(pState->mpVM, Console::genericVMSetErrorCallback, &pState->mErrorText); AssertRC(vrc2);
     1342            vrc2 = VMR3AtErrorDeregister(VMR3GetVM(pState->mpUVM), Console::genericVMSetErrorCallback, &pState->mErrorText); AssertRC(vrc2);
    13321343
    13331344            if (RT_FAILURE(vrc))
     
    13921403                {
    13931404                    if (!strcmp(szCmd, "hand-over-resume"))
    1394                         vrc = VMR3Resume(pState->mpVM);
     1405                        vrc = VMR3Resume(VMR3GetVM(pState->mpUVM));
    13951406                    else
    13961407                        pState->mptrConsole->setMachineState(MachineState_Paused);
  • trunk/src/VBox/VMM/VMMR3/PDM.cpp

    r35787 r36041  
    20872087    LogFlow(("PDMR3QueryLun: pszDevice=%p:{%s} iInstance=%u iLun=%u ppBase=%p\n",
    20882088             pszDevice, pszDevice, iInstance, iLun, ppBase));
     2089    VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
    20892090
    20902091    /*
  • trunk/src/VBox/VMM/VMMR3/VM.cpp

    r35810 r36041  
    8181#include <iprt/semaphore.h>
    8282#include <iprt/thread.h>
     83#include <iprt/uuid.h>
    8384
    8485
     
    461462    AssertCompile(sizeof(pUVM->vm.s) <= sizeof(pUVM->vm.padding));
    462463
     464    pUVM->vm.s.cUvmRefs      = 1;
    463465    pUVM->vm.s.ppAtStateNext = &pUVM->vm.s.pAtState;
    464466    pUVM->vm.s.ppAtErrorNext = &pUVM->vm.s.pAtError;
     
    466468
    467469    pUVM->vm.s.enmHaltMethod = VMHALTMETHOD_BOOTSTRAP;
     470    RTUuidClear(&pUVM->vm.s.Uuid);
    468471
    469472    /* Initialize the VMCPU array in the UVM. */
     
    563566static int vmR3CreateU(PUVM pUVM, uint32_t cCpus, PFNCFGMCONSTRUCTOR pfnCFGMConstructor, void *pvUserCFGM)
    564567{
    565     int rc = VINF_SUCCESS;
    566 
    567568    /*
    568569     * Load the VMMR0.r0 module so that we can call GVMMR0CreateVM.
    569570     */
    570     rc = PDMR3LdrLoadVMMR0U(pUVM);
     571    int rc = PDMR3LdrLoadVMMR0U(pUVM);
    571572    if (RT_FAILURE(rc))
    572573    {
     
    657658                }
    658659            }
     660
     661            /*
     662             * Get the CPU execution cap.
     663             */
    659664            if (RT_SUCCESS(rc))
    660665            {
    661666                rc = CFGMR3QueryU32Def(pRoot, "CpuExecutionCap", &pVM->uCpuExecutionCap, 100);
    662667                AssertLogRelMsgRC(rc, ("Configuration error: Querying \"CpuExecutionCap\" as integer failed, rc=%Rrc\n", rc));
    663 
     668            }
     669
     670            /*
     671             * Get the VM name and UUID.
     672             */
     673            if (RT_SUCCESS(rc))
     674            {
     675                rc = CFGMR3QueryStringAllocDef(pRoot, "Name", &pUVM->vm.s.pszName, "<unknown>");
     676                AssertLogRelMsg(RT_SUCCESS(rc) && rc != VERR_CFGM_VALUE_NOT_FOUND, ("Configuration error: Querying \"Name\" failed, rc=%Rrc\n", rc));
     677            }
     678
     679            if (RT_SUCCESS(rc))
     680            {
     681                rc = CFGMR3QueryBytes(pRoot, "UUID", &pUVM->vm.s.Uuid, sizeof(pUVM->vm.s.Uuid));
     682                AssertLogRelMsg(RT_SUCCESS(rc) && rc != VERR_CFGM_VALUE_NOT_FOUND, ("Configuration error: Querying \"UUID\" failed, rc=%Rrc\n", rc));
     683            }
     684
     685            if (RT_SUCCESS(rc))
     686            {
    664687                /*
    665688                 * Init the ring-3 components and ring-3 per cpu data, finishing it off
     
    22632286     */
    22642287    if (!pVM)
    2265         return VERR_INVALID_PARAMETER;
     2288        return VERR_INVALID_VM_HANDLE;
    22662289    VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
    22672290    AssertLogRelReturn(!VM_IS_EMT(pVM), VERR_VM_THREAD_IS_EMT);
     
    25412564
    25422565    /*
    2543      * Destroy the MM heap and free the UVM structure.
    2544      */
    2545     MMR3TermUVM(pUVM);
    2546     STAMR3TermUVM(pUVM);
    2547 
     2566     * Release the UVM structure reference.
     2567     */
     2568    VMR3ReleaseUVM(pUVM);
     2569
     2570    /*
     2571     * Clean up and flush logs.
     2572     */
    25482573#ifdef LOG_ENABLED
    25492574    RTLogSetCustomPrefixCallback(NULL, NULL, NULL);
    25502575#endif
    2551     RTTlsFree(pUVM->vm.s.idxTLS);
    2552 
    2553     ASMAtomicUoWriteU32(&pUVM->u32Magic, UINT32_MAX);
    2554     RTMemPageFree(pUVM, RT_OFFSETOF(UVM, aCpus[pUVM->cCpus]));
    2555 
    25562576    RTLogFlush(NULL);
    25572577}
     
    28522872
    28532873/**
     2874 * Gets the user mode VM structure pointer given the VM handle.
     2875 *
     2876 * @returns Pointer to the user mode VM structure on success. NULL if @a pVM is
     2877 *          invalid (asserted).
     2878 * @param   pVM                 The VM handle.
     2879 * @sa      VMR3GetVM, VMR3RetainUVM
     2880 */
     2881VMMR3DECL(PUVM) VMR3GetUVM(PVM pVM)
     2882{
     2883    VM_ASSERT_VALID_EXT_RETURN(pVM, NULL);
     2884    return pVM->pUVM;
     2885}
     2886
     2887
     2888/**
     2889 * Gets the shared VM structure pointer given the pointer to the user mode VM
     2890 * structure.
     2891 *
     2892 * @returns Pointer to the shared VM structure.
     2893 *          NULL if @a pUVM is invalid (asserted) or if no shared VM structure
     2894 *          is currently associated with it.
     2895 * @param   pUVM                The user mode VM handle.
     2896 * @sa      VMR3GetUVM
     2897 */
     2898VMMR3DECL(PVM) VMR3GetVM(PUVM pUVM)
     2899{
     2900    UVM_ASSERT_VALID_EXT_RETURN(pUVM, NULL);
     2901    return pUVM->pVM;
     2902}
     2903
     2904
     2905/**
     2906 * Retain the user mode VM handle.
     2907 *
     2908 * @returns Reference count.
     2909 *          UINT32_MAX if @a pUVM is invalid.
     2910 *
     2911 * @param   pUVM                The user mode VM handle.
     2912 * @sa      VMR3ReleaseUVM
     2913 */
     2914VMMR3DECL(uint32_t) VMR3RetainUVM(PUVM pUVM)
     2915{
     2916    UVM_ASSERT_VALID_EXT_RETURN(pUVM, UINT32_MAX);
     2917    uint32_t cRefs = ASMAtomicIncU32(&pUVM->vm.s.cUvmRefs);
     2918    AssertMsg(cRefs > 0 && cRefs < _64K, ("%u\n", cRefs));
     2919    return cRefs;
     2920}
     2921
     2922
     2923/**
     2924 * Does the final release of the UVM structure.
     2925 *
     2926 * @param   pUVM                The user mode VM handle.
     2927 */
     2928static void vmR3DoReleaseUVM(PUVM pUVM)
     2929{
     2930    /*
     2931     * Free the UVM.
     2932     */
     2933    Assert(!pUVM->pVM);
     2934
     2935    MMR3TermUVM(pUVM);
     2936    STAMR3TermUVM(pUVM);
     2937
     2938    ASMAtomicUoWriteU32(&pUVM->u32Magic, UINT32_MAX);
     2939    RTTlsFree(pUVM->vm.s.idxTLS);
     2940    RTMemPageFree(pUVM, RT_OFFSETOF(UVM, aCpus[pUVM->cCpus]));
     2941}
     2942
     2943
     2944/**
     2945 * Releases a refernece to the mode VM handle.
     2946 *
     2947 * @returns The new reference count, 0 if destroyed.
     2948 *          UINT32_MAX if @a pUVM is invalid.
     2949 *
     2950 * @param   pUVM                The user mode VM handle.
     2951 * @sa      VMR3RetainUVM
     2952 */
     2953VMMR3DECL(uint32_t) VMR3ReleaseUVM(PUVM pUVM)
     2954{
     2955    if (!pUVM)
     2956        return 0;
     2957    UVM_ASSERT_VALID_EXT_RETURN(pUVM, UINT32_MAX);
     2958    uint32_t cRefs = ASMAtomicDecU32(&pUVM->vm.s.cUvmRefs);
     2959    if (!cRefs)
     2960        vmR3DoReleaseUVM(pUVM);
     2961    else
     2962        AssertMsg(cRefs < _64K, ("%u\n", cRefs));
     2963    return cRefs;
     2964}
     2965
     2966
     2967/**
     2968 * Gets the VM name.
     2969 *
     2970 * @returns Pointer to a read-only string containing the name. NULL if called
     2971 *          too early.
     2972 * @param   pUVM                The user mode VM handle.
     2973 */
     2974VMMR3DECL(const char *) VMR3GetName(PUVM pUVM)
     2975{
     2976    UVM_ASSERT_VALID_EXT_RETURN(pUVM, NULL);
     2977    return pUVM->vm.s.pszName;
     2978}
     2979
     2980
     2981/**
     2982 * Gets the VM UUID.
     2983 *
     2984 * @returns pUuid on success, NULL on failure.
     2985 * @param   pUVM                The user mode VM handle.
     2986 * @param   pUuid               Where to store the UUID.
     2987 */
     2988VMMR3DECL(PRTUUID) VMR3GetUuid(PUVM pUVM, PRTUUID pUuid)
     2989{
     2990    UVM_ASSERT_VALID_EXT_RETURN(pUVM, NULL);
     2991    AssertPtrReturn(pUuid, NULL);
     2992
     2993    *pUuid = pUVM->vm.s.Uuid;
     2994    return pUuid;
     2995}
     2996
     2997
     2998/**
    28542999 * Gets the current VM state.
    28553000 *
     
    28603005VMMR3DECL(VMSTATE) VMR3GetState(PVM pVM)
    28613006{
     3007    VM_ASSERT_VALID_EXT_RETURN(pVM, VMSTATE_TERMINATED);
    28623008    return pVM->enmVMState;
     3009}
     3010
     3011
     3012/**
     3013 * Gets the current VM state.
     3014 *
     3015 * @returns The current VM state.
     3016 * @param   pUVM            The user-mode VM handle.
     3017 * @thread  Any
     3018 */
     3019VMMR3DECL(VMSTATE) VMR3GetStateU(PUVM pUVM)
     3020{
     3021    UVM_ASSERT_VALID_EXT_RETURN(pUVM, VMSTATE_TERMINATED);
     3022    if (RT_UNLIKELY(!pUVM->pVM))
     3023        return VMSTATE_TERMINATED;
     3024    return pUVM->pVM->enmVMState;
    28633025}
    28643026
     
    34593621VMMR3DECL(int)   VMR3AtErrorRegister(PVM pVM, PFNVMATERROR pfnAtError, void *pvUser)
    34603622{
     3623    VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
    34613624    return VMR3AtErrorRegisterU(pVM->pUVM, pfnAtError, pvUser);
    34623625}
     
    41694332VMMR3DECL(int) VMR3GetCpuCoreAndPackageIdFromCpuId(PVM pVM, VMCPUID idCpu, uint32_t *pidCpuCore, uint32_t *pidCpuPackage)
    41704333{
     4334    /*
     4335     * Validate input.
     4336     */
     4337    VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
     4338    AssertPtrReturn(pidCpuCore, VERR_INVALID_POINTER);
     4339    AssertPtrReturn(pidCpuPackage, VERR_INVALID_POINTER);
    41714340    if (idCpu >= pVM->cCpus)
    41724341        return VERR_INVALID_CPU_ID;
    41734342
     4343    /*
     4344     * Set return values.
     4345     */
    41744346#ifdef VBOX_WITH_MULTI_CORE
    41754347    *pidCpuCore    = idCpu;
     
    42234395VMMR3DECL(int) VMR3HotUnplugCpu(PVM pVM, VMCPUID idCpu)
    42244396{
     4397    VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
    42254398    AssertReturn(idCpu < pVM->cCpus, VERR_INVALID_CPU_ID);
    42264399
     
    42424415VMMR3DECL(int) VMR3HotPlugCpu(PVM pVM, VMCPUID idCpu)
    42434416{
     4417    VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
    42444418    AssertReturn(idCpu < pVM->cCpus, VERR_INVALID_CPU_ID);
    42454419
     
    42544428 * @returns VBox status code.
    42554429 * @param   pVM                 The VM to operate on.
    4256  * @param   ulCpuExecutionCap   New CPU execution cap
    4257  */
    4258 VMMR3DECL(int) VMR3SetCpuExecutionCap(PVM pVM, unsigned ulCpuExecutionCap)
    4259 {
    4260     AssertReturn(ulCpuExecutionCap > 0 && ulCpuExecutionCap <= 100, VERR_INVALID_PARAMETER);
    4261 
    4262     Log(("VMR3SetCpuExecutionCap: new priority = %d\n", ulCpuExecutionCap));
     4430 * @param   uCpuExecutionCap    New CPU execution cap in precent, 1-100. Where
     4431 *                              100 is max performance (default).
     4432 */
     4433VMMR3DECL(int) VMR3SetCpuExecutionCap(PVM pVM, uint32_t uCpuExecutionCap)
     4434{
     4435    VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
     4436    AssertReturn(uCpuExecutionCap > 0 && uCpuExecutionCap <= 100, VERR_INVALID_PARAMETER);
     4437
     4438    Log(("VMR3SetCpuExecutionCap: new priority = %d\n", uCpuExecutionCap));
    42634439    /* Note: not called from EMT. */
    4264     pVM->uCpuExecutionCap = ulCpuExecutionCap;
     4440    pVM->uCpuExecutionCap = uCpuExecutionCap;
    42654441    return VINF_SUCCESS;
    42664442}
  • trunk/src/VBox/VMM/include/VMInternal.h

    r35346 r36041  
    181181    volatile uint32_t               cReqFree;
    182182    /** Array of pointers to lists of free request packets. Atomic. */
    183     volatile PVMREQ                 apReqFree[9];
     183    volatile PVMREQ                 apReqFree[16-4];
     184
     185    /** The reference count of the UVM handle. */
     186    volatile uint32_t               cUvmRefs;
    184187
    185188#ifdef VBOX_WITH_STATISTICS
     
    294297    /** TLS index for the VMINTUSERPERVMCPU pointer. */
    295298    RTTLS                           idxTLS;
     299
     300    /** The VM name. (Set after the config constructure has been called.) */
     301    char                           *pszName;
     302    /** The VM UUID. (Set after the config constructure has been called.) */
     303    RTUUID                          Uuid;
    296304} VMINTUSERPERVM;
    297305
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette