Esempio n. 1
0
/**
 * Register a access handler for a physical range.
 *
 * @returns VBox status code.
 * @param   pVM             Pointer to the VM.
 * @param   enmType         Handler type. Any of the PGMPHYSHANDLERTYPE_PHYSICAL* enums.
 * @param   GCPhys          Start physical address.
 * @param   GCPhysLast      Last physical address. (inclusive)
 * @param   pfnHandlerR3    The R3 handler.
 * @param   pvUserR3        User argument to the R3 handler.
 * @param   pszModR0        The R0 handler module. NULL means the default R0 module.
 * @param   pszHandlerR0    The R0 handler symbol name.
 * @param   pvUserR0        User argument to the R0 handler.
 * @param   pszModRC        The RC handler module. NULL means the default RC
 *                          module.
 * @param   pszHandlerRC    The RC handler symbol name.
 * @param   pvUserRC        User argument to the RC handler. Values less than
 *                          0x10000 will not be relocated.
 * @param   pszDesc         Pointer to description string. This must not be freed.
 */
VMMR3DECL(int) PGMR3HandlerPhysicalRegister(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhys, RTGCPHYS GCPhysLast,
                                            PFNPGMR3PHYSHANDLER pfnHandlerR3, void *pvUserR3,
                                            const char *pszModR0, const char *pszHandlerR0, RTR0PTR pvUserR0,
                                            const char *pszModRC, const char *pszHandlerRC, RTRCPTR pvUserRC, const char *pszDesc)
{
    LogFlow(("PGMR3HandlerPhysicalRegister: enmType=%d GCPhys=%RGp GCPhysLast=%RGp pfnHandlerR3=%RHv pvUserHC=%RHv pszModR0=%s pszHandlerR0=%s pvUserR0=%RHv pszModRC=%s pszHandlerRC=%s pvUser=%RRv pszDesc=%s\n",
             enmType, GCPhys, GCPhysLast, pfnHandlerR3, pvUserR3, pszModR0, pszHandlerR0, pvUserR0, pszHandlerRC, pszModRC, pvUserRC, pszDesc));

    /*
     * Validate input.
     */
    if (!pszModRC)
        pszModRC = VMMGC_MAIN_MODULE_NAME;
    if (!pszModR0)
        pszModR0 = VMMR0_MAIN_MODULE_NAME;
    if (!pszHandlerR0)
        pszHandlerR0 = "pgmPhysHandlerRedirectToHC";
    if (!pszHandlerRC)
        pszHandlerRC = "pgmPhysHandlerRedirectToHC";
    AssertPtrReturn(pfnHandlerR3, VERR_INVALID_POINTER);
    AssertPtrReturn(pszHandlerR0, VERR_INVALID_POINTER);
    AssertPtrReturn(pszHandlerRC, VERR_INVALID_POINTER);

    /*
     * Resolve the R0 handler.
     */
    R0PTRTYPE(PFNPGMR0PHYSHANDLER) pfnHandlerR0 = NIL_RTR0PTR;
    int rc = VINF_SUCCESS;
    rc = PDMR3LdrGetSymbolR0Lazy(pVM, pszModR0, NULL /*pszSearchPath*/, pszHandlerR0, &pfnHandlerR0);
    if (RT_SUCCESS(rc))
    {
        /*
         * Resolve the GC handler.
         */
        RTRCPTR pfnHandlerRC = NIL_RTRCPTR;
        if (!HMIsEnabled(pVM))
            rc = PDMR3LdrGetSymbolRCLazy(pVM, pszModRC, NULL /*pszSearchPath*/, pszHandlerRC, &pfnHandlerRC);
        if (RT_SUCCESS(rc))
            return PGMHandlerPhysicalRegisterEx(pVM, enmType, GCPhys, GCPhysLast, pfnHandlerR3, pvUserR3,
                                                pfnHandlerR0, pvUserR0, pfnHandlerRC, pvUserRC, pszDesc);

        AssertMsgFailed(("Failed to resolve %s.%s, rc=%Rrc.\n", pszModRC, pszHandlerRC, rc));
    }
    else
        AssertMsgFailed(("Failed to resolve %s.%s, rc=%Rrc.\n", pszModR0, pszHandlerR0, rc));

    return rc;
}
Esempio n. 2
0
    VMCPU_ASSERT_EMT(pVCpu);
    Assert(pVCpu->vmm.s.cCallRing3Disabled <= 16);
    return pVCpu->vmm.s.cCallRing3Disabled == 0;
}


/**
 * Sets the ring-0 callback before doing the ring-3 call.
 *
 * @param   pVCpu         The cross context virtual CPU structure.
 * @param   pfnCallback   Pointer to the callback.
 * @param   pvUser        The user argument.
 *
 * @return VBox status code.
 */
VMMRZDECL(int) VMMRZCallRing3SetNotification(PVMCPU pVCpu, R0PTRTYPE(PFNVMMR0CALLRING3NOTIFICATION) pfnCallback, RTR0PTR pvUser)
{
    AssertPtrReturn(pVCpu, VERR_INVALID_POINTER);
    AssertPtrReturn(pfnCallback, VERR_INVALID_POINTER);

    if (pVCpu->vmm.s.pfnCallRing3CallbackR0)
        return VERR_ALREADY_EXISTS;

    pVCpu->vmm.s.pfnCallRing3CallbackR0    = pfnCallback;
    pVCpu->vmm.s.pvCallRing3CallbackUserR0 = pvUser;
    return VINF_SUCCESS;
}


/**
 * Removes the ring-0 callback.
 * @returns VBox status code.
 * @param   pVM             Pointer to the cross context VM structure.
 * @param   enmKind         The kind of access handler.
 * @param   pfnHandlerR3    Pointer to the ring-3 handler callback.
 * @param   pfnHandlerR0    Pointer to the ring-0 handler callback.
 * @param   pfnPfHandlerR0  Pointer to the ring-0 \#PF handler callback.
 * @param   pfnHandlerRC    Pointer to the raw-mode context handler callback.
 * @param   pfnPfHandlerRC  Pointer to the raw-mode context \#PF handler
 *                          callback.
 * @param   pszDesc         The type description.
 * @param   phType          Where to return the type handle (cross context
 *                          safe).
 */
VMMR3_INT_DECL(int) PGMR3HandlerPhysicalTypeRegisterEx(PVM pVM, PGMPHYSHANDLERKIND enmKind,
                                                       PFNPGMPHYSHANDLER pfnHandlerR3,
                                                       R0PTRTYPE(PFNPGMPHYSHANDLER) pfnHandlerR0,
                                                       R0PTRTYPE(PFNPGMRZPHYSPFHANDLER) pfnPfHandlerR0,
                                                       RCPTRTYPE(PFNPGMPHYSHANDLER) pfnHandlerRC,
                                                       RCPTRTYPE(PFNPGMRZPHYSPFHANDLER) pfnPfHandlerRC,
                                                       const char *pszDesc, PPGMPHYSHANDLERTYPE phType)
{
    AssertPtrReturn(pfnHandlerR3, VERR_INVALID_POINTER);
    AssertReturn(pfnHandlerR0   != NIL_RTR0PTR, VERR_INVALID_POINTER);
    AssertReturn(pfnPfHandlerR0 != NIL_RTR0PTR, VERR_INVALID_POINTER);
    AssertReturn(pfnHandlerRC   != NIL_RTRCPTR || HMIsEnabled(pVM), VERR_INVALID_POINTER);
    AssertReturn(pfnPfHandlerRC != NIL_RTRCPTR || HMIsEnabled(pVM), VERR_INVALID_POINTER);
    AssertPtrReturn(pszDesc, VERR_INVALID_POINTER);
    AssertReturn(   enmKind == PGMPHYSHANDLERKIND_WRITE
                 || enmKind == PGMPHYSHANDLERKIND_ALL
                 || enmKind == PGMPHYSHANDLERKIND_MMIO,
                 VERR_INVALID_PARAMETER);