VirtualBox

Changeset 67955 in vbox


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
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/sup.h

    r67821 r67955  
    18881888SUPR0DECL(int) SUPR0ObjVerifyAccess(void *pvObj, PSUPDRVSESSION pSession, const char *pszObjName);
    18891889
     1890SUPR0DECL(PVM) SUPR0GetSessionVM(PSUPDRVSESSION pSession);
     1891SUPR0DECL(PGVM) SUPR0GetSessionGVM(PSUPDRVSESSION pSession);
     1892SUPR0DECL(int) SUPR0SetSessionVM(PSUPDRVSESSION pSession, PGVM pGVM, PVM pVM);
     1893
    18901894SUPR0DECL(int) SUPR0LockMem(PSUPDRVSESSION pSession, RTR3PTR pvR3, uint32_t cPages, PRTHCPHYS paPages);
    18911895SUPR0DECL(int) SUPR0UnlockMem(PSUPDRVSESSION pSession, RTR3PTR pvR3);
  • trunk/include/VBox/vmm/gvm.h

    r62476 r67955  
    8282    /** The ring-0 mapping of the VM structure. */
    8383    PVM             pVM;
     84    /** The support driver session the VM is associated with. */
     85    PSUPDRVSESSION  pSession;
    8486    /** Number of Virtual CPUs, i.e. how many entries there are in aCpus.
    8587     * Same same as VM::cCpus. */
  • trunk/include/VBox/vmm/gvmm.h

    r62476 r67955  
    163163GVMMR0DECL(void)    GVMMR0DoneInitVM(PVM pVM);
    164164GVMMR0DECL(bool)    GVMMR0DoingTermVM(PVM pVM, PGVM pGVM);
    165 GVMMR0DECL(int)     GVMMR0DestroyVM(PVM pVM);
    166 GVMMR0DECL(int)     GVMMR0RegisterVCpu(PVM pVM, VMCPUID idCpu);
     165GVMMR0DECL(int)     GVMMR0DestroyVM(PGVM pGVM, PVM pVM);
     166GVMMR0DECL(int)     GVMMR0RegisterVCpu(PGVM pGVM, PVM pVM, VMCPUID idCpu);
    167167GVMMR0DECL(PGVM)    GVMMR0ByHandle(uint32_t hGVM);
    168168GVMMR0DECL(int)     GVMMR0ByVM(PVM pVM, PGVM *ppGVM);
     
    201201typedef GVMMCREATEVMREQ *PGVMMCREATEVMREQ;
    202202
    203 GVMMR0DECL(int)     GVMMR0CreateVMReq(PGVMMCREATEVMREQ pReq);
     203GVMMR0DECL(int)     GVMMR0CreateVMReq(PGVMMCREATEVMREQ pReq, PSUPDRVSESSION pSession);
    204204
    205205
     
    239239typedef GVMMQUERYSTATISTICSSREQ *PGVMMQUERYSTATISTICSSREQ;
    240240
    241 GVMMR0DECL(int)     GVMMR0QueryStatisticsReq(PVM pVM, PGVMMQUERYSTATISTICSSREQ pReq);
     241GVMMR0DECL(int)     GVMMR0QueryStatisticsReq(PVM pVM, PGVMMQUERYSTATISTICSSREQ pReq, PSUPDRVSESSION pSession);
    242242
    243243
     
    259259typedef GVMMRESETSTATISTICSSREQ *PGVMMRESETSTATISTICSSREQ;
    260260
    261 GVMMR0DECL(int)     GVMMR0ResetStatisticsReq(PVM pVM, PGVMMRESETSTATISTICSSREQ pReq);
     261GVMMR0DECL(int)     GVMMR0ResetStatisticsReq(PVM pVM, PGVMMRESETSTATISTICSSREQ pReq, PSUPDRVSESSION pSession);
    262262
    263263
  • trunk/include/VBox/vmm/vmm.h

    r62476 r67955  
    516516
    517517#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);
     518VMMR0DECL(void)      VMMR0EntryFast(PGVM pGVM, PVM pVM, VMCPUID idCpu, VMMR0OPERATION enmOperation);
     519VMMR0DECL(int)       VMMR0EntryEx(PGVM pGVM, PVM pVM, VMCPUID idCpu, VMMR0OPERATION enmOperation,
     520                                  PSUPVMMR0REQHDR pReq, uint64_t u64Arg, PSUPDRVSESSION);
    521521VMMR0_INT_DECL(int)  VMMR0TermVM(PVM pVM, PGVM pGVM);
    522522VMMR0_INT_DECL(bool) VMMR0IsLongJumpArmed(PVMCPU pVCpu);
  • trunk/src/VBox/HostDrivers/Support/SUPDrv.cpp

    r67823 r67955  
    218218    { "SUPR0PageFree",                          (void *)(uintptr_t)SUPR0PageFree },
    219219    { "SUPR0Printf",                            (void *)(uintptr_t)SUPR0Printf },
     220    { "SUPR0GetSessionGVM",                     (void *)(uintptr_t)SUPR0GetSessionGVM },
     221    { "SUPR0GetSessionVM",                      (void *)(uintptr_t)SUPR0GetSessionVM },
     222    { "SUPR0SetSessionVM",                      (void *)(uintptr_t)SUPR0SetSessionVM },
    220223    { "SUPR0TscDeltaMeasureBySetIndex",         (void *)(uintptr_t)SUPR0TscDeltaMeasureBySetIndex },
    221224    { "SUPR0TracerDeregisterDrv",               (void *)(uintptr_t)SUPR0TracerDeregisterDrv },
     
    924927
    925928    /*
     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    /*
    926941     * Do tracer cleanups related to this session.
    927942     */
     
    14241439{
    14251440    /*
    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);
    14481481    return VERR_INTERNAL_ERROR;
    14491482}
     
    17811814                /* execute */
    17821815                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                }
    17841826                else
    17851827                    pReq->Hdr.rc = VERR_WRONG_ORDER;
     
    17951837                /* execute */
    17961838                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                }
    17981849                else
    17991850                    pReq->Hdr.rc = VERR_WRONG_ORDER;
     
    18271878            /* execute */
    18281879            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            }
    18301889            else
    18311890                pReq->Hdr.rc = VERR_WRONG_ORDER;
     
    19121971                                     && !((uintptr_t)pReq->u.In.pVMR0 & (PAGE_SIZE - 1))),
    19131972                               ("SUP_IOCTL_SET_VM_FOR_FAST: pVMR0=%p!\n", pReq->u.In.pVMR0));
     1973
    19141974            /* 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            }
    19171999            return 0;
    19182000        }
     
    30133095
    30143096/**
     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 */
     3102SUPR0DECL(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 */
     3115SUPR0DECL(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 */
     3140SUPR0DECL(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/**
    30153174 * Lock pages.
    30163175 *
  • trunk/src/VBox/HostDrivers/Support/SUPDrvIOC.h

    r67821 r67955  
    215215 *          - nothing.
    216216 */
    217 #define SUPDRV_IOC_VERSION                              0x00280002
     217#define SUPDRV_IOC_VERSION                              0x00290000
    218218
    219219/** SUP_IOCTL_COOKIE. */
  • trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h

    r67137 r67955  
    488488    RTR0PROCESS                     R0Process;
    489489
    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;
    492498    /** Handle table for IPRT semaphore wrapper APIs.
    493499     * This takes care of its own locking in an IRQ safe manner. */
     
    588594    void * volatile                 pvVMMR0;
    589595    /** VMMR0EntryFast() pointer. */
    590     DECLR0CALLBACKMEMBER(void,      pfnVMMR0EntryFast, (PVM pVM, VMCPUID idCpu, unsigned uOperation));
     596    DECLR0CALLBACKMEMBER(void,      pfnVMMR0EntryFast, (PGVM pGVM, PVM pVM, VMCPUID idCpu, uint32_t uOperation));
    591597    /** 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));
    593600
    594601    /** Linked list of loaded code. */
  • trunk/src/VBox/HostDrivers/Support/testcase/tstInt.cpp

    r62490 r67955  
    3232#include <VBox/vmm/vm.h>
    3333#include <VBox/vmm/vmm.h>
     34#include <VBox/vmm/gvmm.h>
    3435#include <VBox/err.h>
    3536#include <VBox/param.h>
     
    8081        {
    8182            /*
    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.
    8384             */
    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             else
    91                 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);
    9293            if (RT_SUCCESS(rc))
    9394            {
    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));
    99101                pVM->enmVMState = VMSTATE_CREATED;
    100 
    101                 rc = SUPR3SetVMForFastIOCtl(pVMR0);
     102                PVMR0 const pVMR0 = pVM->pVMR0;
     103
     104                rc = SUPR3SetVMForFastIOCtl(pVM->pVMR0);
    102105                if (!rc)
    103106                {
    104 
    105107                    /*
    106108                     * Call VMM code with invalid function.
     
    182184                    rcRet++;
    183185                }
     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                }
    184193            }
    185194            else
    186195            {
    187                 RTPrintf("tstInt: SUPR3ContAlloc(%#zx,,) failed\n", sizeof(*pVM));
     196                RTPrintf("tstInt: VMMR0_DO_GVMM_CREATE_VM failed\n");
    188197                rcRet++;
    189198            }
  • 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.

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