Changeset 67955 in vbox
- Timestamp:
- Jul 13, 2017 9:13:23 PM (8 years ago)
- svn:sync-xref-src-repo-rev:
- 116953
- Location:
- trunk
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/sup.h
r67821 r67955 1888 1888 SUPR0DECL(int) SUPR0ObjVerifyAccess(void *pvObj, PSUPDRVSESSION pSession, const char *pszObjName); 1889 1889 1890 SUPR0DECL(PVM) SUPR0GetSessionVM(PSUPDRVSESSION pSession); 1891 SUPR0DECL(PGVM) SUPR0GetSessionGVM(PSUPDRVSESSION pSession); 1892 SUPR0DECL(int) SUPR0SetSessionVM(PSUPDRVSESSION pSession, PGVM pGVM, PVM pVM); 1893 1890 1894 SUPR0DECL(int) SUPR0LockMem(PSUPDRVSESSION pSession, RTR3PTR pvR3, uint32_t cPages, PRTHCPHYS paPages); 1891 1895 SUPR0DECL(int) SUPR0UnlockMem(PSUPDRVSESSION pSession, RTR3PTR pvR3); -
trunk/include/VBox/vmm/gvm.h
r62476 r67955 82 82 /** The ring-0 mapping of the VM structure. */ 83 83 PVM pVM; 84 /** The support driver session the VM is associated with. */ 85 PSUPDRVSESSION pSession; 84 86 /** Number of Virtual CPUs, i.e. how many entries there are in aCpus. 85 87 * Same same as VM::cCpus. */ -
trunk/include/VBox/vmm/gvmm.h
r62476 r67955 163 163 GVMMR0DECL(void) GVMMR0DoneInitVM(PVM pVM); 164 164 GVMMR0DECL(bool) GVMMR0DoingTermVM(PVM pVM, PGVM pGVM); 165 GVMMR0DECL(int) GVMMR0DestroyVM(P VM pVM);166 GVMMR0DECL(int) GVMMR0RegisterVCpu(P VM pVM, VMCPUID idCpu);165 GVMMR0DECL(int) GVMMR0DestroyVM(PGVM pGVM, PVM pVM); 166 GVMMR0DECL(int) GVMMR0RegisterVCpu(PGVM pGVM, PVM pVM, VMCPUID idCpu); 167 167 GVMMR0DECL(PGVM) GVMMR0ByHandle(uint32_t hGVM); 168 168 GVMMR0DECL(int) GVMMR0ByVM(PVM pVM, PGVM *ppGVM); … … 201 201 typedef GVMMCREATEVMREQ *PGVMMCREATEVMREQ; 202 202 203 GVMMR0DECL(int) GVMMR0CreateVMReq(PGVMMCREATEVMREQ pReq );203 GVMMR0DECL(int) GVMMR0CreateVMReq(PGVMMCREATEVMREQ pReq, PSUPDRVSESSION pSession); 204 204 205 205 … … 239 239 typedef GVMMQUERYSTATISTICSSREQ *PGVMMQUERYSTATISTICSSREQ; 240 240 241 GVMMR0DECL(int) GVMMR0QueryStatisticsReq(PVM pVM, PGVMMQUERYSTATISTICSSREQ pReq );241 GVMMR0DECL(int) GVMMR0QueryStatisticsReq(PVM pVM, PGVMMQUERYSTATISTICSSREQ pReq, PSUPDRVSESSION pSession); 242 242 243 243 … … 259 259 typedef GVMMRESETSTATISTICSSREQ *PGVMMRESETSTATISTICSSREQ; 260 260 261 GVMMR0DECL(int) GVMMR0ResetStatisticsReq(PVM pVM, PGVMMRESETSTATISTICSSREQ pReq );261 GVMMR0DECL(int) GVMMR0ResetStatisticsReq(PVM pVM, PGVMMRESETSTATISTICSSREQ pReq, PSUPDRVSESSION pSession); 262 262 263 263 -
trunk/include/VBox/vmm/vmm.h
r62476 r67955 516 516 517 517 #if defined(IN_RING0) || defined(DOXYGEN_RUNNING) 518 VMMR0DECL( int) VMMR0EntryInt(PVM pVM, VMMR0OPERATION enmOperation, void *pvArg);519 VMMR0DECL( void) VMMR0EntryFast(PVM pVM, VMCPUID idCpu, VMMR0OPERATION enmOperation);520 VMMR0DECL(int) VMMR0EntryEx(PVM pVM, VMCPUID idCpu, VMMR0OPERATION enmOperation,PSUPVMMR0REQHDR pReq, uint64_t u64Arg, PSUPDRVSESSION);518 VMMR0DECL(void) VMMR0EntryFast(PGVM pGVM, PVM pVM, VMCPUID idCpu, VMMR0OPERATION enmOperation); 519 VMMR0DECL(int) VMMR0EntryEx(PGVM pGVM, PVM pVM, VMCPUID idCpu, VMMR0OPERATION enmOperation, 520 PSUPVMMR0REQHDR pReq, uint64_t u64Arg, PSUPDRVSESSION); 521 521 VMMR0_INT_DECL(int) VMMR0TermVM(PVM pVM, PGVM pGVM); 522 522 VMMR0_INT_DECL(bool) VMMR0IsLongJumpArmed(PVMCPU pVCpu); -
trunk/src/VBox/HostDrivers/Support/SUPDrv.cpp
r67823 r67955 218 218 { "SUPR0PageFree", (void *)(uintptr_t)SUPR0PageFree }, 219 219 { "SUPR0Printf", (void *)(uintptr_t)SUPR0Printf }, 220 { "SUPR0GetSessionGVM", (void *)(uintptr_t)SUPR0GetSessionGVM }, 221 { "SUPR0GetSessionVM", (void *)(uintptr_t)SUPR0GetSessionVM }, 222 { "SUPR0SetSessionVM", (void *)(uintptr_t)SUPR0SetSessionVM }, 220 223 { "SUPR0TscDeltaMeasureBySetIndex", (void *)(uintptr_t)SUPR0TscDeltaMeasureBySetIndex }, 221 224 { "SUPR0TracerDeregisterDrv", (void *)(uintptr_t)SUPR0TracerDeregisterDrv }, … … 924 927 925 928 /* 929 * Make sure the associated VM pointers are NULL. 930 */ 931 if (pSession->pSessionGVM || pSession->pSessionVM || pSession->pFastIoCtrlVM) 932 { 933 SUPR0Printf("supdrvCleanupSession: VM not disassociated! pSessionGVM=%p pSessionVM=%p pFastIoCtrlVM=%p\n", 934 pSession->pSessionGVM, pSession->pSessionVM, pSession->pFastIoCtrlVM); 935 pSession->pSessionGVM = NULL; 936 pSession->pSessionVM = NULL; 937 pSession->pFastIoCtrlVM = NULL; 938 } 939 940 /* 926 941 * Do tracer cleanups related to this session. 927 942 */ … … 1424 1439 { 1425 1440 /* 1426 * We check the two prereqs after doing this only to allow the compiler to optimize things better. 1427 */ 1428 if (RT_LIKELY( RT_VALID_PTR(pSession) 1429 && pSession->pVM 1430 && pDevExt->pfnVMMR0EntryFast)) 1431 { 1432 switch (uIOCtl) 1433 { 1434 case SUP_IOCTL_FAST_DO_RAW_RUN: 1435 pDevExt->pfnVMMR0EntryFast(pSession->pVM, idCpu, SUP_VMMR0_DO_RAW_RUN); 1436 break; 1437 case SUP_IOCTL_FAST_DO_HM_RUN: 1438 pDevExt->pfnVMMR0EntryFast(pSession->pVM, idCpu, SUP_VMMR0_DO_HM_RUN); 1439 break; 1440 case SUP_IOCTL_FAST_DO_NOP: 1441 pDevExt->pfnVMMR0EntryFast(pSession->pVM, idCpu, SUP_VMMR0_DO_NOP); 1442 break; 1443 default: 1444 return VERR_INTERNAL_ERROR; 1445 } 1446 return VINF_SUCCESS; 1447 } 1441 * Validate input and check that the VM has a session. 1442 */ 1443 if (RT_LIKELY(RT_VALID_PTR(pSession))) 1444 { 1445 PVM pVM = pSession->pSessionVM; 1446 PGVM pGVM = pSession->pSessionGVM; 1447 if (RT_LIKELY( pGVM != NULL 1448 && pVM != NULL 1449 && pVM == pSession->pFastIoCtrlVM)) 1450 { 1451 if (RT_LIKELY(pDevExt->pfnVMMR0EntryFast)) 1452 { 1453 /* 1454 * Do the call. 1455 */ 1456 switch (uIOCtl) 1457 { 1458 case SUP_IOCTL_FAST_DO_RAW_RUN: 1459 pDevExt->pfnVMMR0EntryFast(pGVM, pVM, idCpu, SUP_VMMR0_DO_RAW_RUN); 1460 break; 1461 case SUP_IOCTL_FAST_DO_HM_RUN: 1462 pDevExt->pfnVMMR0EntryFast(pGVM, pVM, idCpu, SUP_VMMR0_DO_HM_RUN); 1463 break; 1464 case SUP_IOCTL_FAST_DO_NOP: 1465 pDevExt->pfnVMMR0EntryFast(pGVM, pVM, idCpu, SUP_VMMR0_DO_NOP); 1466 break; 1467 default: 1468 return VERR_INTERNAL_ERROR; 1469 } 1470 return VINF_SUCCESS; 1471 } 1472 1473 SUPR0Printf("supdrvIOCtlFast: pfnVMMR0EntryFast is NULL\n"); 1474 } 1475 else 1476 SUPR0Printf("supdrvIOCtlFast: Misconfig session: pGVM=%p pVM=%p pFastIoCtrlVM=%p\n", 1477 pGVM, pVM, pSession->pFastIoCtrlVM); 1478 } 1479 else 1480 SUPR0Printf("supdrvIOCtlFast: Bad session pointer %p\n", pSession); 1448 1481 return VERR_INTERNAL_ERROR; 1449 1482 } … … 1781 1814 /* execute */ 1782 1815 if (RT_LIKELY(pDevExt->pfnVMMR0EntryEx)) 1783 pReq->Hdr.rc = pDevExt->pfnVMMR0EntryEx(pReq->u.In.pVMR0, pReq->u.In.idCpu, pReq->u.In.uOperation, NULL, pReq->u.In.u64Arg, pSession); 1816 { 1817 if (pReq->u.In.pVMR0 == NULL) 1818 pReq->Hdr.rc = pDevExt->pfnVMMR0EntryEx(NULL, NULL, pReq->u.In.idCpu, 1819 pReq->u.In.uOperation, NULL, pReq->u.In.u64Arg, pSession); 1820 else if (pReq->u.In.pVMR0 == pSession->pSessionVM) 1821 pReq->Hdr.rc = pDevExt->pfnVMMR0EntryEx(pSession->pSessionGVM, pSession->pSessionVM, pReq->u.In.idCpu, 1822 pReq->u.In.uOperation, NULL, pReq->u.In.u64Arg, pSession); 1823 else 1824 pReq->Hdr.rc = VERR_INVALID_VM_HANDLE; 1825 } 1784 1826 else 1785 1827 pReq->Hdr.rc = VERR_WRONG_ORDER; … … 1795 1837 /* execute */ 1796 1838 if (RT_LIKELY(pDevExt->pfnVMMR0EntryEx)) 1797 pReq->Hdr.rc = pDevExt->pfnVMMR0EntryEx(pReq->u.In.pVMR0, pReq->u.In.idCpu, pReq->u.In.uOperation, pVMMReq, pReq->u.In.u64Arg, pSession); 1839 { 1840 if (pReq->u.In.pVMR0 == NULL) 1841 pReq->Hdr.rc = pDevExt->pfnVMMR0EntryEx(NULL, NULL, pReq->u.In.idCpu, 1842 pReq->u.In.uOperation, pVMMReq, pReq->u.In.u64Arg, pSession); 1843 else if (pReq->u.In.pVMR0 == pSession->pSessionVM) 1844 pReq->Hdr.rc = pDevExt->pfnVMMR0EntryEx(pSession->pSessionGVM, pSession->pSessionVM, pReq->u.In.idCpu, 1845 pReq->u.In.uOperation, pVMMReq, pReq->u.In.u64Arg, pSession); 1846 else 1847 pReq->Hdr.rc = VERR_INVALID_VM_HANDLE; 1848 } 1798 1849 else 1799 1850 pReq->Hdr.rc = VERR_WRONG_ORDER; … … 1827 1878 /* execute */ 1828 1879 if (RT_LIKELY(pDevExt->pfnVMMR0EntryEx)) 1829 pReq->Hdr.rc = pDevExt->pfnVMMR0EntryEx(pReq->u.In.pVMR0, pReq->u.In.idCpu, pReq->u.In.uOperation, pVMMReq, pReq->u.In.u64Arg, pSession); 1880 { 1881 if (pReq->u.In.pVMR0 == NULL) 1882 pReq->Hdr.rc = pDevExt->pfnVMMR0EntryEx(NULL, NULL, pReq->u.In.idCpu, pReq->u.In.uOperation, pVMMReq, pReq->u.In.u64Arg, pSession); 1883 else if (pReq->u.In.pVMR0 == pSession->pSessionVM) 1884 pReq->Hdr.rc = pDevExt->pfnVMMR0EntryEx(pSession->pSessionGVM, pSession->pSessionVM, pReq->u.In.idCpu, 1885 pReq->u.In.uOperation, pVMMReq, pReq->u.In.u64Arg, pSession); 1886 else 1887 pReq->Hdr.rc = VERR_INVALID_VM_HANDLE; 1888 } 1830 1889 else 1831 1890 pReq->Hdr.rc = VERR_WRONG_ORDER; … … 1912 1971 && !((uintptr_t)pReq->u.In.pVMR0 & (PAGE_SIZE - 1))), 1913 1972 ("SUP_IOCTL_SET_VM_FOR_FAST: pVMR0=%p!\n", pReq->u.In.pVMR0)); 1973 1914 1974 /* execute */ 1915 pSession->pVM = pReq->u.In.pVMR0; 1916 pReq->Hdr.rc = VINF_SUCCESS; 1975 RTSpinlockAcquire(pDevExt->Spinlock); 1976 if (pSession->pSessionVM == pReq->u.In.pVMR0) 1977 { 1978 if (pSession->pFastIoCtrlVM == NULL) 1979 { 1980 pSession->pFastIoCtrlVM = pSession->pSessionVM; 1981 RTSpinlockRelease(pDevExt->Spinlock); 1982 pReq->Hdr.rc = VINF_SUCCESS; 1983 } 1984 else 1985 { 1986 RTSpinlockRelease(pDevExt->Spinlock); 1987 OSDBGPRINT(("SUP_IOCTL_SET_VM_FOR_FAST: pSession->pFastIoCtrlVM=%p! (pVMR0=%p)\n", 1988 pSession->pFastIoCtrlVM, pReq->u.In.pVMR0)); 1989 pReq->Hdr.rc = VERR_ALREADY_EXISTS; 1990 } 1991 } 1992 else 1993 { 1994 RTSpinlockRelease(pDevExt->Spinlock); 1995 OSDBGPRINT(("SUP_IOCTL_SET_VM_FOR_FAST: pSession->pSessionVM=%p vs pVMR0=%p)\n", 1996 pSession->pSessionVM, pReq->u.In.pVMR0)); 1997 pReq->Hdr.rc = pSession->pSessionVM ? VERR_ACCESS_DENIED : VERR_WRONG_ORDER; 1998 } 1917 1999 return 0; 1918 2000 } … … 3013 3095 3014 3096 /** 3097 * API for the VMMR0 module to get the SUPDRVSESSION::pSessionVM member. 3098 * 3099 * @returns The associated VM pointer. 3100 * @param pSession The session of the current thread. 3101 */ 3102 SUPR0DECL(PVM) SUPR0GetSessionVM(PSUPDRVSESSION pSession) 3103 { 3104 AssertReturn(SUP_IS_SESSION_VALID(pSession), NULL); 3105 return pSession->pSessionVM; 3106 } 3107 3108 3109 /** 3110 * API for the VMMR0 module to get the SUPDRVSESSION::pSessionGVM member. 3111 * 3112 * @returns The associated GVM pointer. 3113 * @param pSession The session of the current thread. 3114 */ 3115 SUPR0DECL(PGVM) SUPR0GetSessionGVM(PSUPDRVSESSION pSession) 3116 { 3117 AssertReturn(SUP_IS_SESSION_VALID(pSession), NULL); 3118 return pSession->pSessionGVM; 3119 } 3120 3121 3122 /** 3123 * API for the VMMR0 module to work the SUPDRVSESSION::pSessionVM member. 3124 * 3125 * This will fail if there is already a VM associated with the session and pVM 3126 * isn't NULL. 3127 * 3128 * @retval VINF_SUCCESS 3129 * @retval VERR_ALREADY_EXISTS if there already is a VM associated with the 3130 * session. 3131 * @retval VERR_INVALID_PARAMETER if only one of the parameters are NULL or if 3132 * the session is invalid. 3133 * 3134 * @param pSession The session of the current thread. 3135 * @param pGVM The GVM to associate with the session. Pass NULL to 3136 * dissassociate. 3137 * @param pVM The VM to associate with the session. Pass NULL to 3138 * dissassociate. 3139 */ 3140 SUPR0DECL(int) SUPR0SetSessionVM(PSUPDRVSESSION pSession, PGVM pGVM, PVM pVM) 3141 { 3142 AssertReturn(SUP_IS_SESSION_VALID(pSession), VERR_INVALID_PARAMETER); 3143 AssertReturn((pGVM != NULL) == (pVM != NULL), VERR_INVALID_PARAMETER); 3144 3145 RTSpinlockAcquire(pSession->pDevExt->Spinlock); 3146 if (pGVM) 3147 { 3148 if (!pSession->pSessionGVM) 3149 { 3150 pSession->pSessionGVM = pGVM; 3151 pSession->pSessionVM = pVM; 3152 pSession->pFastIoCtrlVM = NULL; 3153 } 3154 else 3155 { 3156 RTSpinlockRelease(pSession->pDevExt->Spinlock); 3157 SUPR0Printf("SUPR0SetSessionVM: Unable to associated GVM/VM %p/%p with session %p as it has %p/%p already!\n", 3158 pGVM, pVM, pSession, pSession->pSessionGVM, pSession->pSessionVM); 3159 return VERR_ALREADY_EXISTS; 3160 } 3161 } 3162 else 3163 { 3164 pSession->pSessionGVM = NULL; 3165 pSession->pSessionVM = NULL; 3166 pSession->pFastIoCtrlVM = NULL; 3167 } 3168 RTSpinlockRelease(pSession->pDevExt->Spinlock); 3169 return VINF_SUCCESS; 3170 } 3171 3172 3173 /** 3015 3174 * Lock pages. 3016 3175 * -
trunk/src/VBox/HostDrivers/Support/SUPDrvIOC.h
r67821 r67955 215 215 * - nothing. 216 216 */ 217 #define SUPDRV_IOC_VERSION 0x002 80002217 #define SUPDRV_IOC_VERSION 0x00290000 218 218 219 219 /** SUP_IOCTL_COOKIE. */ -
trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h
r67137 r67955 488 488 RTR0PROCESS R0Process; 489 489 490 /** The VM associated with the session. */ 491 PVM pVM; 490 /** The GVM associated with the session. 491 * This is set by VMMR0. */ 492 PGVM pSessionGVM; 493 /** The VM associated with the session. 494 * This is set by VMMR0. */ 495 PVM pSessionVM; 496 /** Set to pSessionVM if fast I/O controlls are enabled. */ 497 PVM pFastIoCtrlVM; 492 498 /** Handle table for IPRT semaphore wrapper APIs. 493 499 * This takes care of its own locking in an IRQ safe manner. */ … … 588 594 void * volatile pvVMMR0; 589 595 /** VMMR0EntryFast() pointer. */ 590 DECLR0CALLBACKMEMBER(void, pfnVMMR0EntryFast, (P VM pVM, VMCPUID idCpu, unsigneduOperation));596 DECLR0CALLBACKMEMBER(void, pfnVMMR0EntryFast, (PGVM pGVM, PVM pVM, VMCPUID idCpu, uint32_t uOperation)); 591 597 /** VMMR0EntryEx() pointer. */ 592 DECLR0CALLBACKMEMBER(int, pfnVMMR0EntryEx, (PVM pVM, VMCPUID idCpu, unsigned uOperation, PSUPVMMR0REQHDR pReq, uint64_t u64Arg, PSUPDRVSESSION pSession)); 598 DECLR0CALLBACKMEMBER(int, pfnVMMR0EntryEx, (PGVM pGVM, PVM pVM, VMCPUID idCpu, uint32_t uOperation, 599 PSUPVMMR0REQHDR pReq, uint64_t u64Arg, PSUPDRVSESSION pSession)); 593 600 594 601 /** Linked list of loaded code. */ -
trunk/src/VBox/HostDrivers/Support/testcase/tstInt.cpp
r62490 r67955 32 32 #include <VBox/vmm/vm.h> 33 33 #include <VBox/vmm/vmm.h> 34 #include <VBox/vmm/gvmm.h> 34 35 #include <VBox/err.h> 35 36 #include <VBox/param.h> … … 80 81 { 81 82 /* 82 * Create a fake 'VM'.83 * Create a tiny dummy VM so we can do NOP calls into it using the fast I/O control path. 83 84 */ 84 PVMR0 pVMR0 = NIL_RTR0PTR;85 PVM pVM = NULL;86 const unsigned cPages = RT_ALIGN_Z(sizeof(*pVM), PAGE_SIZE) >> PAGE_SHIFT;87 PSUPPAGE paPages = (PSUPPAGE)RTMemAllocZ(cPages * sizeof(SUPPAGE));88 if (paPages)89 rc = SUPR3LowAlloc(cPages, (void **)&pVM, &pVMR0, &paPages[0]);90 else91 rc = VERR_NO_MEMORY;85 GVMMCREATEVMREQ CreateVMReq; 86 CreateVMReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC; 87 CreateVMReq.Hdr.cbReq = sizeof(CreateVMReq); 88 CreateVMReq.pSession = pSession; 89 CreateVMReq.pVMR0 = NIL_RTR0PTR; 90 CreateVMReq.pVMR3 = NULL; 91 CreateVMReq.cCpus = 1; 92 rc = SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_VMCPUID, VMMR0_DO_GVMM_CREATE_VM, 0, &CreateVMReq.Hdr); 92 93 if (RT_SUCCESS(rc)) 93 94 { 94 pVM->pVMRC = 0; 95 pVM->pVMR3 = pVM; 96 pVM->pVMR0 = pVMR0; 97 pVM->paVMPagesR3 = paPages; 98 pVM->pSession = pSession; 95 PVM pVM = CreateVMReq.pVMR3; 96 AssertRelease(VALID_PTR(pVM)); 97 AssertRelease(pVM->pVMR0 == CreateVMReq.pVMR0); 98 AssertRelease(pVM->pSession == pSession); 99 AssertRelease(pVM->cCpus == 1); 100 AssertRelease(pVM->offVMCPU == RT_UOFFSETOF(VM, aCpus)); 99 101 pVM->enmVMState = VMSTATE_CREATED; 100 101 rc = SUPR3SetVMForFastIOCtl(pVMR0); 102 PVMR0 const pVMR0 = pVM->pVMR0; 103 104 rc = SUPR3SetVMForFastIOCtl(pVM->pVMR0); 102 105 if (!rc) 103 106 { 104 105 107 /* 106 108 * Call VMM code with invalid function. … … 182 184 rcRet++; 183 185 } 186 187 rc = SUPR3CallVMMR0Ex(pVM->pVMR0, 0 /*idCpu*/, VMMR0_DO_GVMM_DESTROY_VM, 0, NULL); 188 if (RT_FAILURE(rc)) 189 { 190 RTPrintf("tstInt: VMMR0_DO_GVMM_DESTROY_VM failed: %Rrc\n", rc); 191 rcRet++; 192 } 184 193 } 185 194 else 186 195 { 187 RTPrintf("tstInt: SUPR3ContAlloc(%#zx,,) failed\n", sizeof(*pVM));196 RTPrintf("tstInt: VMMR0_DO_GVMM_CREATE_VM failed\n"); 188 197 rcRet++; 189 198 } -
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.