Changeset 19398 in vbox
- Timestamp:
- May 5, 2009 9:05:11 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR0/GVMMR0.cpp
r19396 r19398 45 45 #include <VBox/vm.h> 46 46 #include <VBox/vmm.h> 47 #include <VBox/param.h> 47 48 #include <VBox/err.h> 48 49 #include <iprt/alloc.h> … … 51 52 #include <VBox/log.h> 52 53 #include <iprt/thread.h> 54 #include <iprt/process.h> 53 55 #include <iprt/param.h> 54 56 #include <iprt/string.h> … … 79 81 /** The session this VM is associated with. */ 80 82 PSUPDRVSESSION pSession; 81 /** The ring-0 handle of the EMT thread (VCPU 0). 82 * This is used for assertions and similar cases where we need to find the VM handle. */ 83 RTNATIVETHREAD hEMTCpu0; 83 /** The ring-0 handle of the EMT0 thread. 84 * This is used for ownership checks as well as looking up a VM handle by thread 85 * at times like assertions. */ 86 RTNATIVETHREAD hEMT0; 87 /** The process ID of the handle owner. 88 * This is used for access checks. */ 89 RTPROCESS ProcId; 84 90 } GVMHANDLE; 85 91 /** Pointer to a global VM handle. */ … … 521 527 return VERR_INVALID_PARAMETER; 522 528 523 RTNATIVETHREAD hEMT = RTThreadNativeSelf(); 524 AssertReturn(hEMT != NIL_RTNATIVETHREAD, VERR_INTERNAL_ERROR); 529 RTNATIVETHREAD hEMT0 = RTThreadNativeSelf(); 530 AssertReturn(hEMT0 != NIL_RTNATIVETHREAD, VERR_INTERNAL_ERROR); 531 RTNATIVETHREAD ProcId = RTProcSelf(); 532 AssertReturn(ProcId != NIL_RTPROCESS, VERR_INTERNAL_ERROR); 525 533 526 534 /* … … 561 569 pHandle->pGVM = NULL; 562 570 pHandle->pSession = pSession; 563 pHandle->hEMTCpu0 = NIL_RTNATIVETHREAD; 571 pHandle->hEMT0 = NIL_RTNATIVETHREAD; 572 pHandle->ProcId = NIL_RTPROCESS; 564 573 565 574 gvmmR0UsedUnlock(pGVMM); … … 641 650 pHandle->pVM = pVM; 642 651 pHandle->pGVM = pGVM; 643 pHandle->hEMTCpu0 = hEMT; 652 pHandle->hEMT0 = hEMT0; 653 pHandle->ProcId = ProcId; 644 654 pGVM->pVM = pVM; 645 pGVM->aCpus[0].hEMT = hEMT ;655 pGVM->aCpus[0].hEMT = hEMT0; 646 656 647 657 gvmmR0UsedUnlock(pGVMM); … … 839 849 AssertReturn(pHandle->pVM == pVM, VERR_NOT_OWNER); 840 850 851 RTPROCESS ProcId = RTProcSelf(); 841 852 RTNATIVETHREAD hSelf = RTThreadNativeSelf(); 842 AssertReturn(pHandle->hEMTCpu0 == hSelf || pHandle->hEMTCpu0 == NIL_RTNATIVETHREAD, VERR_NOT_OWNER); 853 AssertReturn( ( pHandle->hEMT0 == hSelf 854 && pHandle->ProcId == ProcId) 855 || pHandle->hEMT0 == NIL_RTNATIVETHREAD, VERR_NOT_OWNER); 843 856 844 857 /* … … 852 865 /* be careful here because we might theoretically be racing someone else cleaning up. */ 853 866 if ( pHandle->pVM == pVM 854 && ( pHandle->hEMTCpu0 == hSelf 855 || pHandle->hEMTCpu0 == NIL_RTNATIVETHREAD) 867 && ( ( pHandle->hEMT0 == hSelf 868 && pHandle->ProcId == ProcId) 869 || pHandle->hEMT0 == NIL_RTNATIVETHREAD) 856 870 && VALID_PTR(pHandle->pvObj) 857 871 && VALID_PTR(pHandle->pSession) … … 867 881 else 868 882 { 869 SUPR0Printf("GVMMR0DestroyVM: pHandle=%p:{.pVM=%p, hEMTCpu0=%p, .pvObj=%p} pVM=%p hSelf=%p\n",870 pHandle, pHandle->pVM, pHandle->hEMT Cpu0, pHandle->pvObj, pVM, hSelf);883 SUPR0Printf("GVMMR0DestroyVM: pHandle=%p:{.pVM=%p, .hEMT0=%p, .ProcId=%u, .pvObj=%p} pVM=%p hSelf=%p\n", 884 pHandle, pHandle->pVM, pHandle->hEMT0, pHandle->ProcId, pHandle->pvObj, pVM, hSelf); 871 885 gvmmR0CreateDestroyUnlock(pGVMM); 872 886 rc = VERR_INTERNAL_ERROR; … … 1049 1063 ASMAtomicXchgPtr((void * volatile *)&pHandle->pvObj, NULL); 1050 1064 ASMAtomicXchgPtr((void * volatile *)&pHandle->pSession, NULL); 1051 ASMAtomicXchgSize(&pHandle->hEMTCpu0, NIL_RTNATIVETHREAD); 1065 ASMAtomicXchgSize(&pHandle->hEMT0, NIL_RTNATIVETHREAD); 1066 ASMAtomicXchgSize(&pHandle->ProcId, NIL_RTPROCESS); 1052 1067 1053 1068 gvmmR0UsedUnlock(pGVMM); … … 1120 1135 /** 1121 1136 * Lookup a GVM structure by the shared VM structure. 1137 * 1138 * The calling thread must be in the same process as the VM. All current lookups 1139 * are by threads inside the same process, so this will not be an issue. 1122 1140 * 1123 1141 * @returns VBox status code. … … 1133 1151 static int gvmmR0ByVM(PVM pVM, PGVM *ppGVM, PGVMM *ppGVMM, bool fTakeUsedLock) 1134 1152 { 1153 RTPROCESS ProcId = RTProcSelf(); 1135 1154 PGVMM pGVMM; 1136 1155 GVMM_GET_VALID_INSTANCE(pGVMM, VERR_INTERNAL_ERROR); … … 1163 1182 pGVM = pHandle->pGVM; 1164 1183 if (RT_UNLIKELY( pHandle->pVM != pVM 1184 || pHandle->ProcId != ProcId 1165 1185 || !VALID_PTR(pHandle->pvObj) 1166 1186 || !VALID_PTR(pGVM) … … 1174 1194 { 1175 1195 if (RT_UNLIKELY(pHandle->pVM != pVM)) 1196 return VERR_INVALID_HANDLE; 1197 if (RT_UNLIKELY(pHandle->ProcId != ProcId)) 1176 1198 return VERR_INVALID_HANDLE; 1177 1199 if (RT_UNLIKELY(!VALID_PTR(pHandle->pvObj))) … … 1202 1224 GVMMR0DECL(PGVM) GVMMR0ByVM(PVM pVM) 1203 1225 { 1226 PGVM pGVM; 1204 1227 PGVMM pGVMM; 1205 PGVM pGVM;1206 1228 int rc = gvmmR0ByVM(pVM, &pGVM, &pGVMM, false /* fTakeUsedLock */); 1207 1229 if (RT_SUCCESS(rc)) … … 1213 1235 1214 1236 /** 1215 * Lookup a GVM structure by the shared VM structure 1216 * and ensuring that the caller is theEMT thread.1237 * Lookup a GVM structure by the shared VM structure and ensuring that the 1238 * caller is an EMT thread. 1217 1239 * 1218 1240 * @returns VBox status code. … … 1245 1267 PGVMHANDLE pHandle = &pGVMM->aHandles[hGVM]; 1246 1268 AssertReturn(pHandle->pVM == pVM, VERR_NOT_OWNER); 1269 RTPROCESS ProcId = RTProcSelf(); 1270 AssertReturn(pHandle->ProcId == ProcId, VERR_NOT_OWNER); 1247 1271 AssertPtrReturn(pHandle->pvObj, VERR_INTERNAL_ERROR); 1248 1272 … … 1315 1339 if (hEMT == NIL_RTNATIVETHREAD) 1316 1340 hEMT = RTThreadNativeSelf(); 1341 RTPROCESS ProcId = RTProcSelf(); 1317 1342 1318 1343 /* … … 1322 1347 { 1323 1348 if ( pGVMM->aHandles[i].iSelf == i 1349 && pGVMM->aHandles[i].ProcId == ProcId 1324 1350 && VALID_PTR(pGVMM->aHandles[i].pvObj) 1325 1351 && VALID_PTR(pGVMM->aHandles[i].pVM) 1326 1352 && VALID_PTR(pGVMM->aHandles[i].pGVM)) 1327 1353 { 1328 if (pGVMM->aHandles[i].hEMT Cpu0 == hEMT)1354 if (pGVMM->aHandles[i].hEMT0 == hEMT) 1329 1355 return pGVMM->aHandles[i].pVM; 1330 1356 1331 /** @todo this isn't safe as GVM may be deallocated while we're running. 1332 * Will change this to use RTPROCESS on the handle level as storing all the 1333 * thread handles there doesn't scale very well. */ 1357 /* This is fearly safe with the current process per VM approach. */ 1334 1358 PGVM pGVM = pGVMM->aHandles[i].pGVM; 1335 for (VMCPUID idCpu = 0; idCpu < pGVM->cCpus; idCpu++) 1359 VMCPUID const cCpus = pGVM->cCpus; 1360 if ( cCpus < 1 1361 || cCpus > VMM_MAX_CPUS) 1362 continue; 1363 for (VMCPUID idCpu = 1; idCpu < cCpus; idCpu++) 1336 1364 if (pGVM->aCpus[idCpu].hEMT == hEMT) 1337 1365 return pGVMM->aHandles[i].pVM;
Note:
See TracChangeset
for help on using the changeset viewer.