Changeset 68011 in vbox
- Timestamp:
- Jul 17, 2017 5:34:33 PM (8 years ago)
- svn:sync-xref-src-repo-rev:
- 117023
- Location:
- trunk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/gvmm.h
r68009 r68011 160 160 161 161 GVMMR0DECL(int) GVMMR0CreateVM(PSUPDRVSESSION pSession, uint32_t cCpus, PVM *ppVM); 162 GVMMR0DECL(int) GVMMR0InitVM(P VM pVM);163 GVMMR0DECL(void) GVMMR0DoneInitVM(P VM pVM);164 GVMMR0DECL(bool) GVMMR0DoingTermVM(P VM pVM, PGVM pGVM);162 GVMMR0DECL(int) GVMMR0InitVM(PGVM pGVM); 163 GVMMR0DECL(void) GVMMR0DoneInitVM(PGVM pGVM); 164 GVMMR0DECL(bool) GVMMR0DoingTermVM(PGVM pGVM); 165 165 GVMMR0DECL(int) GVMMR0DestroyVM(PGVM pGVM, PVM pVM); 166 166 GVMMR0DECL(int) GVMMR0RegisterVCpu(PGVM pGVM, PVM pVM, VMCPUID idCpu); -
trunk/include/VBox/vmm/vmm.h
r67983 r68011 523 523 VMMR0DECL(int) VMMR0EntryEx(PGVM pGVM, PVM pVM, VMCPUID idCpu, VMMR0OPERATION enmOperation, 524 524 PSUPVMMR0REQHDR pReq, uint64_t u64Arg, PSUPDRVSESSION); 525 VMMR0_INT_DECL(int) VMMR0TermVM(P VM pVM, PGVM pGVM);525 VMMR0_INT_DECL(int) VMMR0TermVM(PGVM pGVM, PVM pVM, VMCPUID idCpu); 526 526 VMMR0_INT_DECL(bool) VMMR0IsLongJumpArmed(PVMCPU pVCpu); 527 527 VMMR0_INT_DECL(bool) VMMR0IsInRing3LongJump(PVMCPU pVCpu); -
trunk/src/VBox/VMM/VMMR0/GVMMR0.cpp
r68009 r68011 359 359 static void gvmmR0InitPerVMData(PGVM pGVM); 360 360 static DECLCALLBACK(void) gvmmR0HandleObjDestructor(void *pvObj, void *pvGVMM, void *pvHandle); 361 static int gvmmR0ByVM(PVM pVM, PGVM *ppGVM, PGVMM *ppGVMM, bool fTakeUsedLock);362 static int gvmmR0ByVMAndEMT(PVM pVM, VMCPUID idCpu, PGVM *ppGVM, PGVMM *ppGVMM);363 361 static int gvmmR0ByGVMandVM(PGVM pGVM, PVM pVM, PGVMM *ppGVMM, bool fTakeUsedLock); 364 362 static int gvmmR0ByGVMandVMandEMT(PGVM pGVM, PVM pVM, VMCPUID idCpu, PGVMM *ppGVMM); … … 1070 1068 * 1071 1069 * @returns VBox status code. 1072 * @param pVM The cross context VM structure. 1073 */ 1074 GVMMR0DECL(int) GVMMR0InitVM(PVM pVM) 1075 { 1076 LogFlow(("GVMMR0InitVM: pVM=%p\n", pVM)); 1077 1078 /* 1079 * Validate the VM structure, state and handle. 1080 */ 1081 PGVM pGVM; 1082 PGVMM pGVMM; 1083 int rc = gvmmR0ByVMAndEMT(pVM, 0 /* idCpu */, &pGVM, &pGVMM); 1084 if (RT_SUCCESS(rc)) 1085 { 1086 if ( !pGVM->gvmm.s.fDoneVMMR0Init 1087 && pGVM->aCpus[0].gvmm.s.HaltEventMulti == NIL_RTSEMEVENTMULTI) 1088 { 1089 for (VMCPUID i = 0; i < pGVM->cCpus; i++) 1070 * @param pGVM The global (ring-0) VM structure. 1071 */ 1072 GVMMR0DECL(int) GVMMR0InitVM(PGVM pGVM) 1073 { 1074 LogFlow(("GVMMR0InitVM: pGVM=%p\n", pGVM)); 1075 1076 int rc = VERR_INTERNAL_ERROR_3; 1077 if ( !pGVM->gvmm.s.fDoneVMMR0Init 1078 && pGVM->aCpus[0].gvmm.s.HaltEventMulti == NIL_RTSEMEVENTMULTI) 1079 { 1080 for (VMCPUID i = 0; i < pGVM->cCpus; i++) 1081 { 1082 rc = RTSemEventMultiCreate(&pGVM->aCpus[i].gvmm.s.HaltEventMulti); 1083 if (RT_FAILURE(rc)) 1090 1084 { 1091 rc = RTSemEventMultiCreate(&pGVM->aCpus[i].gvmm.s.HaltEventMulti); 1092 if (RT_FAILURE(rc)) 1093 { 1094 pGVM->aCpus[i].gvmm.s.HaltEventMulti = NIL_RTSEMEVENTMULTI; 1095 break; 1096 } 1085 pGVM->aCpus[i].gvmm.s.HaltEventMulti = NIL_RTSEMEVENTMULTI; 1086 break; 1097 1087 } 1098 1088 } 1099 else1100 rc = VERR_WRONG_ORDER;1101 }1089 } 1090 else 1091 rc = VERR_WRONG_ORDER; 1102 1092 1103 1093 LogFlow(("GVMMR0InitVM: returns %Rrc\n", rc)); … … 1110 1100 * of the VM. 1111 1101 * 1112 * @param p VM The cross contextVM structure.1102 * @param pGVM The global (ring-0) VM structure. 1113 1103 * @thread EMT(0) 1114 1104 */ 1115 GVMMR0DECL(void) GVMMR0DoneInitVM(PVM pVM) 1116 { 1117 /* Validate the VM structure, state and handle. */ 1118 PGVM pGVM; 1119 PGVMM pGVMM; 1120 int rc = gvmmR0ByVMAndEMT(pVM, 0 /* idCpu */, &pGVM, &pGVMM); 1121 AssertRCReturnVoid(rc); 1122 1105 GVMMR0DECL(void) GVMMR0DoneInitVM(PGVM pGVM) 1106 { 1123 1107 /* Set the indicator. */ 1124 1108 pGVM->gvmm.s.fDoneVMMR0Init = true; … … 1130 1114 * 1131 1115 * @returns true if termination hasn't been done already, false if it has. 1132 * @param pVM The cross context VM structure.1133 1116 * @param pGVM Pointer to the global VM structure. Optional. 1134 * @thread EMT(0) 1135 */ 1136 GVMMR0DECL(bool) GVMMR0DoingTermVM(P VM pVM, PGVM pGVM)1117 * @thread EMT(0) or session cleanup thread. 1118 */ 1119 GVMMR0DECL(bool) GVMMR0DoingTermVM(PGVM pGVM) 1137 1120 { 1138 1121 /* Validate the VM structure, state and handle. */ 1139 AssertPtrNullReturn(pGVM, false); 1140 AssertReturn(!pGVM || pGVM->u32Magic == GVM_MAGIC, false); 1141 if (!pGVM) 1142 { 1143 PGVMM pGVMM; 1144 int rc = gvmmR0ByVMAndEMT(pVM, 0 /* idCpu */, &pGVM, &pGVMM); 1145 AssertRCReturn(rc, false); 1146 } 1122 AssertPtrReturn(pGVM, false); 1147 1123 1148 1124 /* Set the indicator. */ … … 1260 1236 { 1261 1237 LogFlow(("gvmmR0CleanupVM: Calling VMMR0TermVM\n")); 1262 VMMR0TermVM(pGVM ->pVM, pGVM);1238 VMMR0TermVM(pGVM, pGVM->pVM, NIL_RTCPUID); 1263 1239 } 1264 1240 else … … 1763 1739 PGVMM pGVMM; 1764 1740 return gvmmR0ByVM(pVM, ppGVM, &pGVMM, false /* fTakeUsedLock */); 1765 }1766 1767 1768 /**1769 * Lookup a GVM structure by the shared VM structure and ensuring that the1770 * caller is an EMT thread.1771 *1772 * @returns VBox status code.1773 * @param pVM The cross context VM structure.1774 * @param idCpu The Virtual CPU ID of the calling EMT.1775 * @param ppGVM Where to store the GVM pointer.1776 * @param ppGVMM Where to store the pointer to the GVMM instance data.1777 * @thread EMT1778 *1779 * @remarks This will assert in all failure paths.1780 */1781 static int gvmmR0ByVMAndEMT(PVM pVM, VMCPUID idCpu, PGVM *ppGVM, PGVMM *ppGVMM)1782 {1783 PGVMM pGVMM;1784 GVMM_GET_VALID_INSTANCE(pGVMM, VERR_GVMM_INSTANCE);1785 1786 /*1787 * Validate.1788 */1789 AssertPtrReturn(pVM, VERR_INVALID_POINTER);1790 AssertReturn(!((uintptr_t)pVM & PAGE_OFFSET_MASK), VERR_INVALID_POINTER);1791 1792 uint16_t hGVM = pVM->hSelf;1793 AssertReturn(hGVM != NIL_GVM_HANDLE, VERR_INVALID_HANDLE);1794 AssertReturn(hGVM < RT_ELEMENTS(pGVMM->aHandles), VERR_INVALID_HANDLE);1795 1796 /*1797 * Look it up.1798 */1799 PGVMHANDLE pHandle = &pGVMM->aHandles[hGVM];1800 AssertReturn(pHandle->pVM == pVM, VERR_NOT_OWNER);1801 RTPROCESS ProcId = RTProcSelf();1802 AssertReturn(pHandle->ProcId == ProcId, VERR_NOT_OWNER);1803 AssertPtrReturn(pHandle->pvObj, VERR_NOT_OWNER);1804 1805 PGVM pGVM = pHandle->pGVM;1806 AssertPtrReturn(pGVM, VERR_NOT_OWNER);1807 AssertReturn(pGVM->pVM == pVM, VERR_NOT_OWNER);1808 RTNATIVETHREAD hAllegedEMT = RTThreadNativeSelf();1809 AssertReturn(idCpu < pGVM->cCpus, VERR_INVALID_CPU_ID);1810 AssertReturn(pGVM->aCpus[idCpu].hEMT == hAllegedEMT, VERR_NOT_OWNER);1811 1812 *ppGVM = pGVM;1813 *ppGVMM = pGVMM;1814 return VINF_SUCCESS;1815 1741 } 1816 1742 -
trunk/src/VBox/VMM/VMMR0/VMMR0.cpp
r68009 r68011 349 349 * @returns VBox status code. 350 350 * 351 * @param pGVM The global (ring-0) VM structure. 351 352 * @param pVM The cross context VM structure. 352 353 * @param uSvnRev The SVN revision of the ring-3 part. 353 354 * @param uBuildType Build type indicator. 354 * @thread EMT .355 */ 356 static int vmmR0InitVM(P VM pVM, uint32_t uSvnRev, uint32_t uBuildType)355 * @thread EMT(0) 356 */ 357 static int vmmR0InitVM(PGVM pGVM, PVM pVM, uint32_t uSvnRev, uint32_t uBuildType) 357 358 { 358 359 VMM_CHECK_SMAP_SETUP(); … … 374 375 return VERR_VMM_R0_VERSION_MISMATCH; 375 376 } 376 if ( !VALID_PTR(pVM) 377 || pVM->pVMR0 != pVM) 378 return VERR_INVALID_PARAMETER; 377 378 int rc = GVMMR0ValidateGVMandVMandEMT(pGVM, pVM, 0 /*idCpu*/); 379 if (RT_FAILURE(rc)) 380 return rc; 379 381 380 382 … … 435 437 */ 436 438 VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING); 437 int rc = GVMMR0InitVM(pVM);439 rc = GVMMR0InitVM(pGVM); 438 440 // if (RT_SUCCESS(rc)) 439 441 // rc = GMMR0InitPerVMData(pVM); … … 471 473 if (RT_SUCCESS(rc)) 472 474 { 473 GVMMR0DoneInitVM(p VM);475 GVMMR0DoneInitVM(pGVM); 474 476 VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING); 475 477 return rc; … … 503 505 * @returns VBox status code. 504 506 * 507 * @param pGVM The global (ring-0) VM structure. 505 508 * @param pVM The cross context VM structure. 506 * @param pGVM Pointer to the global VM structure. Optional. 507 * @thread EMT or session clean up thread. 508 */ 509 VMMR0_INT_DECL(int) VMMR0TermVM(PVM pVM, PGVM pGVM) 510 { 509 * @param idCpu Set to 0 if EMT(0) or NIL_VMCPUID if session cleanup 510 * thread. 511 * @thread EMT(0) or session clean up thread. 512 */ 513 VMMR0_INT_DECL(int) VMMR0TermVM(PGVM pGVM, PVM pVM, VMCPUID idCpu) 514 { 515 /* 516 * Check EMT(0) claim if we're called from userland. 517 */ 518 if (idCpu != NIL_VMCPUID) 519 { 520 AssertReturn(idCpu == 0, VERR_INVALID_CPU_ID); 521 int rc = GVMMR0ValidateGVMandVMandEMT(pGVM, pVM, idCpu); 522 if (RT_FAILURE(rc)) 523 return rc; 524 } 525 511 526 #ifdef VBOX_WITH_PCI_PASSTHROUGH 512 527 PciRawR0TermVM(pVM); … … 516 531 * Tell GVMM what we're up to and check that we only do this once. 517 532 */ 518 if (GVMMR0DoingTermVM(p VM, pGVM))533 if (GVMMR0DoingTermVM(pGVM)) 519 534 { 520 535 GIMR0TermVM(pVM); … … 1507 1522 */ 1508 1523 case VMMR0_DO_VMMR0_INIT: 1509 rc = vmmR0InitVM(p VM, RT_LODWORD(u64Arg), RT_HIDWORD(u64Arg));1524 rc = vmmR0InitVM(pGVM, pVM, RT_LODWORD(u64Arg), RT_HIDWORD(u64Arg)); 1510 1525 VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING); 1511 1526 break; … … 1515 1530 */ 1516 1531 case VMMR0_DO_VMMR0_TERM: 1517 rc = VMMR0TermVM(p VM, NULL);1532 rc = VMMR0TermVM(pGVM, pVM, 0 /*idCpu*/); 1518 1533 VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING); 1519 1534 break;
Note:
See TracChangeset
for help on using the changeset viewer.