- Timestamp:
- Sep 15, 2009 9:30:09 AM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VM.cpp
r23023 r23024 1224 1224 } 1225 1225 1226 VMSTATE enmVMState = pVM->enmVMState;1226 VMSTATE enmVMState = VMR3GetState(pVM); 1227 1227 AssertMsgReturn( enmVMState == VMSTATE_SUSPENDING 1228 1228 || enmVMState == VMSTATE_SUSPENDING_LS, … … 1239 1239 PDMR3Suspend(pVM); 1240 1240 1241 /* Change to the final state. */ 1242 if (pVM->enmVMState != VMSTATE_SUSPENDING_LS) 1243 vmR3SetState(pVM, fFatal ? VMSTATE_FATAL_ERROR : VMSTATE_SUSPENDED, VMSTATE_SUSPENDING); 1241 /* 1242 * Change to the final state. Live saving makes this a wee bit more 1243 * complicated than one would like. 1244 */ 1245 PUVM pUVM = pVM->pUVM; 1246 RTCritSectEnter(&pUVM->vm.s.AtStateCritSect); 1247 VMSTATE enmVMState = pVM->enmVMState; 1248 if (enmVMState != VMSTATE_SUSPENDING_LS) 1249 vmR3SetStateLocked(pVM, pUVM, fFatal ? VMSTATE_FATAL_ERROR : VMSTATE_SUSPENDED, VMSTATE_SUSPENDING); 1244 1250 else if (!fFatal) 1245 vmR3SetState (pVM, VMSTATE_SUSPENDED_LS, VMSTATE_SUSPENDING_LS);1251 vmR3SetStateLocked(pVM, pUVM, VMSTATE_SUSPENDED_LS, VMSTATE_SUSPENDING_LS); 1246 1252 else 1247 1253 { 1248 vmR3SetState (pVM, VMSTATE_FATAL_ERROR_LS, VMSTATE_SUSPENDING_LS);1254 vmR3SetStateLocked(pVM, pUVM, VMSTATE_FATAL_ERROR_LS, VMSTATE_SUSPENDING_LS); 1249 1255 SSMR3Cancel(pVM); 1250 1256 } 1257 RTCritSectLeave(&pUVM->vm.s.AtStateCritSect); 1251 1258 } 1252 1259 … … 1337 1344 * latter seems easy and perhaps more attractive, the former might be 1338 1345 * better wrt TSC/TM... */ 1339 AssertMsgReturn( pVM->enmVMState == VMSTATE_RUNNING, ("%s\n", VMR3GetStateName(pVM->enmVMState)), VERR_VM_INVALID_VM_STATE);1346 AssertMsgReturn(VMR3GetState(pVM) == VMSTATE_RUNNING, ("%s\n", VMR3GetStateName(VMR3GetState(pVM))), VERR_VM_INVALID_VM_STATE); 1340 1347 return VINF_EM_RESUME; 1341 1348 } … … 1433 1440 LogFlow(("vmR3SaveLiveStep2: pVM=%p pSSM=%p\n", pVM, pSSM)); 1434 1441 VM_ASSERT_EMT0(pVM); 1435 Assert( pVM->enmVMState== VMSTATE_SUSPENDED_LS);1442 Assert(VMR3GetState(pVM) == VMSTATE_SUSPENDED_LS); 1436 1443 1437 1444 int rc = SSMR3LiveDoStep2(pSSM); … … 1634 1641 1635 1642 /* 1636 * Request the operation in EMT.1643 * Forward the request to EMT(0). 1637 1644 */ 1638 1645 int rc = VMR3ReqCallWaitU(pVM->pUVM, 0 /*idDstCpu*/, … … 1647 1654 * cycling thru the other EMTs first. 1648 1655 * 1649 * @returns VBox st atus code.1656 * @returns VBox strict status code. 1650 1657 * 1651 1658 * @param pVM The VM handle. … … 1663 1670 if (pVCpu->idCpu == pVM->cCpus - 1) 1664 1671 { 1665 PUVM pUVM = pVM->pUVM; 1666 RTCritSectEnter(&pUVM->vm.s.AtStateCritSect); 1667 1668 VMSTATE enmStateNew; 1669 VMSTATE enmStateOld = pVM->enmVMState; 1670 switch (enmStateOld) 1671 { 1672 case VMSTATE_RUNNING: 1673 case VMSTATE_SUSPENDED: 1674 case VMSTATE_DEBUGGING: 1675 case VMSTATE_LOAD_FAILURE: 1676 case VMSTATE_GURU_MEDITATION: 1677 case VMSTATE_FATAL_ERROR: 1678 enmStateNew = VMSTATE_POWERING_OFF; 1679 break; 1680 1681 case VMSTATE_RUNNING_LS: 1682 case VMSTATE_DEBUGGING_LS: 1683 case VMSTATE_GURU_MEDITATION_LS: 1684 case VMSTATE_FATAL_ERROR_LS: 1685 enmStateNew = VMSTATE_POWERING_OFF_LS; 1686 break; 1687 1688 default: 1689 AssertLogRelMsgFailed(("%s\n", VMR3GetStateName(enmStateOld))); 1690 RTCritSectLeave(&pUVM->vm.s.AtStateCritSect); 1691 return VERR_VM_INVALID_VM_STATE; 1692 } 1693 1694 vmR3SetStateLocked(pVM, pUVM, enmStateNew, enmStateOld); 1695 RTCritSectLeave(&pUVM->vm.s.AtStateCritSect); 1672 int rc = vmR3TrySetState(pVM, "VMR3PowerOff", 10, 1673 VMSTATE_POWERING_OFF, VMSTATE_RUNNING, 1674 VMSTATE_POWERING_OFF, VMSTATE_SUSPENDED, 1675 VMSTATE_POWERING_OFF, VMSTATE_DEBUGGING, 1676 VMSTATE_POWERING_OFF, VMSTATE_LOAD_FAILURE, 1677 VMSTATE_POWERING_OFF, VMSTATE_GURU_MEDITATION, 1678 VMSTATE_POWERING_OFF, VMSTATE_FATAL_ERROR, 1679 VMSTATE_POWERING_OFF_LS, VMSTATE_RUNNING_LS, 1680 VMSTATE_POWERING_OFF_LS, VMSTATE_DEBUGGING_LS, 1681 VMSTATE_POWERING_OFF_LS, VMSTATE_GURU_MEDITATION_LS, 1682 VMSTATE_POWERING_OFF_LS, VMSTATE_FATAL_ERROR_LS); 1683 if (RT_FAILURE(rc)) 1684 return rc; 1696 1685 } 1697 1686 … … 1699 1688 * Check the state. 1700 1689 */ 1701 VMSTATE const enmVMState = pVM->enmVMState;1690 VMSTATE enmVMState = VMR3GetState(pVM); 1702 1691 AssertMsgReturn( enmVMState == VMSTATE_POWERING_OFF 1703 1692 || enmVMState == VMSTATE_POWERING_OFF_LS, … … 1780 1769 PUVM pUVM = pVM->pUVM; 1781 1770 RTCritSectEnter(&pUVM->vm.s.AtStateCritSect); 1782 VMSTATEenmVMState = pVM->enmVMState;1771 enmVMState = pVM->enmVMState; 1783 1772 if (enmVMState == VMSTATE_POWERING_OFF_LS) 1784 1773 vmR3SetStateLocked(pVM, pUVM, VMSTATE_OFF_LS, VMSTATE_POWERING_OFF_LS); … … 1792 1781 1793 1782 /** 1794 * Power Off the VM. 1795 * 1796 * @returns 0 on success. 1797 * @returns VBox error code on failure. 1798 * @param pVM VM which should be destroyed. 1783 * Power off the VM. 1784 * 1785 * @returns VBox status code. When called on EMT, this will be a strict status 1786 * code that has to be propagated up the call stack. 1787 * 1788 * @param pVM The handle of the VM to be powered off. 1789 * 1799 1790 * @thread Any thread. 1800 1791 * @vmstate Suspended, Running, Guru Meditation, Load Failure 1801 * @vmstateto Off 1792 * @vmstateto Off or OffLS 1802 1793 */ 1803 1794 VMMR3DECL(int) VMR3PowerOff(PVM pVM) 1804 1795 { 1805 1796 LogFlow(("VMR3PowerOff: pVM=%p\n", pVM)); 1806 1807 /* 1808 * Validate input. 1809 */ 1810 if (!pVM) 1811 { 1812 AssertMsgFailed(("Invalid VM pointer\n")); 1813 return VERR_INVALID_PARAMETER; 1814 } 1815 1816 /* 1817 * Request the operation in EMT. (in reverse order as VCPU 0 does the actual work) 1797 VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE); 1798 1799 /* 1800 * Forward the request to the EMTs in reverse order, making all the other 1801 * EMTs stop working before EMT(0) comes and does the actual powering off. 1818 1802 */ 1819 1803 int rc = VMR3ReqCallWaitU(pVM->pUVM, VMCPUID_ALL_REVERSE, (PFNRT)vmR3PowerOff, 1, pVM); … … 2355 2339 /* 2356 2340 * The first EMT will try change the state to resetting. 2341 * We do the live save cancellation inside the state critsect because it 2342 * is cleaner and safer. 2357 2343 */ 2358 2344 if (pVCpu->idCpu == pVM->cCpus - 1) … … 2360 2346 PUVM pUVM = pVM->pUVM; 2361 2347 RTCritSectEnter(&pUVM->vm.s.AtStateCritSect); 2362 VMSTATE enmStateOld = pVM->enmVMState; 2363 switch (enmStateOld) 2364 { 2365 case VMSTATE_RUNNING: 2366 case VMSTATE_SUSPENDED: 2367 vmR3SetStateLocked(pVM, pUVM, VMSTATE_RESETTING, enmStateOld); 2368 RTCritSectLeave(&pUVM->vm.s.AtStateCritSect); 2369 break; 2370 2371 case VMSTATE_RUNNING_LS: 2372 vmR3SetStateLocked(pVM, pUVM, VMSTATE_RESETTING_LS, enmStateOld); 2373 RTCritSectLeave(&pUVM->vm.s.AtStateCritSect); 2374 2375 SSMR3Cancel(pVM); 2376 break; 2377 2378 default: 2379 AssertLogRelMsgFailed(("%s\n", VMR3GetStateName(enmStateOld))); 2380 RTCritSectLeave(&pUVM->vm.s.AtStateCritSect); 2381 return VERR_VM_INVALID_VM_STATE; 2382 } 2348 int rc = vmR3TrySetState(pVM, "VMR3Reset", 3, 2349 VMSTATE_RESETTING, VMSTATE_RUNNING, 2350 VMSTATE_RESETTING, VMSTATE_SUSPENDED, 2351 VMSTATE_RESETTING_LS, VMSTATE_RUNNING_LS); 2352 if (rc == 3) 2353 SSMR3Cancel(pVM); 2354 RTCritSectLeave(&pUVM->vm.s.AtStateCritSect); 2355 if (RT_FAILURE(rc)) 2356 return rc; 2383 2357 } 2384 2358 … … 2386 2360 * Check the state. 2387 2361 */ 2388 VMSTATE enmVMState = pVM->enmVMState;2362 VMSTATE enmVMState = VMR3GetState(pVM); 2389 2363 AssertLogRelMsgReturn( enmVMState == VMSTATE_RESETTING 2390 2364 || enmVMState == VMSTATE_RESETTING_LS, … … 2544 2518 * @param enmStateOld The old (current) state. 2545 2519 * @param enmStateNew The proposed new state. 2520 * 2521 * @remarks The reference for this is found in doc/vp/VMM.vpp, the VMSTATE 2522 * diagram (under State Machine Diagram). 2546 2523 */ 2547 2524 static bool vmR3ValidateStateTransition(VMSTATE enmStateOld, VMSTATE enmStateNew) 2548 2525 { 2549 #ifdef /*VBOX_STRICT*/ DEBUG_bird2526 #ifdef VBOX_STRICT 2550 2527 switch (enmStateOld) 2551 2528 { … … 2730 2707 "from destroying the VM. There are restrictions in the way the state changes " 2731 2708 "are propagated up to the EM execution loop and it makes the program flow very " 2732 "difficult to follow.\n")); 2709 "difficult to follow. (%s, expected %s, old %s)\n", 2710 VMR3GetStateName(pVM->enmVMState), VMR3GetStateName(enmStateNew), 2711 VMR3GetStateName(enmStateOld))); 2733 2712 } 2734 2713 } … … 2747 2726 vmR3ValidateStateTransition(enmStateOld, enmStateNew); 2748 2727 2749 Assert(pVM->enmVMState == enmStateOld); 2728 AssertMsg(pVM->enmVMState == enmStateOld, 2729 ("%s != %s\n", VMR3GetStateName(pVM->enmVMState), VMR3GetStateName(enmStateOld))); 2750 2730 pUVM->vm.s.enmPrevVMState = enmStateOld; 2751 2731 pVM->enmVMState = enmStateNew; 2752 2732 2753 2733 vmR3DoAtState(pVM, pUVM, enmStateNew, enmStateOld); 2734 } 2735 2736 2737 /** 2738 * Sets the current VM state. 2739 * 2740 * @param pVM VM handle. 2741 * @param enmStateNew The new state. 2742 * @param enmStateOld The old state (for asserting only). 2743 */ 2744 static void vmR3SetState(PVM pVM, VMSTATE enmStateNew, VMSTATE enmStateOld) 2745 { 2746 PUVM pUVM = pVM->pUVM; 2747 RTCritSectEnter(&pUVM->vm.s.AtStateCritSect); 2748 2749 AssertMsg(pVM->enmVMState == enmStateOld, 2750 ("%s != %s\n", VMR3GetStateName(pVM->enmVMState), VMR3GetStateName(enmStateOld))); 2751 vmR3SetStateLocked(pVM, pUVM, enmStateNew, pVM->enmVMState); 2752 2753 RTCritSectLeave(&pUVM->vm.s.AtStateCritSect); 2754 2754 } 2755 2755 … … 2810 2810 if (RT_FAILURE(rc)) 2811 2811 { 2812 /* bitch */ 2812 /* 2813 * Complain about it. 2814 */ 2813 2815 if (cTransitions == 1) 2814 2816 LogRel(("%s: %s -> %s failed, because the VM state is actually %s\n", … … 2843 2845 2844 2846 2845 2846 /**2847 * Sets the current VM state.2848 *2849 * @param pVM VM handle.2850 * @param enmStateNew The new state.2851 * @param enmStateOld The old state (for asserting only).2852 */2853 static void vmR3SetState(PVM pVM, VMSTATE enmStateNew, VMSTATE enmStateOld)2854 {2855 PUVM pUVM = pVM->pUVM;2856 RTCritSectEnter(&pUVM->vm.s.AtStateCritSect);2857 2858 AssertMsg(enmStateOld == pVM->enmVMState, ("\n", VMR3GetStateName(enmStateOld), VMR3GetStateName(pVM->enmVMState)));2859 vmR3SetStateLocked(pVM, pUVM, enmStateNew, pVM->enmVMState);2860 2861 RTCritSectLeave(&pUVM->vm.s.AtStateCritSect);2862 }2863 2864 2865 2847 /** 2866 2848 * Flag a guru meditation ... a hack. … … 3613 3595 return pUVCpu->vm.s.ThreadEMT; 3614 3596 } 3597
Note:
See TracChangeset
for help on using the changeset viewer.