Changeset 30473 in vbox for trunk/src/VBox/VMM/VMEmt.cpp
- Timestamp:
- Jun 28, 2010 3:45:22 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMEmt.cpp
r29250 r30473 149 149 PVM pVM = pUVM->pVM; 150 150 enmBefore = pVM->enmVMState; 151 if ( VM_FF_ISSET(pVM, VM_FF_TERMINATE) 152 || pUVM->vm.s.fTerminateEMT) 151 if (pUVM->vm.s.fTerminateEMT) 153 152 { 154 153 rc = VINF_EM_TERMINATE; … … 211 210 */ 212 211 if ( rc == VINF_EM_TERMINATE 213 || pUVM->vm.s.fTerminateEMT 214 || ( pUVM->pVM /* pVM may have become invalid by now. */ 215 && VM_FF_ISSET(pUVM->pVM, VM_FF_TERMINATE))) 212 || pUVM->vm.s.fTerminateEMT) 216 213 break; 217 214 } … … 242 239 /* 243 240 * Cleanup and exit. 244 * If EMT(0) called VMR3Destroy, EMT(0) will do all the terminating here.245 241 */ 246 242 Log(("vmR3EmulationThread: Terminating emulation thread! Thread=%#x pUVM=%p rc=%Rrc enmBefore=%d enmVMState=%d\n", 247 243 ThreadSelf, pUVM, rc, enmBefore, pUVM->pVM ? pUVM->pVM->enmVMState : VMSTATE_TERMINATED)); 248 if ( pUVM->vm.s.fEMTDoesTheCleanup 249 && idCpu == 0) 250 { 251 Log(("vmR3EmulationThread: executing delayed Destroy\n")); 252 Assert(pUVM->pVM); 253 vmR3Destroy(pUVM->pVM); 254 vmR3DestroyFinalBitFromEMT(pUVM, idCpu); 255 /* The pUVM structure is now invliad. */ 256 pUVCpu = NULL; 257 pUVM = NULL; 258 } 259 else 260 { 261 vmR3DestroyFinalBitFromEMT(pUVM, idCpu); 262 pUVCpu->vm.s.NativeThreadEMT = NIL_RTNATIVETHREAD; 263 } 244 if ( idCpu == 0 245 && pUVM->pVM) 246 { 247 PVM pVM = pUVM->pVM; 248 vmR3SetTerminated(pVM); 249 pUVM->pVM = NULL; 250 251 /** @todo SMP: This isn't 100% safe. We should wait for the other 252 * threads to finish before destroy the VM. */ 253 int rc2 = SUPR3CallVMMR0Ex(pVM->pVMR0, 0 /*idCpu*/, VMMR0_DO_GVMM_DESTROY_VM, 0, NULL); 254 AssertLogRelRC(rc2); 255 } 256 257 pUVCpu->vm.s.NativeThreadEMT = NIL_RTNATIVETHREAD; 264 258 Log(("vmR3EmulationThread: EMT is terminated.\n")); 265 259 return rc; … … 289 283 290 284 /** 285 * Signal a fatal wait error. 286 * 287 * @returns Fatal error code to be propagated up the call stack. 288 * @param pUVCpu The user mode per CPU structure of the calling 289 * EMT. 290 * @param pszFmt The error format with a single %Rrc in it. 291 * @param rcFmt The status code to format. 292 */ 293 static int vmR3FatalWaitError(PUVMCPU pUVCpu, const char *pszFmt, int rcFmt) 294 { 295 /** @todo This is wrong ... raise a fatal error / guru meditation 296 * instead. */ 297 AssertLogRelMsgFailed((pszFmt, rcFmt)); 298 ASMAtomicUoWriteBool(&pUVCpu->pUVM->vm.s.fTerminateEMT, true); 299 if (pUVCpu->pVM) 300 VM_FF_SET(pUVCpu->pVM, VM_FF_CHECK_VM_STATE); 301 return VERR_INTERNAL_ERROR; 302 } 303 304 305 /** 291 306 * The old halt loop. 292 307 */ … … 362 377 else if (RT_FAILURE(rc)) 363 378 { 364 AssertRC(rc != VERR_INTERRUPTED); 365 AssertMsgFailed(("RTSemEventWait->%Rrc\n", rc)); 366 ASMAtomicUoWriteBool(&pUVCpu->vm.s.fTerminateEMT, true); 367 VM_FF_SET(pVM, VM_FF_TERMINATE); 368 rc = VERR_INTERNAL_ERROR; 379 rc = vmR3FatalWaitError(pUVCpu, "RTSemEventWait->%Rrc\n", rc); 369 380 break; 370 381 } … … 551 562 else if (RT_FAILURE(rc)) 552 563 { 553 AssertRC(rc != VERR_INTERRUPTED); 554 AssertMsgFailed(("RTSemEventWait->%Rrc\n", rc)); 555 ASMAtomicUoWriteBool(&pUVCpu->vm.s.fTerminateEMT, true); 556 VM_FF_SET(pVM, VM_FF_TERMINATE); 557 rc = VERR_INTERNAL_ERROR; 564 rc = vmR3FatalWaitError(pUVCpu, "RTSemEventWait->%Rrc\n", rc); 558 565 break; 559 566 } … … 662 669 else if (RT_FAILURE(rc)) 663 670 { 664 AssertMsgFailed(("VMMR0_DO_GVMM_SCHED_HALT->%Rrc\n", rc)); 665 ASMAtomicUoWriteBool(&pUVCpu->vm.s.fTerminateEMT, true); 666 VM_FF_SET(pVM, VM_FF_TERMINATE); 667 rc = VERR_INTERNAL_ERROR; 671 rc = vmR3FatalWaitError(pUVCpu, "VMMR0_DO_GVMM_SCHED_HALT->%Rrc\n", rc); 668 672 break; 669 673 } … … 720 724 else if (RT_FAILURE(rc)) 721 725 { 722 AssertMsgFailed(("RTSemEventWait->%Rrc\n", rc)); 723 ASMAtomicUoWriteBool(&pUVCpu->vm.s.fTerminateEMT, true); 724 VM_FF_SET(pVM, VM_FF_TERMINATE); 725 rc = VERR_INTERNAL_ERROR; 726 break; 727 } 728 726 rc = vmR3FatalWaitError(pUVCpu, "VMMR0_DO_GVMM_SCHED_HALT->%Rrc\n", rc); 727 break; 728 } 729 729 } 730 730 … … 798 798 ) 799 799 break; 800 if (pUV Cpu->vm.s.fTerminateEMT)800 if (pUVM->vm.s.fTerminateEMT) 801 801 break; 802 802 … … 810 810 else if (RT_FAILURE(rc)) 811 811 { 812 AssertMsgFailed(("RTSemEventWait->%Rrc\n", rc)); 813 ASMAtomicUoWriteBool(&pUVCpu->vm.s.fTerminateEMT, true); 814 if (pUVCpu->pVM) 815 VM_FF_SET(pUVCpu->pVM, VM_FF_TERMINATE); 816 rc = VERR_INTERNAL_ERROR; 817 break; 818 } 819 812 rc = vmR3FatalWaitError(pUVCpu, "RTSemEventWait->%Rrc\n", rc); 813 break; 814 } 820 815 } 821 816 … … 873 868 else if (RT_FAILURE(rc)) 874 869 { 875 AssertMsgFailed(("RTSemEventWait->%Rrc\n", rc)); 876 ASMAtomicUoWriteBool(&pUVCpu->vm.s.fTerminateEMT, true); 877 VM_FF_SET(pVM, VM_FF_TERMINATE); 878 rc = VERR_INTERNAL_ERROR; 879 break; 880 } 881 870 rc = vmR3FatalWaitError(pUVCpu, "RTSemEventWait->%Rrc", rc); 871 break; 872 } 882 873 } 883 874
Note:
See TracChangeset
for help on using the changeset viewer.