Changeset 67955 in vbox for trunk/src/VBox/VMM/VMMR0
- Timestamp:
- Jul 13, 2017 9:13:23 PM (8 years ago)
- svn:sync-xref-src-repo-rev:
- 116953
- Location:
- trunk/src/VBox/VMM/VMMR0
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR0/GVMMR0.cpp
r66439 r67955 361 361 static int gvmmR0ByVM(PVM pVM, PGVM *ppGVM, PGVMM *ppGVMM, bool fTakeUsedLock); 362 362 static int gvmmR0ByVMAndEMT(PVM pVM, VMCPUID idCpu, PGVM *ppGVM, PGVMM *ppGVMM); 363 static int gvmmR0ByGVMandVM(PGVM pGVM, PVM pVM, PGVMM *ppGVMM, bool fTakeUsedLock); 364 363 365 #ifdef GVMM_SCHED_WITH_PPT 364 366 static DECLCALLBACK(void) gvmmR0SchedPeriodicPreemptionTimerCallback(PRTTIMER pTimer, void *pvUser, uint64_t iTick); … … 769 771 * @returns VBox status code. 770 772 * @param pReq The request buffer. 771 */ 772 GVMMR0DECL(int) GVMMR0CreateVMReq(PGVMMCREATEVMREQ pReq) 773 * @param pSession The session handle. The VM will be associated with this. 774 */ 775 GVMMR0DECL(int) GVMMR0CreateVMReq(PGVMMCREATEVMREQ pReq, PSUPDRVSESSION pSession) 773 776 { 774 777 /* … … 779 782 if (pReq->Hdr.cbReq != sizeof(*pReq)) 780 783 return VERR_INVALID_PARAMETER; 781 if ( !VALID_PTR(pReq->pSession))784 if (pReq->pSession != pSession) 782 785 return VERR_INVALID_POINTER; 783 786 … … 788 791 pReq->pVMR0 = NULL; 789 792 pReq->pVMR3 = NIL_RTR3PTR; 790 int rc = GVMMR0CreateVM(p Req->pSession, pReq->cCpus, &pVM);793 int rc = GVMMR0CreateVM(pSession, pReq->cCpus, &pVM); 791 794 if (RT_SUCCESS(rc)) 792 795 { … … 833 836 int rc = gvmmR0CreateDestroyLock(pGVMM); 834 837 AssertRCReturn(rc, rc); 838 839 /* 840 * Only one VM per session. 841 */ 842 if (SUPR0GetSessionVM(pSession) != NULL) 843 { 844 gvmmR0CreateDestroyUnlock(pGVMM); 845 SUPR0Printf("GVMMR0CreateVM: The session %p already got a VM: %p\n", pSession, SUPR0GetSessionVM(pSession)); 846 return VERR_ALREADY_EXISTS; 847 } 835 848 836 849 /* … … 883 896 pGVM->pVM = NULL; 884 897 pGVM->cCpus = cCpus; 898 pGVM->pSession = pSession; 885 899 886 900 gvmmR0InitPerVMData(pGVM); … … 960 974 pGVMM->cEMTs += cCpus; 961 975 962 rc = VMMR0ThreadCtxHookCreateForEmt(&pVM->aCpus[0]); 976 /* Associate it with the session and create the context hook for EMT0. */ 977 rc = SUPR0SetSessionVM(pSession, pGVM, pVM); 963 978 if (RT_SUCCESS(rc)) 964 979 { 965 VBOXVMM_R0_GVMM_VM_CREATED(pGVM, pVM, ProcId, (void *)hEMT0, cCpus); 966 967 GVMMR0_USED_EXCLUSIVE_UNLOCK(pGVMM); 968 gvmmR0CreateDestroyUnlock(pGVMM); 969 970 CPUMR0RegisterVCpuThread(&pVM->aCpus[0]); 971 972 *ppVM = pVM; 973 Log(("GVMMR0CreateVM: pVM=%p pVMR3=%p pGVM=%p hGVM=%d\n", pVM, pVM->pVMR3, pGVM, iHandle)); 974 return VINF_SUCCESS; 980 rc = VMMR0ThreadCtxHookCreateForEmt(&pVM->aCpus[0]); 981 if (RT_SUCCESS(rc)) 982 { 983 /* 984 * Done! 985 */ 986 VBOXVMM_R0_GVMM_VM_CREATED(pGVM, pVM, ProcId, (void *)hEMT0, cCpus); 987 988 GVMMR0_USED_EXCLUSIVE_UNLOCK(pGVMM); 989 gvmmR0CreateDestroyUnlock(pGVMM); 990 991 CPUMR0RegisterVCpuThread(&pVM->aCpus[0]); 992 993 *ppVM = pVM; 994 Log(("GVMMR0CreateVM: pVM=%p pVMR3=%p pGVM=%p hGVM=%d\n", pVM, pVM->pVMR3, pGVM, iHandle)); 995 return VINF_SUCCESS; 996 } 997 998 SUPR0SetSessionVM(pSession, NULL, NULL); 975 999 } 976 977 1000 GVMMR0_USED_EXCLUSIVE_UNLOCK(pGVMM); 978 1001 } … … 1139 1162 * 1140 1163 * @returns VBox status code. 1164 * @param pGVM The global (ring-0) VM structure. 1141 1165 * @param pVM The cross context VM structure. 1142 1166 * 1143 1167 * @thread EMT(0) if it's associated with the VM, otherwise any thread. 1144 1168 */ 1145 GVMMR0DECL(int) GVMMR0DestroyVM(P VM pVM)1146 { 1147 LogFlow(("GVMMR0DestroyVM: p VM=%p\n", pVM));1169 GVMMR0DECL(int) GVMMR0DestroyVM(PGVM pGVM, PVM pVM) 1170 { 1171 LogFlow(("GVMMR0DestroyVM: pGVM=%p pVM=%p\n", pGVM, pVM)); 1148 1172 PGVMM pGVMM; 1149 1173 GVMM_GET_VALID_INSTANCE(pGVMM, VERR_GVMM_INSTANCE); … … 1152 1176 * Validate the VM structure, state and caller. 1153 1177 */ 1178 AssertPtrReturn(pGVM, VERR_INVALID_POINTER); 1154 1179 AssertPtrReturn(pVM, VERR_INVALID_POINTER); 1155 1180 AssertReturn(!((uintptr_t)pVM & PAGE_OFFSET_MASK), VERR_INVALID_POINTER); 1181 AssertReturn(pGVM->pVM == pVM, VERR_INVALID_POINTER); 1156 1182 AssertMsgReturn(pVM->enmVMState >= VMSTATE_CREATING && pVM->enmVMState <= VMSTATE_TERMINATED, ("%d\n", pVM->enmVMState), 1157 1183 VERR_WRONG_ORDER); 1158 1184 1159 uint32_t hGVM = p VM->hSelf;1185 uint32_t hGVM = pGVM->hSelf; 1160 1186 AssertReturn(hGVM != NIL_GVM_HANDLE, VERR_INVALID_HANDLE); 1161 1187 AssertReturn(hGVM < RT_ELEMENTS(pGVMM->aHandles), VERR_INVALID_HANDLE); … … 1330 1356 { 1331 1357 pGVMM->cEMTs -= pGVM->cCpus; 1358 1359 if (pGVM->pSession) 1360 SUPR0SetSessionVM(pGVM->pSession, NULL, NULL); 1361 1332 1362 GVMMR0_USED_EXCLUSIVE_UNLOCK(pGVMM); 1333 1363 … … 1405 1435 * 1406 1436 * @returns VBox status code 1407 * @param pVM The cross context VM structure. 1408 * @param idCpu VCPU id. 1409 */ 1410 GVMMR0DECL(int) GVMMR0RegisterVCpu(PVM pVM, VMCPUID idCpu) 1437 * @param pGVM The global (ring-0) VM structure. 1438 * @param pVM The cross context VM structure. 1439 * @param idCpu VCPU id to register the current thread as. 1440 */ 1441 GVMMR0DECL(int) GVMMR0RegisterVCpu(PGVM pGVM, PVM pVM, VMCPUID idCpu) 1411 1442 { 1412 1443 AssertReturn(idCpu != 0, VERR_NOT_OWNER); … … 1415 1446 * Validate the VM structure, state and handle. 1416 1447 */ 1417 PGVM pGVM;1418 1448 PGVMM pGVMM; 1419 int rc = gvmmR0ByVM(pVM, &pGVM, &pGVMM, false /* fTakeUsedLock */); /** @todo take lock here. */ 1420 if (RT_FAILURE(rc)) 1421 return rc; 1422 1423 AssertReturn(idCpu < pGVM->cCpus, VERR_INVALID_CPU_ID); 1424 AssertReturn(pGVM->aCpus[idCpu].hEMT == NIL_RTNATIVETHREAD, VERR_ACCESS_DENIED); 1425 Assert(pGVM->cCpus == pVM->cCpus); 1426 Assert(pVM->aCpus[idCpu].hNativeThreadR0 == NIL_RTNATIVETHREAD); 1427 1428 pVM->aCpus[idCpu].hNativeThreadR0 = pGVM->aCpus[idCpu].hEMT = RTThreadNativeSelf(); 1429 1430 rc = VMMR0ThreadCtxHookCreateForEmt(&pVM->aCpus[idCpu]); 1449 int rc = gvmmR0ByGVMandVM(pGVM, pVM, &pGVMM, false /* fTakeUsedLock */); /** @todo take lock here. */ 1431 1450 if (RT_SUCCESS(rc)) 1432 CPUMR0RegisterVCpuThread(&pVM->aCpus[idCpu]); 1451 { 1452 if (idCpu < pGVM->cCpus) 1453 { 1454 /* Check that the EMT isn't already assigned to a thread. */ 1455 if (pGVM->aCpus[idCpu].hEMT == NIL_RTNATIVETHREAD) 1456 { 1457 Assert(pVM->aCpus[idCpu].hNativeThreadR0 == NIL_RTNATIVETHREAD); 1458 1459 /* A thread may only be one EMT. */ 1460 RTNATIVETHREAD const hNativeSelf = RTThreadNativeSelf(); 1461 for (VMCPUID iCpu = 0; iCpu < pGVM->cCpus; iCpu++) 1462 AssertBreakStmt(pGVM->aCpus[iCpu].hEMT != hNativeSelf, rc = VERR_INVALID_PARAMETER); 1463 if (RT_SUCCESS(rc)) 1464 { 1465 /* 1466 * Do the assignment, then try setup the hook. Undo if that fails. 1467 */ 1468 pVM->aCpus[idCpu].hNativeThreadR0 = pGVM->aCpus[idCpu].hEMT = RTThreadNativeSelf(); 1469 1470 rc = VMMR0ThreadCtxHookCreateForEmt(&pVM->aCpus[idCpu]); 1471 if (RT_SUCCESS(rc)) 1472 CPUMR0RegisterVCpuThread(&pVM->aCpus[idCpu]); 1473 else 1474 pVM->aCpus[idCpu].hNativeThreadR0 = pGVM->aCpus[idCpu].hEMT = NIL_RTNATIVETHREAD; 1475 } 1476 } 1477 else 1478 rc = VERR_ACCESS_DENIED; 1479 } 1480 else 1481 rc = VERR_INVALID_CPU_ID; 1482 } 1433 1483 return rc; 1434 1484 } … … 1545 1595 *ppGVMM = pGVMM; 1546 1596 return VINF_SUCCESS; 1597 } 1598 1599 1600 /** 1601 * Check that the given GVM and VM structures match up. 1602 * 1603 * The calling thread must be in the same process as the VM. All current lookups 1604 * are by threads inside the same process, so this will not be an issue. 1605 * 1606 * @returns VBox status code. 1607 * @param pGVM The global (ring-0) VM structure. 1608 * @param pVM The cross context VM structure. 1609 * @param ppGVMM Where to store the pointer to the GVMM instance data. 1610 * @param fTakeUsedLock Whether to take the used lock or not. We take it in 1611 * shared mode when requested. 1612 * 1613 * Be very careful if not taking the lock as it's 1614 * possible that the VM will disappear then! 1615 * 1616 * @remark This will not assert on an invalid pVM but try return silently. 1617 */ 1618 static int gvmmR0ByGVMandVM(PGVM pGVM, PVM pVM, PGVMM *ppGVMM, bool fTakeUsedLock) 1619 { 1620 /* 1621 * Check the pointers. 1622 */ 1623 int rc; 1624 if (RT_LIKELY(RT_VALID_PTR(pGVM))) 1625 { 1626 if (RT_LIKELY( RT_VALID_PTR(pVM) 1627 && ((uintptr_t)pVM & PAGE_OFFSET_MASK) == 0)) 1628 { 1629 if (RT_LIKELY(pGVM->pVM == pVM)) 1630 { 1631 /* 1632 * Get the pGVMM instance and check the VM handle. 1633 */ 1634 PGVMM pGVMM; 1635 GVMM_GET_VALID_INSTANCE(pGVMM, VERR_GVMM_INSTANCE); 1636 1637 uint16_t hGVM = pGVM->hSelf; 1638 if (RT_LIKELY( hGVM != NIL_GVM_HANDLE 1639 && hGVM < RT_ELEMENTS(pGVMM->aHandles))) 1640 { 1641 RTPROCESS const pidSelf = RTProcSelf(); 1642 PGVMHANDLE pHandle = &pGVMM->aHandles[hGVM]; 1643 if (fTakeUsedLock) 1644 { 1645 rc = GVMMR0_USED_SHARED_LOCK(pGVMM); 1646 AssertRCReturn(rc, rc); 1647 } 1648 1649 if (RT_LIKELY( pHandle->pGVM == pGVM 1650 && pHandle->pVM == pVM 1651 && pHandle->ProcId == pidSelf 1652 && RT_VALID_PTR(pHandle->pvObj))) 1653 { 1654 /* 1655 * Some more VM data consistency checks. 1656 */ 1657 if (RT_LIKELY( pVM->cCpus == pGVM->cCpus 1658 && pVM->hSelf == hGVM 1659 && pVM->enmVMState >= VMSTATE_CREATING 1660 && pVM->enmVMState <= VMSTATE_TERMINATED 1661 && pVM->pVMR0 == pVM)) 1662 { 1663 *ppGVMM = pGVMM; 1664 return VINF_SUCCESS; 1665 } 1666 } 1667 1668 if (fTakeUsedLock) 1669 GVMMR0_USED_SHARED_UNLOCK(pGVMM); 1670 } 1671 } 1672 rc = VERR_INVALID_HANDLE; 1673 } 1674 else 1675 rc = VERR_INVALID_POINTER; 1676 } 1677 else 1678 rc = VERR_INVALID_POINTER; 1679 return rc; 1547 1680 } 1548 1681 … … 2590 2723 * @param pVM The cross context VM structure. Optional. 2591 2724 * @param pReq Pointer to the request packet. 2592 */ 2593 GVMMR0DECL(int) GVMMR0QueryStatisticsReq(PVM pVM, PGVMMQUERYSTATISTICSSREQ pReq) 2725 * @param pSession The current session. 2726 */ 2727 GVMMR0DECL(int) GVMMR0QueryStatisticsReq(PVM pVM, PGVMMQUERYSTATISTICSSREQ pReq, PSUPDRVSESSION pSession) 2594 2728 { 2595 2729 /* … … 2598 2732 AssertPtrReturn(pReq, VERR_INVALID_POINTER); 2599 2733 AssertMsgReturn(pReq->Hdr.cbReq == sizeof(*pReq), ("%#x != %#x\n", pReq->Hdr.cbReq, sizeof(*pReq)), VERR_INVALID_PARAMETER); 2600 2601 return GVMMR0QueryStatistics(&pReq->Stats, pReq->pSession, pVM); 2734 AssertReturn(pReq->pSession == pSession, VERR_INVALID_PARAMETER); 2735 2736 return GVMMR0QueryStatistics(&pReq->Stats, pSession, pVM); 2602 2737 } 2603 2738 … … 2705 2840 * @param pVM The cross context VM structure. Optional. 2706 2841 * @param pReq Pointer to the request packet. 2707 */ 2708 GVMMR0DECL(int) GVMMR0ResetStatisticsReq(PVM pVM, PGVMMRESETSTATISTICSSREQ pReq) 2842 * @param pSession The current session. 2843 */ 2844 GVMMR0DECL(int) GVMMR0ResetStatisticsReq(PVM pVM, PGVMMRESETSTATISTICSSREQ pReq, PSUPDRVSESSION pSession) 2709 2845 { 2710 2846 /* … … 2713 2849 AssertPtrReturn(pReq, VERR_INVALID_POINTER); 2714 2850 AssertMsgReturn(pReq->Hdr.cbReq == sizeof(*pReq), ("%#x != %#x\n", pReq->Hdr.cbReq, sizeof(*pReq)), VERR_INVALID_PARAMETER); 2715 2716 return GVMMR0ResetStatistics(&pReq->Stats, pReq->pSession, pVM); 2717 } 2718 2851 AssertReturn(pReq->pSession == pSession, VERR_INVALID_PARAMETER); 2852 2853 return GVMMR0ResetStatistics(&pReq->Stats, pSession, pVM); 2854 } 2855 -
trunk/src/VBox/VMM/VMMR0/VMMR0.cpp
r67130 r67955 31 31 #include "VMMInternal.h" 32 32 #include <VBox/vmm/vm.h> 33 #include <VBox/vmm/gvm.h> 33 34 #ifdef VBOX_WITH_PCI_PASSTHROUGH 34 35 # include <VBox/vmm/pdmpci.h> … … 930 931 * The Ring 0 entry point, called by the fast-ioctl path. 931 932 * 933 * @param pGVM The global (ring-0) VM structure. 932 934 * @param pVM The cross context VM structure. 933 935 * The return code is stored in pVM->vmm.s.iLastGZRc. … … 936 938 * @remarks Assume called with interrupts _enabled_. 937 939 */ 938 VMMR0DECL(void) VMMR0EntryFast(P VM pVM, VMCPUID idCpu, VMMR0OPERATION enmOperation)940 VMMR0DECL(void) VMMR0EntryFast(PGVM pGVM, PVM pVM, VMCPUID idCpu, VMMR0OPERATION enmOperation) 939 941 { 940 942 /* 941 943 * Validation. 942 944 */ 943 if (RT_UNLIKELY(idCpu >= pVM->cCpus)) 945 if ( idCpu < pGVM->cCpus 946 && pGVM->cCpus == pVM->cCpus) 947 { /*likely*/ } 948 else 949 { 950 SUPR0Printf("VMMR0EntryFast: Bad idCpu=%#x cCpus=%#x/%#x\n", idCpu, pGVM->cCpus, pVM->cCpus); 944 951 return; 945 PVMCPU pVCpu = &pVM->aCpus[idCpu]; 946 if (RT_UNLIKELY(pVCpu->hNativeThreadR0 != RTThreadNativeSelf())) 952 } 953 954 PGVMCPU pGVCpu = &pGVM->aCpus[idCpu]; 955 PVMCPU pVCpu = &pVM->aCpus[idCpu]; 956 RTNATIVETHREAD const hNativeThread = RTThreadNativeSelf(); 957 if (RT_LIKELY( pGVCpu->hEMT == hNativeThread 958 && pVCpu->hNativeThreadR0 == hNativeThread)) 959 { /* likely */ } 960 else 961 { 962 SUPR0Printf("VMMR0EntryFast: Bad thread idCpu=%#x hNativeSelf=%p pGVCpu->hEmt=%p pVCpu->hNativeThreadR0=%p\n", 963 idCpu, hNativeThread, pGVCpu->hEMT, pVCpu->hNativeThreadR0); 947 964 return; 965 } 966 967 /* 968 * SMAP fun. 969 */ 948 970 VMM_CHECK_SMAP_SETUP(); 949 971 VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING); … … 1314 1336 * 1315 1337 * @returns VBox status code. 1338 * @param pGVM The global (ring-0) VM structure. 1316 1339 * @param pVM The cross context VM structure. 1317 1340 * @param idCpu Virtual CPU ID argument. Must be NIL_VMCPUID if pVM … … 1322 1345 * @param u64Arg Some simple constant argument. 1323 1346 * @param pSession The session of the caller. 1347 * 1324 1348 * @remarks Assume called with interrupts _enabled_. 1325 1349 */ 1326 static int vmmR0EntryExWorker(PVM pVM, VMCPUID idCpu, VMMR0OPERATION enmOperation, PSUPVMMR0REQHDR pReqHdr, uint64_t u64Arg, PSUPDRVSESSION pSession) 1327 { 1328 /* 1329 * Common VM pointer validation. 1330 */ 1331 if (pVM) 1350 static int vmmR0EntryExWorker(PGVM pGVM, PVM pVM, VMCPUID idCpu, VMMR0OPERATION enmOperation, 1351 PSUPVMMR0REQHDR pReqHdr, uint64_t u64Arg, PSUPDRVSESSION pSession) 1352 { 1353 /* 1354 * Validate pGVM, pVM and idCpu for consistency and validity. 1355 */ 1356 if ( pGVM != NULL 1357 || pVM != NULL) 1332 1358 { 1333 if (RT_UNLIKELY( !VALID_PTR(pVM) 1334 || ((uintptr_t)pVM & PAGE_OFFSET_MASK))) 1359 if (RT_LIKELY( RT_VALID_PTR(pGVM) 1360 && RT_VALID_PTR(pVM) 1361 && ((uintptr_t)pVM & PAGE_OFFSET_MASK) == 0)) 1362 { /* likely */ } 1363 else 1335 1364 { 1336 SUPR0Printf("vmmR0EntryExWorker: Invalid p VM=%p! (op=%d)\n", pVM, enmOperation);1365 SUPR0Printf("vmmR0EntryExWorker: Invalid pGVM=%p and/or pVM=%p! (op=%d)\n", pGVM, pVM, enmOperation); 1337 1366 return VERR_INVALID_POINTER; 1338 1367 } 1339 if (RT_UNLIKELY( pVM->enmVMState < VMSTATE_CREATING 1340 || pVM->enmVMState > VMSTATE_TERMINATED 1341 || pVM->pVMR0 != pVM)) 1368 1369 if (RT_LIKELY(pGVM->pVM == pVM)) 1370 { /* likely */ } 1371 else 1342 1372 { 1343 SUPR0Printf("vmmR0EntryExWorker: Invalid pVM=%p:{enmVMState=%d, .pVMR0=%p}! (op=%d)\n", 1344 pVM, pVM->enmVMState, pVM->pVMR0, enmOperation); 1373 SUPR0Printf("vmmR0EntryExWorker: pVM mismatch: got %p, pGVM->pVM=%p\n", pVM, pGVM->pVM); 1374 return VERR_INVALID_PARAMETER; 1375 } 1376 1377 if (RT_LIKELY(idCpu == NIL_VMCPUID || idCpu < pGVM->cCpus)) 1378 { /* likely */ } 1379 else 1380 { 1381 SUPR0Printf("vmmR0EntryExWorker: Invalid idCpu %#x (cCpus=%#x)\n", idCpu, pGVM->cCpus); 1382 return VERR_INVALID_PARAMETER; 1383 } 1384 1385 if (RT_LIKELY( pVM->enmVMState >= VMSTATE_CREATING 1386 && pVM->enmVMState <= VMSTATE_TERMINATED 1387 && pVM->cCpus == pGVM->cCpus 1388 && pVM->pSession == pSession 1389 && pVM->pVMR0 == pVM)) 1390 { /* likely */ } 1391 else 1392 { 1393 SUPR0Printf("vmmR0EntryExWorker: Invalid pVM=%p:{.enmVMState=%d, .cCpus=%#x(==%#x), .pSession=%p(==%p), .pVMR0=%p(==%p)}! (op=%d)\n", 1394 pVM, pVM->enmVMState, pVM->cCpus, pGVM->cCpus, pVM->pSession, pSession, pVM->pVMR0, pVM, enmOperation); 1345 1395 return VERR_INVALID_POINTER; 1346 1396 } 1347 1348 if (RT_UNLIKELY(idCpu >= pVM->cCpus && idCpu != NIL_VMCPUID))1349 {1350 SUPR0Printf("vmmR0EntryExWorker: Invalid idCpu (%u vs cCpus=%u)\n", idCpu, pVM->cCpus);1351 return VERR_INVALID_PARAMETER;1352 }1353 1397 } 1354 else if (RT_UNLIKELY(idCpu != NIL_VMCPUID)) 1398 else if (RT_LIKELY(idCpu == NIL_VMCPUID)) 1399 { /* likely */ } 1400 else 1355 1401 { 1356 1402 SUPR0Printf("vmmR0EntryExWorker: Invalid idCpu=%u\n", idCpu); 1357 1403 return VERR_INVALID_PARAMETER; 1358 1404 } 1405 1406 /* 1407 * SMAP fun. 1408 */ 1359 1409 VMM_CHECK_SMAP_SETUP(); 1360 1410 VMM_CHECK_SMAP_CHECK(RT_NOTHING); 1411 1412 /* 1413 * Process the request. 1414 */ 1361 1415 int rc; 1362 1363 1416 switch (enmOperation) 1364 1417 { … … 1367 1420 */ 1368 1421 case VMMR0_DO_GVMM_CREATE_VM: 1369 if (pVM || u64Arg || idCpu != NIL_VMCPUID) 1370 return VERR_INVALID_PARAMETER; 1371 rc = GVMMR0CreateVMReq((PGVMMCREATEVMREQ)pReqHdr); 1422 if (pGVM == NULL && pVM == NULL && u64Arg == 0 && idCpu == NIL_VMCPUID) 1423 rc = GVMMR0CreateVMReq((PGVMMCREATEVMREQ)pReqHdr, pSession); 1424 else 1425 rc = VERR_INVALID_PARAMETER; 1372 1426 VMM_CHECK_SMAP_CHECK(RT_NOTHING); 1373 1427 break; 1374 1428 1375 1429 case VMMR0_DO_GVMM_DESTROY_VM: 1376 if (pReqHdr || u64Arg) 1377 return VERR_INVALID_PARAMETER; 1378 rc = GVMMR0DestroyVM(pVM); 1430 if (pReqHdr == NULL && u64Arg == 0) 1431 rc = GVMMR0DestroyVM(pGVM, pVM); 1432 else 1433 rc = VERR_INVALID_PARAMETER; 1379 1434 VMM_CHECK_SMAP_CHECK(RT_NOTHING); 1380 1435 break; 1381 1436 1382 1437 case VMMR0_DO_GVMM_REGISTER_VMCPU: 1383 { 1384 if (!pVM) 1385 return VERR_INVALID_PARAMETER; 1386 rc = GVMMR0RegisterVCpu(pVM, idCpu); 1387 VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING); 1388 break; 1389 } 1438 if (pGVM != NULL && pVM != NULL ) 1439 rc = GVMMR0RegisterVCpu(pGVM, pVM, idCpu); 1440 else 1441 rc = VERR_INVALID_PARAMETER; 1442 VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING); 1443 break; 1390 1444 1391 1445 case VMMR0_DO_GVMM_SCHED_HALT: … … 1429 1483 if (u64Arg) 1430 1484 return VERR_INVALID_PARAMETER; 1431 rc = GVMMR0QueryStatisticsReq(pVM, (PGVMMQUERYSTATISTICSSREQ)pReqHdr );1485 rc = GVMMR0QueryStatisticsReq(pVM, (PGVMMQUERYSTATISTICSSREQ)pReqHdr, pSession); 1432 1486 VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING); 1433 1487 break; … … 1436 1490 if (u64Arg) 1437 1491 return VERR_INVALID_PARAMETER; 1438 rc = GVMMR0ResetStatisticsReq(pVM, (PGVMMRESETSTATISTICSSREQ)pReqHdr );1492 rc = GVMMR0ResetStatisticsReq(pVM, (PGVMMRESETSTATISTICSSREQ)pReqHdr, pSession); 1439 1493 VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING); 1440 1494 break; … … 1923 1977 typedef struct VMMR0ENTRYEXARGS 1924 1978 { 1979 PGVM pGVM; 1925 1980 PVM pVM; 1926 1981 VMCPUID idCpu; … … 1941 1996 static DECLCALLBACK(int) vmmR0EntryExWrapper(void *pvArgs) 1942 1997 { 1943 return vmmR0EntryExWorker(((PVMMR0ENTRYEXARGS)pvArgs)->pVM, 1998 return vmmR0EntryExWorker(((PVMMR0ENTRYEXARGS)pvArgs)->pGVM, 1999 ((PVMMR0ENTRYEXARGS)pvArgs)->pVM, 1944 2000 ((PVMMR0ENTRYEXARGS)pvArgs)->idCpu, 1945 2001 ((PVMMR0ENTRYEXARGS)pvArgs)->enmOperation, … … 1963 2019 * @remarks Assume called with interrupts _enabled_. 1964 2020 */ 1965 VMMR0DECL(int) VMMR0EntryEx(PVM pVM, VMCPUID idCpu, VMMR0OPERATION enmOperation, PSUPVMMR0REQHDR pReq, uint64_t u64Arg, PSUPDRVSESSION pSession) 2021 VMMR0DECL(int) VMMR0EntryEx(PGVM pGVM, PVM pVM, VMCPUID idCpu, VMMR0OPERATION enmOperation, 2022 PSUPVMMR0REQHDR pReq, uint64_t u64Arg, PSUPDRVSESSION pSession) 1966 2023 { 1967 2024 /* … … 1969 2026 * wrapped in a setjmp so we can assert without causing trouble. 1970 2027 */ 1971 if ( VALID_PTR(pVM) 1972 && pVM->pVMR0 1973 && idCpu < pVM->cCpus) 2028 if ( pVM != NULL 2029 && pGVM != NULL 2030 && idCpu < pGVM->cCpus 2031 && pVM->pVMR0 != NULL) 1974 2032 { 1975 2033 switch (enmOperation) … … 1985 2043 case VMMR0_DO_VMMR0_TERM: 1986 2044 { 1987 PVMCPU pVCpu = &pVM->aCpus[idCpu]; 1988 1989 if (!pVCpu->vmm.s.CallRing3JmpBufR0.pvSavedStack) 1990 break; 1991 1992 /** @todo validate this EMT claim... GVM knows. */ 1993 VMMR0ENTRYEXARGS Args; 1994 Args.pVM = pVM; 1995 Args.idCpu = idCpu; 1996 Args.enmOperation = enmOperation; 1997 Args.pReq = pReq; 1998 Args.u64Arg = u64Arg; 1999 Args.pSession = pSession; 2000 return vmmR0CallRing3SetJmpEx(&pVCpu->vmm.s.CallRing3JmpBufR0, vmmR0EntryExWrapper, &Args); 2045 PGVMCPU pGVCpu = &pGVM->aCpus[idCpu]; 2046 PVMCPU pVCpu = &pVM->aCpus[idCpu]; 2047 RTNATIVETHREAD hNativeThread = RTThreadNativeSelf(); 2048 if (RT_LIKELY( pGVCpu->hEMT == hNativeThread 2049 && pVCpu->hNativeThreadR0 == hNativeThread)) 2050 { 2051 if (!pVCpu->vmm.s.CallRing3JmpBufR0.pvSavedStack) 2052 break; 2053 2054 /** @todo validate this EMT claim... GVM knows. */ 2055 VMMR0ENTRYEXARGS Args; 2056 Args.pGVM = pGVM; 2057 Args.pVM = pVM; 2058 Args.idCpu = idCpu; 2059 Args.enmOperation = enmOperation; 2060 Args.pReq = pReq; 2061 Args.u64Arg = u64Arg; 2062 Args.pSession = pSession; 2063 return vmmR0CallRing3SetJmpEx(&pVCpu->vmm.s.CallRing3JmpBufR0, vmmR0EntryExWrapper, &Args); 2064 } 2065 return VERR_VM_THREAD_NOT_EMT; 2001 2066 } 2002 2067 … … 2005 2070 } 2006 2071 } 2007 return vmmR0EntryExWorker(p VM, idCpu, enmOperation, pReq, u64Arg, pSession);2072 return vmmR0EntryExWorker(pGVM, pVM, idCpu, enmOperation, pReq, u64Arg, pSession); 2008 2073 } 2009 2074
Note:
See TracChangeset
for help on using the changeset viewer.