VirtualBox

Changeset 67955 in vbox for trunk/src/VBox/VMM/VMMR0


Ignore:
Timestamp:
Jul 13, 2017 9:13:23 PM (8 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
116953
Message:

VMM,SUPDrv: Started on some session/VMMR0 nits. I/O control interface version bump (sorry).

Location:
trunk/src/VBox/VMM/VMMR0
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR0/GVMMR0.cpp

    r66439 r67955  
    361361static int gvmmR0ByVM(PVM pVM, PGVM *ppGVM, PGVMM *ppGVMM, bool fTakeUsedLock);
    362362static int gvmmR0ByVMAndEMT(PVM pVM, VMCPUID idCpu, PGVM *ppGVM, PGVMM *ppGVMM);
     363static int gvmmR0ByGVMandVM(PGVM pGVM, PVM pVM, PGVMM *ppGVMM, bool fTakeUsedLock);
     364
    363365#ifdef GVMM_SCHED_WITH_PPT
    364366static DECLCALLBACK(void) gvmmR0SchedPeriodicPreemptionTimerCallback(PRTTIMER pTimer, void *pvUser, uint64_t iTick);
     
    769771 * @returns VBox status code.
    770772 * @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 */
     775GVMMR0DECL(int) GVMMR0CreateVMReq(PGVMMCREATEVMREQ pReq, PSUPDRVSESSION pSession)
    773776{
    774777    /*
     
    779782    if (pReq->Hdr.cbReq != sizeof(*pReq))
    780783        return VERR_INVALID_PARAMETER;
    781     if (!VALID_PTR(pReq->pSession))
     784    if (pReq->pSession != pSession)
    782785        return VERR_INVALID_POINTER;
    783786
     
    788791    pReq->pVMR0 = NULL;
    789792    pReq->pVMR3 = NIL_RTR3PTR;
    790     int rc = GVMMR0CreateVM(pReq->pSession, pReq->cCpus, &pVM);
     793    int rc = GVMMR0CreateVM(pSession, pReq->cCpus, &pVM);
    791794    if (RT_SUCCESS(rc))
    792795    {
     
    833836    int rc = gvmmR0CreateDestroyLock(pGVMM);
    834837    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    }
    835848
    836849    /*
     
    883896                        pGVM->pVM       = NULL;
    884897                        pGVM->cCpus     = cCpus;
     898                        pGVM->pSession  = pSession;
    885899
    886900                        gvmmR0InitPerVMData(pGVM);
     
    960974                                        pGVMM->cEMTs += cCpus;
    961975
    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);
    963978                                        if (RT_SUCCESS(rc))
    964979                                        {
    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);
    975999                                        }
    976 
    9771000                                        GVMMR0_USED_EXCLUSIVE_UNLOCK(pGVMM);
    9781001                                    }
     
    11391162 *
    11401163 * @returns VBox status code.
     1164 * @param   pGVM        The global (ring-0) VM structure.
    11411165 * @param   pVM         The cross context VM structure.
    11421166 *
    11431167 * @thread  EMT(0) if it's associated with the VM, otherwise any thread.
    11441168 */
    1145 GVMMR0DECL(int) GVMMR0DestroyVM(PVM pVM)
    1146 {
    1147     LogFlow(("GVMMR0DestroyVM: pVM=%p\n", pVM));
     1169GVMMR0DECL(int) GVMMR0DestroyVM(PGVM pGVM, PVM pVM)
     1170{
     1171    LogFlow(("GVMMR0DestroyVM: pGVM=%p pVM=%p\n", pGVM, pVM));
    11481172    PGVMM pGVMM;
    11491173    GVMM_GET_VALID_INSTANCE(pGVMM, VERR_GVMM_INSTANCE);
     
    11521176     * Validate the VM structure, state and caller.
    11531177     */
     1178    AssertPtrReturn(pGVM, VERR_INVALID_POINTER);
    11541179    AssertPtrReturn(pVM, VERR_INVALID_POINTER);
    11551180    AssertReturn(!((uintptr_t)pVM & PAGE_OFFSET_MASK), VERR_INVALID_POINTER);
     1181    AssertReturn(pGVM->pVM == pVM, VERR_INVALID_POINTER);
    11561182    AssertMsgReturn(pVM->enmVMState >= VMSTATE_CREATING && pVM->enmVMState <= VMSTATE_TERMINATED, ("%d\n", pVM->enmVMState),
    11571183                    VERR_WRONG_ORDER);
    11581184
    1159     uint32_t hGVM = pVM->hSelf;
     1185    uint32_t hGVM = pGVM->hSelf;
    11601186    AssertReturn(hGVM != NIL_GVM_HANDLE, VERR_INVALID_HANDLE);
    11611187    AssertReturn(hGVM < RT_ELEMENTS(pGVMM->aHandles), VERR_INVALID_HANDLE);
     
    13301356    {
    13311357        pGVMM->cEMTs -= pGVM->cCpus;
     1358
     1359        if (pGVM->pSession)
     1360            SUPR0SetSessionVM(pGVM->pSession, NULL, NULL);
     1361
    13321362        GVMMR0_USED_EXCLUSIVE_UNLOCK(pGVMM);
    13331363
     
    14051435 *
    14061436 * @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 */
     1441GVMMR0DECL(int) GVMMR0RegisterVCpu(PGVM pGVM, PVM pVM, VMCPUID idCpu)
    14111442{
    14121443    AssertReturn(idCpu != 0, VERR_NOT_OWNER);
     
    14151446     * Validate the VM structure, state and handle.
    14161447     */
    1417     PGVM pGVM;
    14181448    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. */
    14311450    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    }
    14331483    return rc;
    14341484}
     
    15451595    *ppGVMM = pGVMM;
    15461596    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 */
     1618static 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;
    15471680}
    15481681
     
    25902723 * @param   pVM             The cross context VM structure. Optional.
    25912724 * @param   pReq            Pointer to the request packet.
    2592  */
    2593 GVMMR0DECL(int) GVMMR0QueryStatisticsReq(PVM pVM, PGVMMQUERYSTATISTICSSREQ pReq)
     2725 * @param   pSession        The current session.
     2726 */
     2727GVMMR0DECL(int) GVMMR0QueryStatisticsReq(PVM pVM, PGVMMQUERYSTATISTICSSREQ pReq, PSUPDRVSESSION pSession)
    25942728{
    25952729    /*
     
    25982732    AssertPtrReturn(pReq, VERR_INVALID_POINTER);
    25992733    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);
    26022737}
    26032738
     
    27052840 * @param   pVM             The cross context VM structure. Optional.
    27062841 * @param   pReq            Pointer to the request packet.
    2707  */
    2708 GVMMR0DECL(int) GVMMR0ResetStatisticsReq(PVM pVM, PGVMMRESETSTATISTICSSREQ pReq)
     2842 * @param   pSession        The current session.
     2843 */
     2844GVMMR0DECL(int) GVMMR0ResetStatisticsReq(PVM pVM, PGVMMRESETSTATISTICSSREQ pReq, PSUPDRVSESSION pSession)
    27092845{
    27102846    /*
     
    27132849    AssertPtrReturn(pReq, VERR_INVALID_POINTER);
    27142850    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  
    3131#include "VMMInternal.h"
    3232#include <VBox/vmm/vm.h>
     33#include <VBox/vmm/gvm.h>
    3334#ifdef VBOX_WITH_PCI_PASSTHROUGH
    3435# include <VBox/vmm/pdmpci.h>
     
    930931 * The Ring 0 entry point, called by the fast-ioctl path.
    931932 *
     933 * @param   pGVM            The global (ring-0) VM structure.
    932934 * @param   pVM             The cross context VM structure.
    933935 *                          The return code is stored in pVM->vmm.s.iLastGZRc.
     
    936938 * @remarks Assume called with interrupts _enabled_.
    937939 */
    938 VMMR0DECL(void) VMMR0EntryFast(PVM pVM, VMCPUID idCpu, VMMR0OPERATION enmOperation)
     940VMMR0DECL(void) VMMR0EntryFast(PGVM pGVM, PVM pVM, VMCPUID idCpu, VMMR0OPERATION enmOperation)
    939941{
    940942    /*
    941943     * Validation.
    942944     */
    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);
    944951        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);
    947964        return;
     965    }
     966
     967    /*
     968     * SMAP fun.
     969     */
    948970    VMM_CHECK_SMAP_SETUP();
    949971    VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING);
     
    13141336 *
    13151337 * @returns VBox status code.
     1338 * @param   pGVM            The global (ring-0) VM structure.
    13161339 * @param   pVM             The cross context VM structure.
    13171340 * @param   idCpu           Virtual CPU ID argument. Must be NIL_VMCPUID if pVM
     
    13221345 * @param   u64Arg          Some simple constant argument.
    13231346 * @param   pSession        The session of the caller.
     1347 *
    13241348 * @remarks Assume called with interrupts _enabled_.
    13251349 */
    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)
     1350static 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)
    13321358    {
    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
    13351364        {
    1336             SUPR0Printf("vmmR0EntryExWorker: Invalid pVM=%p! (op=%d)\n", pVM, enmOperation);
     1365            SUPR0Printf("vmmR0EntryExWorker: Invalid pGVM=%p and/or pVM=%p! (op=%d)\n", pGVM, pVM, enmOperation);
    13371366            return VERR_INVALID_POINTER;
    13381367        }
    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
    13421372        {
    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);
    13451395            return VERR_INVALID_POINTER;
    13461396        }
    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         }
    13531397    }
    1354     else if (RT_UNLIKELY(idCpu != NIL_VMCPUID))
     1398    else if (RT_LIKELY(idCpu == NIL_VMCPUID))
     1399    { /* likely */ }
     1400    else
    13551401    {
    13561402        SUPR0Printf("vmmR0EntryExWorker: Invalid idCpu=%u\n", idCpu);
    13571403        return VERR_INVALID_PARAMETER;
    13581404    }
     1405
     1406    /*
     1407     * SMAP fun.
     1408     */
    13591409    VMM_CHECK_SMAP_SETUP();
    13601410    VMM_CHECK_SMAP_CHECK(RT_NOTHING);
     1411
     1412    /*
     1413     * Process the request.
     1414     */
    13611415    int rc;
    1362 
    13631416    switch (enmOperation)
    13641417    {
     
    13671420         */
    13681421        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;
    13721426            VMM_CHECK_SMAP_CHECK(RT_NOTHING);
    13731427            break;
    13741428
    13751429        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;
    13791434            VMM_CHECK_SMAP_CHECK(RT_NOTHING);
    13801435            break;
    13811436
    13821437        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;
    13901444
    13911445        case VMMR0_DO_GVMM_SCHED_HALT:
     
    14291483            if (u64Arg)
    14301484                return VERR_INVALID_PARAMETER;
    1431             rc = GVMMR0QueryStatisticsReq(pVM, (PGVMMQUERYSTATISTICSSREQ)pReqHdr);
     1485            rc = GVMMR0QueryStatisticsReq(pVM, (PGVMMQUERYSTATISTICSSREQ)pReqHdr, pSession);
    14321486            VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING);
    14331487            break;
     
    14361490            if (u64Arg)
    14371491                return VERR_INVALID_PARAMETER;
    1438             rc = GVMMR0ResetStatisticsReq(pVM, (PGVMMRESETSTATISTICSSREQ)pReqHdr);
     1492            rc = GVMMR0ResetStatisticsReq(pVM, (PGVMMRESETSTATISTICSSREQ)pReqHdr, pSession);
    14391493            VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING);
    14401494            break;
     
    19231977typedef struct VMMR0ENTRYEXARGS
    19241978{
     1979    PGVM                pGVM;
    19251980    PVM                 pVM;
    19261981    VMCPUID             idCpu;
     
    19411996static DECLCALLBACK(int) vmmR0EntryExWrapper(void *pvArgs)
    19421997{
    1943     return vmmR0EntryExWorker(((PVMMR0ENTRYEXARGS)pvArgs)->pVM,
     1998    return vmmR0EntryExWorker(((PVMMR0ENTRYEXARGS)pvArgs)->pGVM,
     1999                              ((PVMMR0ENTRYEXARGS)pvArgs)->pVM,
    19442000                              ((PVMMR0ENTRYEXARGS)pvArgs)->idCpu,
    19452001                              ((PVMMR0ENTRYEXARGS)pvArgs)->enmOperation,
     
    19632019 * @remarks Assume called with interrupts _enabled_.
    19642020 */
    1965 VMMR0DECL(int) VMMR0EntryEx(PVM pVM, VMCPUID idCpu, VMMR0OPERATION enmOperation, PSUPVMMR0REQHDR pReq, uint64_t u64Arg, PSUPDRVSESSION pSession)
     2021VMMR0DECL(int) VMMR0EntryEx(PGVM pGVM, PVM pVM, VMCPUID idCpu, VMMR0OPERATION enmOperation,
     2022                            PSUPVMMR0REQHDR pReq, uint64_t u64Arg, PSUPDRVSESSION pSession)
    19662023{
    19672024    /*
     
    19692026     * wrapped in a setjmp so we can assert without causing trouble.
    19702027     */
    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)
    19742032    {
    19752033        switch (enmOperation)
     
    19852043            case VMMR0_DO_VMMR0_TERM:
    19862044            {
    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;
    20012066            }
    20022067
     
    20052070        }
    20062071    }
    2007     return vmmR0EntryExWorker(pVM, idCpu, enmOperation, pReq, u64Arg, pSession);
     2072    return vmmR0EntryExWorker(pGVM, pVM, idCpu, enmOperation, pReq, u64Arg, pSession);
    20082073}
    20092074
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette