VirtualBox

Changeset 14332

Show
Ignore:
Timestamp:
11/18/08 23:11:06 (2 months ago)
Author:
vboxsync
Message:

SUPDrv,SUPLib: generic ring-0 service interface.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/include/VBox/err.h

    r13703 r14332  
    11331133/** The component factories do not support the requested interface. */ 
    11341134#define VERR_SUPDRV_INTERFACE_NOT_SUPPORTED         (-3701) 
     1135/** The service module was not found. */ 
     1136#define VERR_SUPDRV_SERVICE_NOT_FOUND               (-3702) 
    11351137/** @} */ 
    11361138 
  • trunk/include/VBox/sup.h

    r13858 r14332  
    275275typedef SUPVMMR0REQHDR *PSUPVMMR0REQHDR; 
    276276/** the SUPVMMR0REQHDR::u32Magic value (Ethan Iverson - The Bad Plus). */ 
    277 #define SUPVMMR0REQHDR_MAGIC    UINT32_C(0x19730211) 
     277#define SUPVMMR0REQHDR_MAGIC        UINT32_C(0x19730211) 
    278278 
    279279 
     
    288288#define SUP_VMMR0_DO_NOP        2 
    289289/** @} */ 
     290 
     291 
     292/** 
     293 * Request for generic FNSUPR0SERVICEREQHANDLER calls. 
     294 */ 
     295typedef struct SUPR0SERVICEREQHDR 
     296{ 
     297    /** The magic. (SUPR0SERVICEREQHDR_MAGIC) */ 
     298    uint32_t    u32Magic; 
     299    /** The size of the request. */ 
     300    uint32_t    cbReq; 
     301} SUPR0SERVICEREQHDR; 
     302/** Pointer to a ring-0 service request header. */ 
     303typedef SUPR0SERVICEREQHDR *PSUPR0SERVICEREQHDR; 
     304/** the SUPVMMR0REQHDR::u32Magic value (Esbjoern Svensson - E.S.P.).  */ 
     305#define SUPR0SERVICEREQHDR_MAGIC    UINT32_C(0x19640416) 
    290306 
    291307 
     
    463479 
    464480/** 
     481 * Calls a ring-0 service. 
     482 * 
     483 * The operation and the request packet is specific to the service. 
     484 * 
     485 * @returns error code specific to uFunction. 
     486 * @param   pszService  The service name. 
     487 * @param   cchService  The length of the service name. 
     488 * @param   uReq        The request number. 
     489 * @param   u64Arg      Constant argument. 
     490 * @param   pReqHdr     Pointer to a request header. Optional. 
     491 *                      This will be copied in and out of kernel space. There currently is a size 
     492 *                      limit on this, just below 4KB. 
     493 */ 
     494SUPR3DECL(int) SUPR3CallR0Service(const char *pszService, size_t cchService, uint32_t uOperation, uint64_t u64Arg, PSUPR0SERVICEREQHDR pReqHdr); 
     495 
     496/** 
    465497 * Queries the paging mode of the host OS. 
    466498 * 
     
    626658 * @param   pszFilename     The path to the image file. 
    627659 * @param   pszModule       The module name. Max 32 bytes. 
     660 * @param   ppvImageBase        Where to store the image address. 
    628661 */ 
    629662SUPR3DECL(int) SUPLoadModule(const char *pszFilename, const char *pszModule, void **ppvImageBase); 
     663 
     664/** 
     665 * Load a module into R0 HC. 
     666 * 
     667 * This will verify the file integrity in a similar manner as 
     668 * SUPR3HardenedVerifyFile before loading it. 
     669 * 
     670 * @returns VBox status code. 
     671 * @param   pszFilename         The path to the image file. 
     672 * @param   pszModule           The module name. Max 32 bytes. 
     673 * @param   pszSrvReqHandler    The name of the service request handler entry 
     674 *                              point. See FNSUPR0SERVICEREQHANDLER. 
     675 * @param   ppvImageBase        Where to store the image address. 
     676 */ 
     677SUPR3DECL(int) SUPR3LoadServiceModule(const char *pszFilename, const char *pszModule, 
     678                                      const char *pszSrvReqHandler, void **ppvImageBase); 
    630679 
    631680/** 
     
    820869 
    821870 
     871/** 
     872 * Service request callback function. 
     873 * 
     874 * @returns VBox status code. 
     875 * @param   pSession    The caller's session. 
     876 * @param   u64Arg      64-bit integer argument. 
     877 * @param   pReqHdr     The request header. Input / Output. Optional. 
     878 */ 
     879typedef DECLCALLBACK(int) FNSUPR0SERVICEREQHANDLER(PSUPDRVSESSION pSession, uint32_t uOperation, 
     880                                                   uint64_t u64Arg, PSUPR0SERVICEREQHDR pReqHdr); 
     881/** Pointer to a FNR0SERVICEREQHANDLER(). */ 
     882typedef R0PTRTYPE(FNSUPR0SERVICEREQHANDLER *) PFNSUPR0SERVICEREQHANDLER; 
     883 
     884 
    822885/** @defgroup   grp_sup_r0_idc  The IDC Interface 
    823886 * @ingroup grp_sup_r0 
  • 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/