VirtualBox

Changeset 19322 in vbox


Ignore:
Timestamp:
May 4, 2009 11:54:21 AM (16 years ago)
Author:
vboxsync
Message:

Deal with reset, suspend, resume, poweroff for SMP guests.

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

Legend:

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

    r19300 r19322  
    37293729                case VINF_EM_RESET:
    37303730                {
    3731                     EMSTATE enmState = emR3Reschedule(pVM, pVCpu, pVCpu->em.s.pCtx);
    3732                     Log2(("EMR3ExecuteVM: VINF_EM_RESET: %d -> %d (%s)\n", pVCpu->em.s.enmState, enmState, EMR3GetStateName(enmState)));
    3733                     pVCpu->em.s.enmState = enmState;
     3731                    if (pVCpu->idCpu == 0)
     3732                    {
     3733                        EMSTATE enmState = emR3Reschedule(pVM, pVCpu, pVCpu->em.s.pCtx);
     3734                        Log2(("EMR3ExecuteVM: VINF_EM_RESET: %d -> %d (%s)\n", pVCpu->em.s.enmState, enmState, EMR3GetStateName(enmState)));
     3735                        pVCpu->em.s.enmState = enmState;
     3736                    }
     3737                    else
     3738                    {
     3739                        /* All other VCPUs go into the halted state until woken up again. */
     3740                        pVCpu->em.s.enmState = EMSTATE_HALTED;
     3741                    }
    37343742                    break;
    37353743                }
  • trunk/src/VBox/VMM/VM.cpp

    r19300 r19322  
    966966static int vmR3InitDoCompleted(PVM pVM, VMINITCOMPLETED enmWhat)
    967967{
    968 
    969968    return VINF_SUCCESS;
    970969}
     
    10351034     */
    10361035    PVMREQ pReq;
    1037     int rc = VMR3ReqCall(pVM, VMCPUID_ANY, &pReq, RT_INDEFINITE_WAIT, (PFNRT)vmR3PowerOn, 1, pVM);
     1036    int rc = VMR3ReqCall(pVM, 0 /* VCPU 0 */, &pReq, RT_INDEFINITE_WAIT, (PFNRT)vmR3PowerOn, 1, pVM);
    10381037    if (RT_SUCCESS(rc))
    10391038    {
     
    11021101
    11031102    /*
    1104      * Request the operation in EMT.
    1105      */
    1106     PVMREQ pReq;
    1107     int rc = VMR3ReqCall(pVM, VMCPUID_ANY, &pReq, RT_INDEFINITE_WAIT, (PFNRT)vmR3Suspend, 1, pVM);
     1103     * Request the operation in EMT. (in reverse order as VCPU 0 does the actual work)
     1104     */
     1105    PVMREQ pReq = NULL;
     1106    int rc = VMR3ReqCall(pVM, VMCPUID_ALL_REVERSE, &pReq, RT_INDEFINITE_WAIT, (PFNRT)vmR3Suspend, 1, pVM);
    11081107    if (RT_SUCCESS(rc))
    11091108    {
     
    11111110        VMR3ReqFree(pReq);
    11121111    }
     1112    else
     1113        Assert(pReq == NULL);
    11131114
    11141115    LogFlow(("VMR3Suspend: returns %Rrc\n", rc));
     
    11551156    }
    11561157
     1158    PVMCPU pVCpu = VMMGetCpu(pVM);
     1159    /* Only VCPU 0 does the actual work. */
     1160    if (pVCpu->idCpu != 0)
     1161        return VINF_EM_SUSPEND;
     1162
    11571163    /*
    11581164     * Change the state, notify the components and resume the execution.
     
    11891195
    11901196    /*
    1191      * Request the operation in EMT.
    1192      */
    1193     PVMREQ pReq;
    1194     int rc = VMR3ReqCall(pVM, VMCPUID_ANY, &pReq, RT_INDEFINITE_WAIT, (PFNRT)vmR3Resume, 1, pVM);
     1197     * Request the operation in EMT. (in VCPU order as VCPU 0 does the actual work)
     1198     */
     1199    PVMREQ pReq = NULL;
     1200    int rc = VMR3ReqCall(pVM, VMCPUID_ALL, &pReq, RT_INDEFINITE_WAIT, (PFNRT)vmR3Resume, 1, pVM);
    11951201    if (RT_SUCCESS(rc))
    11961202    {
     
    11981204        VMR3ReqFree(pReq);
    11991205    }
     1206    else
     1207        Assert(pReq == NULL);
    12001208
    12011209    LogFlow(("VMR3Resume: returns %Rrc\n", rc));
     
    12241232        return VERR_VM_INVALID_VM_STATE;
    12251233    }
     1234
     1235    PVMCPU pVCpu = VMMGetCpu(pVM);
     1236    /* Only VCPU 0 does the actual work. */
     1237    if (pVCpu->idCpu != 0)
     1238        return VINF_EM_RESUME;
    12261239
    12271240    /*
     
    12731286     */
    12741287    PVMREQ pReq;
    1275     int rc = VMR3ReqCall(pVM, VMCPUID_ANY, &pReq, RT_INDEFINITE_WAIT, (PFNRT)vmR3Save, 4, pVM, pszFilename, pfnProgress, pvUser);
     1288    int rc = VMR3ReqCall(pVM, 0 /* VCPU 0 */, &pReq, RT_INDEFINITE_WAIT, (PFNRT)vmR3Save, 4, pVM, pszFilename, pfnProgress, pvUser);
    12761289    if (RT_SUCCESS(rc))
    12771290    {
     
    13681381     */
    13691382    PVMREQ pReq;
    1370     int rc = VMR3ReqCall(pVM, VMCPUID_ANY, &pReq, RT_INDEFINITE_WAIT, (PFNRT)vmR3Load, 4, pVM, pszFilename, pfnProgress, pvUser);
     1383    int rc = VMR3ReqCall(pVM, 0 /* VCPU 0 */, &pReq, RT_INDEFINITE_WAIT, (PFNRT)vmR3Load, 4, pVM, pszFilename, pfnProgress, pvUser);
    13711384    if (RT_SUCCESS(rc))
    13721385    {
     
    14541467
    14551468    /*
    1456      * Request the operation in EMT.
    1457      */
    1458     PVMREQ pReq;
    1459     int rc = VMR3ReqCall(pVM, VMCPUID_ANY, &pReq, RT_INDEFINITE_WAIT, (PFNRT)vmR3PowerOff, 1, pVM);
     1469     * Request the operation in EMT. (in reverse order as VCPU 0 does the actual work)
     1470     */
     1471    PVMREQ pReq = NULL;
     1472    int rc = VMR3ReqCall(pVM, VMCPUID_ALL_REVERSE, &pReq, RT_INDEFINITE_WAIT, (PFNRT)vmR3PowerOff, 1, pVM);
    14601473    if (RT_SUCCESS(rc))
    14611474    {
     
    14631476        VMR3ReqFree(pReq);
    14641477    }
     1478    else
     1479        Assert(pReq == NULL);
    14651480
    14661481    LogFlow(("VMR3PowerOff: returns %Rrc\n", rc));
     
    14921507        return VERR_VM_INVALID_VM_STATE;
    14931508    }
     1509
     1510    PVMCPU pVCpu = VMMGetCpu(pVM);
     1511    /* Only VCPU 0 does the actual work. */
     1512    if (pVCpu->idCpu != 0)
     1513        return VINF_EM_TERMINATE;
    14941514
    14951515    /*
     
    16161636
    16171637    /*
    1618      * If we are the EMT we'll delay the cleanup till later.
    1619      */
    1620     if (VM_IS_EMT(pVM))
     1638     * If we are the EMT of VCPU 0, then we'll delay the cleanup till later.
     1639     */
     1640    if (VMMGetCpuId(pVM) == 0)
    16211641    {
    16221642        pUVM->vm.s.fEMTDoesTheCleanup = true;
    16231643        pUVM->vm.s.fTerminateEMT = true;
    16241644        VM_FF_SET(pVM, VM_FF_TERMINATE);
     1645
     1646        /* Inform all other VCPUs too. */
     1647        for (VMCPUID idCpu = 1; idCpu < pVM->cCPUs; idCpu++)
     1648        {
     1649            /*
     1650             * Request EMT to do the larger part of the destruction.
     1651             */
     1652            PVMREQ pReq = NULL;
     1653            int rc = VMR3ReqCallU(pUVM, idCpu, &pReq, RT_INDEFINITE_WAIT, 0, (PFNRT)vmR3Destroy, 1, pVM);
     1654            if (RT_SUCCESS(rc))
     1655                rc = pReq->iStatus;
     1656            AssertRC(rc);
     1657            VMR3ReqFree(pReq);
     1658        }
    16251659    }
    16261660    else
     
    20742108    /*
    20752109     * Queue reset request to the emulation thread
    2076      * and wait for it to be processed.
     2110     * and wait for it to be processed. (in reverse order as VCPU 0 does the real cleanup)
    20772111     */
    20782112    PVMREQ pReq = NULL;
    2079     rc = VMR3ReqCall(pVM, VMCPUID_ANY, &pReq, 0, (PFNRT)vmR3Reset, 1, pVM);
     2113    rc = VMR3ReqCall(pVM, VMCPUID_ALL_REVERSE, &pReq, RT_INDEFINITE_WAIT, (PFNRT)vmR3Reset, 1, pVM);
     2114    /** @note Can this really happen?? */
    20802115    while (rc == VERR_TIMEOUT)
    20812116        rc = VMR3ReqWait(pReq, RT_INDEFINITE_WAIT);
     2117
    20822118    if (RT_SUCCESS(rc))
    20832119        rc = pReq->iStatus;
     2120    AssertRC(rc);
    20842121    VMR3ReqFree(pReq);
    20852122
     
    21122149static DECLCALLBACK(int) vmR3Reset(PVM pVM)
    21132150{
     2151    PVMCPU pVCpu = VMMGetCpu(pVM);
     2152
     2153    /* Only VCPU 0 does the full cleanup. */
     2154    if (pVCpu->idCpu != 0)
     2155        return VINF_EM_RESET;
     2156
    21142157    /*
    21152158     * As a safety precaution we temporarily change the state while resetting.
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