VirtualBox

Changeset 26214 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Feb 3, 2010 5:18:11 PM (15 years ago)
Author:
vboxsync
Message:

emR3RemExecute: Must leave the REM lock before executing forced actions or we'll deadlock like in #4653.

Location:
trunk/src/VBox/VMM
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/EM.cpp

    r25825 r26214  
    8989static int emR3RemStep(PVM pVM, PVMCPU pVCpu);
    9090static int emR3RemExecute(PVM pVM, PVMCPU pVCpu, bool *pfFFDone);
    91 DECLINLINE(int) emR3RawExecuteInstruction(PVM pVM, PVMCPU pVCpu, const char *pszPrefix, int rcGC = VINF_SUCCESS);
    9291int emR3HighPriorityPostForcedActions(PVM pVM, PVMCPU pVCpu, int rc);
    9392
     
    382381        EM_REG_COUNTER(&pVCpu->em.s.StatIOEmu,                 "/PROF/CPU%d/EM/Emulation/IO",      "Profiling of emR3RawExecuteIOInstruction.");
    383382        EM_REG_COUNTER(&pVCpu->em.s.StatPrivEmu,               "/PROF/CPU%d/EM/Emulation/Priv",    "Profiling of emR3RawPrivileged.");
    384         EM_REG_COUNTER(&pVCpu->em.s.StatMiscEmu,               "/PROF/CPU%d/EM/Emulation/Misc",    "Profiling of emR3RawExecuteInstruction.");
    385383        EM_REG_PROFILE(&pVCpu->em.s.StatHwAccEntry,           "/PROF/CPU%d/EM/HwAccEnter",        "Profiling Hardware Accelerated Mode entry overhead.");
    386384        EM_REG_PROFILE(&pVCpu->em.s.StatHwAccExec,            "/PROF/CPU%d/EM/HwAccExec",         "Profiling Hardware Accelerated Mode execution.");
     
    861859
    862860/**
     861 * emR3RemExecute helper that syncs the state back from REM and leave the REM
     862 * critical section.
     863 *
     864 * @returns false - new fInREMState value.
     865 * @param   pVM         The VM handle.
     866 * @param   pVCpu       The virtual CPU handle.
     867 */
     868DECLINLINE(bool) emR3RemExecuteSyncBack(PVM pVM, PVMCPU pVCpu)
     869{
     870    STAM_PROFILE_START(&pVCpu->em.s.StatREMSync, a);
     871    REMR3StateBack(pVM, pVCpu);
     872    STAM_PROFILE_STOP(&pVCpu->em.s.StatREMSync, a);
     873
     874    EMRemUnlock(pVM);
     875    return false;
     876}
     877
     878
     879/**
    863880 * Executes recompiled code.
    864881 *
     
    894911#endif
    895912
    896     /* Big lock, but you are not supposed to own any lock when coming in here. */
    897     EMRemLock(pVM);
    898 
    899913    /*
    900914     * Spin till we get a forced action which returns anything but VINF_SUCCESS
     
    903917    *pfFFDone = false;
    904918    bool    fInREMState = false;
    905     int     rc = VINF_SUCCESS;
    906 
    907     /* Flush the recompiler TLB if the VCPU has changed. */
    908     if (pVM->em.s.idLastRemCpu != pVCpu->idCpu)
    909     {
    910         REMFlushTBs(pVM);
    911         /* Also sync the entire state. */
    912         CPUMSetChangedFlags(pVCpu, CPUM_CHANGED_ALL);
    913     }
    914     pVM->em.s.idLastRemCpu = pVCpu->idCpu;
    915 
     919    int     rc          = VINF_SUCCESS;
    916920    for (;;)
    917921    {
    918922        /*
    919          * Update REM state if not already in sync.
     923         * Lock REM and update the state if not already in sync.
     924         *
     925         * Note! Big lock, but you are not supposed to own any lock when
     926         *       coming in here.
    920927         */
    921928        if (!fInREMState)
    922929        {
     930            EMRemLock(pVM);
    923931            STAM_PROFILE_START(&pVCpu->em.s.StatREMSync, b);
     932
     933            /* Flush the recompiler translation blocks if the VCPU has changed,
     934               also force a full CPU state resync. */
     935            if (pVM->em.s.idLastRemCpu != pVCpu->idCpu)
     936            {
     937                REMFlushTBs(pVM);
     938                CPUMSetChangedFlags(pVCpu, CPUM_CHANGED_ALL);
     939            }
     940            pVM->em.s.idLastRemCpu = pVCpu->idCpu;
     941
    924942            rc = REMR3State(pVM, pVCpu);
     943
    925944            STAM_PROFILE_STOP(&pVCpu->em.s.StatREMSync, b);
    926945            if (RT_FAILURE(rc))
     
    950969
    951970        /*
    952          * Deal with high priority post execution FFs before doing anything else.
     971         * Deal with high priority post execution FFs before doing anything
     972         * else.  Sync back the state and leave the lock to be on the safe side.
    953973         */
    954974        if (    VM_FF_ISPENDING(pVM, VM_FF_HIGH_PRIORITY_POST_MASK)
    955975            ||  VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_HIGH_PRIORITY_POST_MASK))
     976        {
     977            fInREMState = emR3RemExecuteSyncBack(pVM, pVCpu);
    956978            rc = emR3HighPriorityPostForcedActions(pVM, pVCpu, rc);
     979        }
    957980
    958981        /*
    959982         * Process the returned status code.
    960          * (Try keep this short! Call functions!)
    961983         */
    962984        if (rc != VINF_SUCCESS)
     
    9781000        /*
    9791001         * Check and execute forced actions.
    980          * Sync back the VM state before calling any of these.
     1002         *
     1003         * Sync back the VM state and leave the lock  before calling any of
     1004         * these, you never know what's going to happen here.
    9811005         */
    9821006#ifdef VBOX_HIGH_RES_TIMERS_HACK
     
    9891013l_REMDoForcedActions:
    9901014            if (fInREMState)
    991             {
    992                 STAM_PROFILE_START(&pVCpu->em.s.StatREMSync, d);
    993                 REMR3StateBack(pVM, pVCpu);
    994                 STAM_PROFILE_STOP(&pVCpu->em.s.StatREMSync, d);
    995                 fInREMState = false;
    996             }
     1015                fInREMState = emR3RemExecuteSyncBack(pVM, pVCpu);
    9971016            STAM_REL_PROFILE_ADV_SUSPEND(&pVCpu->em.s.StatREMTotal, a);
    9981017            rc = emR3ForcedActions(pVM, pVCpu, rc);
     
    10131032     */
    10141033    if (fInREMState)
    1015     {
    1016         STAM_PROFILE_START(&pVCpu->em.s.StatREMSync, e);
    1017         REMR3StateBack(pVM, pVCpu);
    1018         STAM_PROFILE_STOP(&pVCpu->em.s.StatREMSync, e);
    1019     }
    1020     EMRemUnlock(pVM);
     1034        fInREMState = emR3RemExecuteSyncBack(pVM, pVCpu);
    10211035
    10221036    STAM_REL_PROFILE_ADV_STOP(&pVCpu->em.s.StatREMTotal, a);
  • trunk/src/VBox/VMM/EMInternal.h

    r21251 r26214  
    380380    /** R3: Profiling of emR3RawPrivileged. */
    381381    STAMPROFILE             StatPrivEmu;
    382     /** R3: Profiling of emR3RawExecuteInstruction. */
    383     STAMPROFILE             StatMiscEmu;
    384382    /** R3: Number of time emR3HwAccExecute is called. */
    385383    STAMCOUNTER             StatHwAccExecuteEntry;
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