VirtualBox

Changeset 14332 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Nov 18, 2008 10:11:06 PM (16 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
39535
Message:

SUPDrv,SUPLib: generic ring-0 service interface.

Location:
trunk/src/VBox/HostDrivers/Support
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/Support/SUPDrv.c

    r13871 r14332  
    141141static int      supdrvLdrAddUsage(PSUPDRVSESSION pSession, PSUPDRVLDRIMAGE pImage);
    142142static void     supdrvLdrFree(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage);
     143static int      supdrvIOCtl_CallServiceModule(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, PSUPCALLSERVICE pReq);
    143144static SUPPAGINGMODE supdrvIOCtl_GetPagingMode(void);
    144145static SUPGIPMODE supdrvGipDeterminTscMode(PSUPDRVDEVEXT pDevExt);
     
    160161DECLASM(int)    supdrvNtWrapModuleInit(PFNRT pfnModuleInit);
    161162DECLASM(void)   supdrvNtWrapModuleTerm(PFNRT pfnModuleTerm);
     163DECLASM(int)    supdrvNtWrapServiceReqHandler(PFNRT pfnServiceReqHandler, PSUPDRVSESSION pSession, uint32_t uOperation, uint64_t u64Arg, PSUPR0SERVICEREQHDR pReqHdr);
    162164
    163165DECLASM(int)    UNWIND_WRAP(SUPR0ComponentRegisterFactory)(PSUPDRVSESSION pSession, PCSUPDRVFACTORY pFactory);
     
    14171419        }
    14181420
     1421        case SUP_CTL_CODE_NO_SIZE(SUP_IOCTL_CALL_SERVICE(0)):
     1422        {
     1423            /* validate */
     1424            PSUPCALLSERVICE pReq = (PSUPCALLSERVICE)pReqHdr;
     1425            Log4(("SUP_IOCTL_CALL_SERVICE: op=%u in=%u arg=%RX64 p/t=%RTproc/%RTthrd\n",
     1426                  pReq->u.In.uOperation, pReq->Hdr.cbIn, pReq->u.In.u64Arg, RTProcSelf(), RTThreadNativeSelf()));
     1427
     1428            if (pReq->Hdr.cbIn == SUP_IOCTL_CALL_SERVICE_SIZE(0))
     1429                REQ_CHECK_SIZES_EX(SUP_IOCTL_CALL_SERVICE, SUP_IOCTL_CALL_SERVICE_SIZE_IN(0), SUP_IOCTL_CALL_SERVICE_SIZE_OUT(0));
     1430            else
     1431            {
     1432                PSUPR0SERVICEREQHDR pSrvReq = (PSUPR0SERVICEREQHDR)&pReq->abReqPkt[0];
     1433                REQ_CHECK_EXPR_FMT(pReq->Hdr.cbIn >= SUP_IOCTL_CALL_SERVICE_SIZE(sizeof(SUPR0SERVICEREQHDR)),
     1434                                   ("SUP_IOCTL_CALL_SERVICE: cbIn=%#x < %#lx\n", pReq->Hdr.cbIn, SUP_IOCTL_CALL_SERVICE_SIZE(sizeof(SUPR0SERVICEREQHDR))));
     1435                REQ_CHECK_EXPR(SUP_IOCTL_CALL_SERVICE, pSrvReq->u32Magic == SUPR0SERVICEREQHDR_MAGIC);
     1436                REQ_CHECK_SIZES_EX(SUP_IOCTL_CALL_SERVICE, SUP_IOCTL_CALL_SERVICE_SIZE_IN(pSrvReq->cbReq), SUP_IOCTL_CALL_SERVICE_SIZE_OUT(pSrvReq->cbReq));
     1437            }
     1438            REQ_CHECK_EXPR(SUP_IOCTL_CALL_SERVICE, memchr(pReq->u.In.szName, '\0', sizeof(pReq->u.In.szName)));
     1439
     1440            /* execute */
     1441            pReq->Hdr.rc = supdrvIOCtl_CallServiceModule(pDevExt, pSession, pReq);
     1442            return 0;
     1443        }
     1444
    14191445        default:
    14201446            Log(("Unknown IOCTL %#lx\n", (long)uIOCtl));
     
    37133739    pImage->pfnModuleInit   = NULL;
    37143740    pImage->pfnModuleTerm   = NULL;
     3741    pImage->pfnServiceReqHandler = NULL;
    37153742    pImage->uState          = SUP_IOCTL_LDR_OPEN;
    37163743    pImage->cUsage          = 1;
     
    37823809        case SUPLDRLOADEP_NOTHING:
    37833810            break;
     3811
    37843812        case SUPLDRLOADEP_VMMR0:
    37853813            if (    !pReq->u.In.EP.VMMR0.pvVMMR0
     
    38063834            }
    38073835            break;
     3836
     3837        case SUPLDRLOADEP_SERVICE:
     3838            if (!pReq->u.In.EP.Service.pfnServiceReq)
     3839            {
     3840                RTSemFastMutexRelease(pDevExt->mtxLdr);
     3841                Log(("NULL pointer: pfnServiceReq=%p!\n", pReq->u.In.EP.Service.pfnServiceReq));
     3842                return VERR_INVALID_PARAMETER;
     3843            }
     3844            if ((uintptr_t)pReq->u.In.EP.Service.pfnServiceReq  - (uintptr_t)pImage->pvImage >= pReq->u.In.cbImage)
     3845            {
     3846                RTSemFastMutexRelease(pDevExt->mtxLdr);
     3847                Log(("Out of range (%p LB %#x): pfnServiceReq=%p, pvVMMR0EntryFast=%p or pvVMMR0EntryEx=%p is NULL!\n",
     3848                     pImage->pvImage, pReq->u.In.cbImage, pReq->u.In.EP.Service.pfnServiceReq));
     3849                return VERR_INVALID_PARAMETER;
     3850            }
     3851            if (    pReq->u.In.EP.Service.apvReserved[0] != NIL_RTR0PTR
     3852                ||  pReq->u.In.EP.Service.apvReserved[1] != NIL_RTR0PTR
     3853                ||  pReq->u.In.EP.Service.apvReserved[2] != NIL_RTR0PTR)
     3854            {
     3855                RTSemFastMutexRelease(pDevExt->mtxLdr);
     3856                Log(("Out of range (%p LB %#x): apvReserved={%p,%p,%p} MBZ!\n",
     3857                     pImage->pvImage, pReq->u.In.cbImage,
     3858                     pReq->u.In.EP.Service.apvReserved[0],
     3859                     pReq->u.In.EP.Service.apvReserved[1],
     3860                     pReq->u.In.EP.Service.apvReserved[2]));
     3861                return VERR_INVALID_PARAMETER;
     3862            }
     3863            break;
     3864
    38083865        default:
    38093866            RTSemFastMutexRelease(pDevExt->mtxLdr);
     
    38533910            rc = supdrvLdrSetR0EP(pDevExt, pReq->u.In.EP.VMMR0.pvVMMR0, pReq->u.In.EP.VMMR0.pvVMMR0EntryInt,
    38543911                                  pReq->u.In.EP.VMMR0.pvVMMR0EntryFast, pReq->u.In.EP.VMMR0.pvVMMR0EntryEx);
     3912            break;
     3913        case SUPLDRLOADEP_SERVICE:
     3914            pImage->pfnServiceReqHandler = pReq->u.In.EP.Service.pfnServiceReq;
     3915            rc = VINF_SUCCESS;
    38553916            break;
    38563917    }
     
    43494410    pImage->uState = SUP_IOCTL_LDR_FREE;
    43504411    RTMemExecFree(pImage);
     4412}
     4413
     4414
     4415/**
     4416 * Implements the service call request.
     4417 *
     4418 * @returns VBox status code.
     4419 * @param   pDevExt         The device extension.
     4420 * @param   pSession        The calling session.
     4421 * @param   pReq            The request packet, valid.
     4422 */
     4423static int supdrvIOCtl_CallServiceModule(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, PSUPCALLSERVICE pReq)
     4424{
     4425#if !defined(RT_OS_WINDOWS) || defined(DEBUG)
     4426    int rc;
     4427
     4428    /*
     4429     * Find the module first in the module referenced by the calling session.
     4430     */
     4431    rc = RTSemFastMutexRequest(pDevExt->mtxLdr);
     4432    if (RT_SUCCESS(rc))
     4433    {
     4434        PFNSUPR0SERVICEREQHANDLER   pfnServiceReqHandler = NULL;
     4435        PSUPDRVLDRUSAGE             pUsage;
     4436
     4437        for (pUsage = pSession->pLdrUsage; pUsage; pUsage = pUsage->pNext)
     4438            if (    pUsage->pImage->pfnServiceReqHandler
     4439                &&  !strcmp(pUsage->pImage->szName, pReq->u.In.szName))
     4440            {
     4441                pfnServiceReqHandler = pUsage->pImage->pfnServiceReqHandler;
     4442                break;
     4443            }
     4444        RTSemFastMutexRelease(pDevExt->mtxLdr);
     4445
     4446        if (pfnServiceReqHandler)
     4447        {
     4448            /*
     4449             * Call it.
     4450             */
     4451            if (pReq->Hdr.cbIn == SUP_IOCTL_CALL_SERVICE_SIZE(0))
     4452#ifdef RT_WITH_W64_UNWIND_HACK
     4453                rc = supdrvNtWrapServiceReqHandler((PRNRT)pfnServiceReqHandler, pSession, pReq->u.In.uOperation, pReq->u.In.u64Arg, NULL);
     4454#else
     4455                rc = pfnServiceReqHandler(pSession, pReq->u.In.uOperation, pReq->u.In.u64Arg, NULL);
     4456#endif
     4457            else
     4458#ifdef RT_WITH_W64_UNWIND_HACK
     4459                rc = supdrvNtWrapServiceReqHandler((PRNRT)pfnServiceReqHandler, pSession, pReq->u.In.uOperation,
     4460                                                   pReq->u.In.u64Arg, (PSUPR0SERVICEREQHDR)&pReq->abReqPkt[0]);
     4461#else
     4462                rc = pfnServiceReqHandler(pSession, pReq->u.In.uOperation, pReq->u.In.u64Arg, (PSUPR0SERVICEREQHDR)&pReq->abReqPkt[0]);
     4463#endif
     4464        }
     4465        else
     4466            rc = VERR_SUPDRV_SERVICE_NOT_FOUND;
     4467    }
     4468
     4469    /* log it */
     4470    if (    RT_FAILURE(rc)
     4471        &&  rc != VERR_INTERRUPTED
     4472        &&  rc != VERR_TIMEOUT)
     4473        Log(("SUP_IOCTL_CALL_SERVICE: rc=%Rrc op=%u out=%u arg=%RX64 p/t=%RTproc/%RTthrd\n",
     4474             rc, pReq->u.In.uOperation, pReq->Hdr.cbOut, pReq->u.In.u64Arg, RTProcSelf(), RTThreadNativeSelf()));
     4475    else
     4476        Log4(("SUP_IOCTL_CALL_SERVICE: rc=%Rrc op=%u out=%u arg=%RX64 p/t=%RTproc/%RTthrd\n",
     4477              rc, pReq->u.In.uOperation, pReq->Hdr.cbOut, pReq->u.In.u64Arg, RTProcSelf(), RTThreadNativeSelf()));
     4478    return rc;
     4479#else  /* RT_OS_WINDOWS && !DEBUG */
     4480    return VERR_NOT_IMPLEMENTED;
     4481#endif /* RT_OS_WINDOWS && !DEBUG */
    43514482}
    43524483
  • trunk/src/VBox/HostDrivers/Support/SUPDrvIOC.h

    r13858 r14332  
    182182 * The upper 16-bit is the major version, the the lower the minor version.
    183183 * When incompatible changes are made, the upper major number has to be changed. */
    184 #define SUPDRV_IOC_VERSION                              0x000A0000
     184#define SUPDRV_IOC_VERSION                              0x000a0001
    185185
    186186/** SUP_IOCTL_COOKIE. */
     
    383383    SUPLDRLOADEP_NOTHING = 0,
    384384    SUPLDRLOADEP_VMMR0,
     385    SUPLDRLOADEP_SERVICE,
    385386    SUPLDRLOADEP_32BIT_HACK = 0x7fffffff
    386387} SUPLDRLOADEP;
     
    401402            union
    402403            {
     404                /** SUPLDRLOADEP_VMMR0. */
    403405                struct
    404406                {
    405407                    /** The module handle (i.e. address). */
    406                     RTR0PTR         pvVMMR0;
     408                    RTR0PTR                 pvVMMR0;
    407409                    /** Address of VMMR0EntryInt function. */
    408                     RTR0PTR         pvVMMR0EntryInt;
     410                    RTR0PTR                 pvVMMR0EntryInt;
    409411                    /** Address of VMMR0EntryFast function. */
    410                     RTR0PTR         pvVMMR0EntryFast;
     412                    RTR0PTR                 pvVMMR0EntryFast;
    411413                    /** Address of VMMR0EntryEx function. */
    412                     RTR0PTR         pvVMMR0EntryEx;
     414                    RTR0PTR                 pvVMMR0EntryEx;
    413415                } VMMR0;
     416                /** SUPLDRLOADEP_SERVICE. */
     417                struct
     418                {
     419                    /** The service request handler.
     420                     * (PFNR0SERVICEREQHANDLER isn't defined yet.) */
     421                    RTR0PTR                 pfnServiceReq;
     422                    /** Reserved, must be NIL. */
     423                    RTR0PTR                 apvReserved[3];
     424                } Service;
    414425            }               EP;
    415426            /** Address. */
     
    844855
    845856
     857/** @name SUP_IOCTL_CALL_SERVICE
     858 * Call the a ring-0 service.
     859 *
     860 * @todo    Might have to convert this to a big request, just like
     861 *          SUP_IOCTL_CALL_VMMR0
     862 * @{
     863 */
     864#define SUP_IOCTL_CALL_SERVICE(cbReq)                   SUP_CTL_CODE_SIZE(22, SUP_IOCTL_CALL_SERVICE_SIZE(cbReq))
     865#define SUP_IOCTL_CALL_SERVICE_SIZE(cbReq)              RT_UOFFSETOF(SUPCALLSERVICE, abReqPkt[cbReq])
     866#define SUP_IOCTL_CALL_SERVICE_SIZE_IN(cbReq)           SUP_IOCTL_CALL_SERVICE_SIZE(cbReq)
     867#define SUP_IOCTL_CALL_SERVICE_SIZE_OUT(cbReq)          SUP_IOCTL_CALL_SERVICE_SIZE(cbReq)
     868typedef struct SUPCALLSERVICE
     869{
     870    /** The header. */
     871    SUPREQHDR               Hdr;
     872    union
     873    {
     874        struct
     875        {
     876            /** The service name. */
     877            char            szName[28];
     878            /** Which operation to execute. */
     879            uint32_t        uOperation;
     880            /** Argument to use when no request packet is supplied. */
     881            uint64_t        u64Arg;
     882        } In;
     883    } u;
     884    /** The request packet passed to SUP. */
     885    uint8_t                 abReqPkt[1];
     886} SUPCALLSERVICE, *PSUPCALLSERVICE;
     887/** @} */
     888
     889
    846890#pragma pack()                          /* paranoia */
    847891
  • trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h

    r13871 r14332  
    347347#define SUPDRV_PATCH_CODE_SIZE  0x50
    348348    /** Patch code. */
    349     uint8_t                 auCode[SUPDRV_PATCH_CODE_SIZE];
     349    uint8_t                         auCode[SUPDRV_PATCH_CODE_SIZE];
    350350    /** Changed IDT entry (for parnoid UnpatchIdt()). */
    351     SUPDRVIDTE              ChangedIdt;
     351    SUPDRVIDTE                      ChangedIdt;
    352352    /** Saved IDT entry. */
    353     SUPDRVIDTE              SavedIdt;
     353    SUPDRVIDTE                      SavedIdt;
    354354    /** Pointer to the IDT.
    355355     * We ASSUME the IDT is not re(al)located after bootup and use this as key
     
    360360     * the(se) page(s), but we'll find that out soon enough in VBOX_STRICT mode.
    361361     */
    362     void                   *pvIdt;
     362    void                           *pvIdt;
    363363    /** Pointer to the IDT entry. */
    364     SUPDRVIDTE volatile    *pIdtEntry;
     364    SUPDRVIDTE volatile            *pIdtEntry;
    365365    /** Usage counter. */
    366     uint32_t volatile       cUsage;
     366    uint32_t volatile               cUsage;
    367367    /** The offset into auCode of the VMMR0Entry fixup. */
    368     uint16_t                offVMMR0EntryFixup;
     368    uint16_t                        offVMMR0EntryFixup;
    369369    /** The offset into auCode of the stub function. */
    370     uint16_t                offStub;
     370    uint16_t                        offStub;
    371371    /** Pointer to the next patch. */
    372372    struct SUPDRVPATCH * volatile pNext;
     
    381381    struct SUPDRVPATCHUSAGE * volatile pNext;
    382382    /** The patch this usage applies to. */
    383     PSUPDRVPATCH        pPatch;
     383    PSUPDRVPATCH                    pPatch;
    384384    /** Usage count. */
    385     uint32_t volatile   cUsage;
     385    uint32_t volatile               cUsage;
    386386} SUPDRVPATCHUSAGE, *PSUPDRVPATCHUSAGE;
    387387
     
    418418{
    419419    /** The memory object handle. */
    420     RTR0MEMOBJ          MemObj;
     420    RTR0MEMOBJ                      MemObj;
    421421    /** The ring-3 mapping memory object handle. */
    422     RTR0MEMOBJ          MapObjR3;
     422    RTR0MEMOBJ                      MapObjR3;
    423423    /** Type of memory. */
    424     SUPDRVMEMREFTYPE    eType;
     424    SUPDRVMEMREFTYPE                eType;
    425425} SUPDRVMEMREF, *PSUPDRVMEMREF;
    426426
     
    432432{
    433433    /** Pointer to the next bundle. */
    434     struct SUPDRVBUNDLE * volatile pNext;
     434    struct SUPDRVBUNDLE * volatile  pNext;
    435435    /** Referenced memory. */
    436     SUPDRVMEMREF        aMem[64];
     436    SUPDRVMEMREF                    aMem[64];
    437437    /** Number of entries used. */
    438438    uint32_t volatile   cUsed;
     
    448448    struct SUPDRVLDRIMAGE * volatile pNext;
    449449    /** Pointer to the image. */
    450     void               *pvImage;
     450    void                           *pvImage;
    451451    /** Pointer to the optional module initialization callback. */
    452     PFNR0MODULEINIT     pfnModuleInit;
     452    PFNR0MODULEINIT                 pfnModuleInit;
    453453    /** Pointer to the optional module termination callback. */
    454     PFNR0MODULETERM     pfnModuleTerm;
     454    PFNR0MODULETERM                 pfnModuleTerm;
     455    /** Service request handler. This is NULL for non-service modules. */
     456    PFNSUPR0SERVICEREQHANDLER       pfnServiceReqHandler;
    455457    /** Size of the image. */
    456     uint32_t            cbImage;
     458    uint32_t                        cbImage;
    457459    /** The offset of the symbol table. */
    458     uint32_t            offSymbols;
     460    uint32_t                        offSymbols;
    459461    /** The number of entries in the symbol table. */
    460     uint32_t            cSymbols;
     462    uint32_t                        cSymbols;
    461463    /** The offset of the string table. */
    462     uint32_t            offStrTab;
     464    uint32_t                        offStrTab;
    463465    /** Size of the string table. */
    464     uint32_t            cbStrTab;
     466    uint32_t                        cbStrTab;
    465467    /** The ldr image state. (IOCtl code of last opration.) */
    466     uint32_t            uState;
     468    uint32_t                        uState;
    467469    /** Usage count. */
    468     uint32_t volatile   cUsage;
     470    uint32_t volatile               cUsage;
    469471    /** Image name. */
    470     char                szName[32];
     472    char                            szName[32];
    471473} SUPDRVLDRIMAGE, *PSUPDRVLDRIMAGE;
    472474
     
    478480    struct SUPDRVLDRUSAGE * volatile pNext;
    479481    /** The image. */
    480     PSUPDRVLDRIMAGE     pImage;
     482    PSUPDRVLDRIMAGE                 pImage;
    481483    /** Load count. */
    482     uint32_t volatile   cUsage;
     484    uint32_t volatile               cUsage;
    483485} SUPDRVLDRUSAGE, *PSUPDRVLDRUSAGE;
    484486
     
    490492{
    491493    /** Pointer to the next registration. */
    492     struct SUPDRVFACTORYREG    *pNext;
     494    struct SUPDRVFACTORYREG        *pNext;
    493495    /** Pointer to the registered factory. */
    494     PCSUPDRVFACTORY             pFactory;
     496    PCSUPDRVFACTORY                 pFactory;
    495497    /** The session owning the factory.
    496498     * Used for deregistration and session cleanup. */
    497     PSUPDRVSESSION              pSession;
     499    PSUPDRVSESSION                  pSession;
    498500    /** Length of the name. */
    499     size_t                      cchName;
     501    size_t                          cchName;
    500502} SUPDRVFACTORYREG;
    501503/** Pointer to a component factory registration record. */
     
    558560{
    559561    /** Pointer to the device extension. */
    560     PSUPDRVDEVEXT               pDevExt;
     562    PSUPDRVDEVEXT                   pDevExt;
    561563    /** Session Cookie. */
    562     uint32_t                    u32Cookie;
     564    uint32_t                        u32Cookie;
    563565
    564566    /** Load usage records. (protected by SUPDRVDEVEXT::mtxLdr) */
    565     PSUPDRVLDRUSAGE volatile    pLdrUsage;
     567    PSUPDRVLDRUSAGE volatile        pLdrUsage;
    566568#ifdef VBOX_WITH_IDT_PATCHING
    567569    /** Patch usage records. (protected by SUPDRVDEVEXT::SpinLock) */
    568     PSUPDRVPATCHUSAGE volatile  pPatchUsage;
     570    PSUPDRVPATCHUSAGE volatile      pPatchUsage;
    569571#endif
    570572    /** The VM associated with the session. */
    571     PVM                         pVM;
     573    PVM                             pVM;
    572574    /** List of generic usage records. (protected by SUPDRVDEVEXT::SpinLock) */
    573     PSUPDRVUSAGE volatile       pUsage;
     575    PSUPDRVUSAGE volatile           pUsage;
    574576
    575577    /** Spinlock protecting the bundles and the GIP members. */
    576     RTSPINLOCK                  Spinlock;
     578    RTSPINLOCK                      Spinlock;
    577579    /** The ring-3 mapping of the GIP (readonly). */
    578     RTR0MEMOBJ                  GipMapObjR3;
     580    RTR0MEMOBJ                      GipMapObjR3;
    579581    /** Set if the session is using the GIP. */
    580     uint32_t                    fGipReferenced;
     582    uint32_t                        fGipReferenced;
    581583    /** Bundle of locked memory objects. */
    582     SUPDRVBUNDLE                Bundle;
     584    SUPDRVBUNDLE                    Bundle;
    583585
    584586    /** The user id of the session. (Set by the OS part.) */
    585     RTUID                       Uid;
     587    RTUID                           Uid;
    586588    /** The group id of the session. (Set by the OS part.) */
    587     RTGID                       Gid;
     589    RTGID                           Gid;
    588590    /** The process (id) of the session. */
    589     RTPROCESS                   Process;
     591    RTPROCESS                       Process;
    590592    /** Which process this session is associated with.
    591593     * This is NIL_RTR0PROCESS for kernel sessions and valid for user ones. */
    592     RTR0PROCESS                 R0Process;
     594    RTR0PROCESS                     R0Process;
    593595#if defined(RT_OS_DARWIN)
    594596    /** Pointer to the associated org_virtualbox_SupDrvClient object. */
    595     void                       *pvSupDrvClient;
     597    void                           *pvSupDrvClient;
    596598    /** Whether this session has been opened or not. */
    597     bool                        fOpened;
     599    bool                            fOpened;
    598600#endif
    599601#if defined(RT_OS_OS2)
    600602    /** The system file number of this session. */
    601     uint16_t                    sfn;
    602     uint16_t                    Alignment; /**< Alignment */
     603    uint16_t                        sfn;
     604    uint16_t                        Alignment; /**< Alignment */
    603605#endif
    604606#if defined(RT_OS_DARWIN) || defined(RT_OS_OS2) || defined(RT_OS_SOLARIS)
    605607    /** Pointer to the next session with the same hash. */
    606     PSUPDRVSESSION              pNextHash;
     608    PSUPDRVSESSION                  pNextHash;
    607609#endif
    608610} SUPDRVSESSION;
     
    616618    /** Spinlock to serialize the initialization,
    617619     * usage counting and destruction of the IDT entry override and objects. */
    618     RTSPINLOCK              Spinlock;
     620    RTSPINLOCK                      Spinlock;
    619621
    620622#ifdef VBOX_WITH_IDT_PATCHING
    621623    /** List of patches. */
    622     PSUPDRVPATCH volatile   pIdtPatches;
     624    PSUPDRVPATCH volatile           pIdtPatches;
    623625    /** List of patches Free. */
    624     PSUPDRVPATCH volatile   pIdtPatchesFree;
     626    PSUPDRVPATCH volatile           pIdtPatchesFree;
    625627#endif
    626628
    627629    /** List of registered objects. Protected by the spinlock. */
    628     PSUPDRVOBJ volatile     pObjs;
     630    PSUPDRVOBJ volatile             pObjs;
    629631    /** List of free object usage records. */
    630     PSUPDRVUSAGE volatile   pUsageFree;
     632    PSUPDRVUSAGE volatile           pUsageFree;
    631633
    632634    /** Global cookie. */
    633     uint32_t                u32Cookie;
     635    uint32_t                        u32Cookie;
    634636
    635637    /** The IDT entry number.
    636638     * Only valid if pIdtPatches is set. */
    637     uint8_t volatile        u8Idt;
     639    uint8_t volatile                u8Idt;
    638640
    639641    /** Loader mutex.
    640642     * This protects pvVMMR0, pvVMMR0Entry, pImages and SUPDRVSESSION::pLdrUsage. */
    641     RTSEMFASTMUTEX          mtxLdr;
     643    RTSEMFASTMUTEX                  mtxLdr;
    642644
    643645    /** VMM Module 'handle'.
    644646     * 0 if the code VMM isn't loaded and Idt are nops. */
    645     void * volatile         pvVMMR0;
     647    void * volatile                 pvVMMR0;
    646648    /** VMMR0EntryInt() pointer. */
    647     DECLR0CALLBACKMEMBER(int, pfnVMMR0EntryInt, (PVM pVM, unsigned uOperation, void *pvArg));
     649    DECLR0CALLBACKMEMBER(int,       pfnVMMR0EntryInt, (PVM pVM, unsigned uOperation, void *pvArg));
    648650    /** VMMR0EntryFast() pointer. */
    649     DECLR0CALLBACKMEMBER(void, pfnVMMR0EntryFast, (PVM pVM, unsigned idCpu, unsigned uOperation));
     651    DECLR0CALLBACKMEMBER(void,      pfnVMMR0EntryFast, (PVM pVM, unsigned idCpu, unsigned uOperation));
    650652    /** VMMR0EntryEx() pointer. */
    651     DECLR0CALLBACKMEMBER(int, pfnVMMR0EntryEx, (PVM pVM, unsigned uOperation, PSUPVMMR0REQHDR pReq, uint64_t u64Arg, PSUPDRVSESSION pSession));
     653    DECLR0CALLBACKMEMBER(int,       pfnVMMR0EntryEx, (PVM pVM, unsigned uOperation, PSUPVMMR0REQHDR pReq, uint64_t u64Arg, PSUPDRVSESSION pSession));
    652654
    653655    /** Linked list of loaded code. */
    654     PSUPDRVLDRIMAGE volatile pLdrImages;
     656    PSUPDRVLDRIMAGE volatile        pLdrImages;
    655657
    656658    /** GIP mutex.
    657659     * Any changes to any of the GIP members requires ownership of this mutex,
    658660     * except on driver init and termination. */
    659     RTSEMFASTMUTEX          mtxGip;
     661    RTSEMFASTMUTEX                  mtxGip;
    660662    /** Pointer to the Global Info Page (GIP). */
    661     PSUPGLOBALINFOPAGE      pGip;
     663    PSUPGLOBALINFOPAGE              pGip;
    662664    /** The physical address of the GIP. */
    663     RTHCPHYS                HCPhysGip;
     665    RTHCPHYS                        HCPhysGip;
    664666    /** Number of processes using the GIP.
    665667     * (The updates are suspend while cGipUsers is 0.)*/
    666     uint32_t volatile       cGipUsers;
     668    uint32_t volatile               cGipUsers;
    667669    /** The ring-0 memory object handle for the GIP page. */
    668     RTR0MEMOBJ              GipMemObj;
     670    RTR0MEMOBJ                      GipMemObj;
    669671    /** The GIP timer handle. */
    670     PRTTIMER                pGipTimer;
     672    PRTTIMER                        pGipTimer;
    671673    /** If non-zero we've successfully called RTTimerRequestSystemGranularity(). */
    672     uint32_t                u32SystemTimerGranularityGrant;
     674    uint32_t                        u32SystemTimerGranularityGrant;
    673675    /** The CPU id of the GIP master.
    674676     * This CPU is responsible for the updating the common GIP data. */
    675     RTCPUID volatile        idGipMaster;
     677    RTCPUID volatile                idGipMaster;
    676678
    677679#ifdef RT_OS_WINDOWS
    678680    /* Callback object returned by ExCreateCallback. */
    679     PCALLBACK_OBJECT        pObjPowerCallback;
     681    PCALLBACK_OBJECT                pObjPowerCallback;
    680682    /* Callback handle returned by ExRegisterCallback. */
    681     PVOID                   hPowerCallback;
     683    PVOID                           hPowerCallback;
    682684#endif
    683685
    684686    /** Component factory mutex.
    685687     * This protects pComponentFactoryHead and component factory querying. */
    686     RTSEMFASTMUTEX          mtxComponentFactory;
     688    RTSEMFASTMUTEX                  mtxComponentFactory;
    687689    /** The head of the list of registered component factories. */
    688     PSUPDRVFACTORYREG       pComponentFactoryHead;
     690    PSUPDRVFACTORYREG               pComponentFactoryHead;
    689691} SUPDRVDEVEXT;
    690692
  • trunk/src/VBox/HostDrivers/Support/SUPLib.cpp

    r13871 r14332  
    151151*******************************************************************************/
    152152static int supInitFake(PSUPDRVSESSION *ppSession);
    153 static int supLoadModule(const char *pszFilename, const char *pszModule, void **ppvImageBase);
     153static int supLoadModule(const char *pszFilename, const char *pszModule, const char *pszSrvReqHandler, void **ppvImageBase);
    154154#ifdef VBOX_WITH_IDT_PATCHING
    155155static int supInstallIDTE(void);
     
    679679
    680680
     681SUPR3DECL(int) SUPR3CallR0Service(const char *pszService, size_t cchService, uint32_t uOperation, uint64_t u64Arg, PSUPR0SERVICEREQHDR pReqHdr)
     682{
     683    AssertReturn(cchService < RT_SIZEOFMEMB(SUPCALLSERVICE, u.In.szName), VERR_INVALID_PARAMETER);
     684    Assert(strlen(pszService) == cchService);
     685
     686    /* fake */
     687    if (RT_UNLIKELY(g_u32FakeMode))
     688        return VERR_NOT_SUPPORTED;
     689
     690    int rc;
     691    if (!pReqHdr)
     692    {
     693        /* no data. */
     694        SUPCALLSERVICE Req;
     695        Req.Hdr.u32Cookie = g_u32Cookie;
     696        Req.Hdr.u32SessionCookie = g_u32SessionCookie;
     697        Req.Hdr.cbIn = SUP_IOCTL_CALL_SERVICE_SIZE_IN(0);
     698        Req.Hdr.cbOut = SUP_IOCTL_CALL_SERVICE_SIZE_OUT(0);
     699        Req.Hdr.fFlags = SUPREQHDR_FLAGS_DEFAULT;
     700        Req.Hdr.rc = VERR_INTERNAL_ERROR;
     701        memcpy(Req.u.In.szName, pszService, cchService);
     702        Req.u.In.szName[cchService] = '\0';
     703        Req.u.In.uOperation = uOperation;
     704        Req.u.In.u64Arg = u64Arg;
     705        rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_CALL_SERVICE(0), &Req, SUP_IOCTL_CALL_SERVICE_SIZE(0));
     706        if (RT_SUCCESS(rc))
     707            rc = Req.Hdr.rc;
     708    }
     709    else if (SUP_IOCTL_CALL_SERVICE_SIZE(pReqHdr->cbReq) < _4K) /* FreeBSD won't copy more than 4K. */
     710    {
     711        AssertPtrReturn(pReqHdr, VERR_INVALID_POINTER);
     712        AssertReturn(pReqHdr->u32Magic == SUPR0SERVICEREQHDR_MAGIC, VERR_INVALID_MAGIC);
     713        const size_t cbReq = pReqHdr->cbReq;
     714
     715        PSUPCALLSERVICE pReq = (PSUPCALLSERVICE)alloca(SUP_IOCTL_CALL_SERVICE_SIZE(cbReq));
     716        pReq->Hdr.u32Cookie = g_u32Cookie;
     717        pReq->Hdr.u32SessionCookie = g_u32SessionCookie;
     718        pReq->Hdr.cbIn = SUP_IOCTL_CALL_SERVICE_SIZE_IN(cbReq);
     719        pReq->Hdr.cbOut = SUP_IOCTL_CALL_SERVICE_SIZE_OUT(cbReq);
     720        pReq->Hdr.fFlags = SUPREQHDR_FLAGS_DEFAULT;
     721        pReq->Hdr.rc = VERR_INTERNAL_ERROR;
     722        memcpy(pReq->u.In.szName, pszService, cchService);
     723        pReq->u.In.szName[cchService] = '\0';
     724        pReq->u.In.uOperation = uOperation;
     725        pReq->u.In.u64Arg = u64Arg;
     726        memcpy(&pReq->abReqPkt[0], pReqHdr, cbReq);
     727        rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_CALL_SERVICE(cbReq), pReq, SUP_IOCTL_CALL_SERVICE_SIZE(cbReq));
     728        if (RT_SUCCESS(rc))
     729            rc = pReq->Hdr.rc;
     730        memcpy(pReqHdr, &pReq->abReqPkt[0], cbReq);
     731    }
     732    else /** @todo may have to remove the size limits one this request... */
     733        AssertMsgFailedReturn(("cbReq=%#x\n", pReqHdr->cbReq), VERR_INTERNAL_ERROR);
     734    return rc;
     735}
     736
     737
    681738SUPR3DECL(int) SUPPageAlloc(size_t cPages, void **ppvPages)
    682739{
     
    11801237         * If it's VMMR0.r0 we need to install the IDTE.
    11811238         */
    1182         rc = supLoadModule(pszFilename, pszModule, ppvImageBase);
     1239        rc = supLoadModule(pszFilename, pszModule, NULL, ppvImageBase);
    11831240#ifdef VBOX_WITH_IDT_PATCHING
    11841241        if (    RT_SUCCESS(rc)
     
    11931250    else
    11941251        LogRel(("SUPLoadModule: Verification of \"%s\" failed, rc=%Rrc\n", rc));
     1252    return rc;
     1253}
     1254
     1255
     1256SUPR3DECL(int) SUPR3LoadServiceModule(const char *pszFilename, const char *pszModule,
     1257                                      const char *pszSrvReqHandler, void **ppvImageBase)
     1258{
     1259    int rc = VINF_SUCCESS;
     1260    AssertPtrReturn(pszSrvReqHandler, VERR_INVALID_PARAMETER);
     1261
     1262#ifdef VBOX_WITH_HARDENING
     1263    /*
     1264     * Check that the module can be trusted.
     1265     */
     1266    rc = supR3HardenedVerifyFile(pszFilename, false /* fFatal */);
     1267#endif
     1268    if (RT_SUCCESS(rc))
     1269    {
     1270        /*
     1271         * Load the module.
     1272         * If it's VMMR0.r0 we need to install the IDTE.
     1273         */
     1274        rc = supLoadModule(pszFilename, pszModule, pszSrvReqHandler, ppvImageBase);
     1275    }
     1276    else
     1277        LogRel(("SUPR3LoadServiceModule: Verification of \"%s\" failed, rc=%Rrc\n", rc));
    11951278    return rc;
    11961279}
     
    15691652 * @param   pszFilename     Name of the VMMR0 image file
    15701653 */
    1571 static int supLoadModule(const char *pszFilename, const char *pszModule, void **ppvImageBase)
     1654static int supLoadModule(const char *pszFilename, const char *pszModule, const char *pszSrvReqHandler, void **ppvImageBase)
    15721655{
    15731656    /*
     
    15801663
    15811664    const bool fIsVMMR0 = !strcmp(pszModule, "VMMR0.r0");
     1665    AssertReturn(!pszSrvReqHandler || !fIsVMMR0, VERR_INTERNAL_ERROR);
    15821666    *ppvImageBase = NULL;
    15831667
     
    16491733                    RTUINTPTR VMMR0EntryFast = 0;
    16501734                    RTUINTPTR VMMR0EntryEx = 0;
     1735                    RTUINTPTR SrvReqHandler = 0;
    16511736                    RTUINTPTR ModuleInit = 0;
    16521737                    RTUINTPTR ModuleTerm = 0;
     
    16591744                            rc = RTLdrGetSymbolEx(hLdrMod, &pLoadReq->u.In.achImage[0], (uintptr_t)OpenReq.u.Out.pvImageBase, "VMMR0EntryEx", &VMMR0EntryEx);
    16601745                    }
     1746                    else if (pszSrvReqHandler)
     1747                        rc = RTLdrGetSymbolEx(hLdrMod, &pLoadReq->u.In.achImage[0], (uintptr_t)OpenReq.u.Out.pvImageBase, pszSrvReqHandler, &SrvReqHandler);
    16611748                    if (RT_SUCCESS(rc))
    16621749                    {
     
    17041791                                pLoadReq->u.In.EP.VMMR0.pvVMMR0EntryFast= (RTR0PTR)VMMR0EntryFast;
    17051792                                pLoadReq->u.In.EP.VMMR0.pvVMMR0EntryEx  = (RTR0PTR)VMMR0EntryEx;
     1793                            }
     1794                            else if (pszSrvReqHandler)
     1795                            {
     1796                                pLoadReq->u.In.eEPType                = SUPLDRLOADEP_SERVICE;
     1797                                pLoadReq->u.In.EP.Service.pfnServiceReq = (RTR0PTR)SrvReqHandler;
     1798                                pLoadReq->u.In.EP.Service.apvReserved[0] = NIL_RTR0PTR;
     1799                                pLoadReq->u.In.EP.Service.apvReserved[1] = NIL_RTR0PTR;
     1800                                pLoadReq->u.In.EP.Service.apvReserved[2] = NIL_RTR0PTR;
    17061801                            }
    17071802                            else
  • trunk/src/VBox/HostDrivers/Support/win/SUPDrvA-win.asm

    r13858 r14332  
    294294
    295295
     296;;
     297; @cproto DECLASM(int) supdrvNtWrapServiceReqHandler(PFNRT pfnServiceReqHandler, PSUPDRVSESSION pSession, uint32_t uOperation, uint64_t u64Arg, PSUPR0SERVICEREQHDR pReqHdr);
     298;
     299; @param    pfnSerivceReqHandler rcx
     300; @param    pSession            rdx
     301; @param    uOperation          r8
     302; @param    u64Arg              r9
     303; @param    pReq                [rsp + 28h] / [rbp + 30h]
     304;
     305BEGINPROC supdrvNtWrapServiceReqHandler
     306        NtWrapProlog supdrvNtWrapServiceReqHandler
     307        NtWrapCreateMarker
     308
     309        mov     rax, rcx
     310        mov     rcx, rdx
     311        mov     rdx, r8
     312        mov     r8, r9
     313        mov     r9, [rbp + 30h]
     314        call    rax
     315
     316        NtWrapDestroyMarker
     317        NtWrapEpilog supdrvNtWrapServiceReqHandler
     318ENDPROC   supdrvNtWrapServiceReqHandler
     319
     320
    296321 %endif ; RT_ARCH_AMD64
    297322%endif ; RT_WITH_W64_UNWIND_HACK
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