VirtualBox

Changeset 55889 in vbox


Ignore:
Timestamp:
May 17, 2015 6:01:37 PM (10 years ago)
Author:
vboxsync
Message:

VMM: Split up virtual handlers just like the physical ones, such that the kind+callbacks are stored seprately from the actual handler registration. This should hopefully save a byte or two when adding more callbacks. Implemented the pvUser for ring-3 callbacks.

Location:
trunk
Files:
20 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/pgm.h

    r55493 r55889  
    159159 * Virtual access handler type.
    160160 */
    161 typedef enum PGMVIRTHANDLERTYPE
     161typedef enum PGMVIRTHANDLERKIND
    162162{
    163163    /** Write access handled. */
    164     PGMVIRTHANDLERTYPE_WRITE = 1,
     164    PGMVIRTHANDLERKIND_WRITE = 1,
    165165    /** All access handled. */
    166     PGMVIRTHANDLERTYPE_ALL,
     166    PGMVIRTHANDLERKIND_ALL,
    167167    /** Hypervisor write access handled.
    168168     * This is used to catch the guest trying to write to LDT, TSS and any other
    169169     * system structure which the brain dead intel guys let unprivilegde code find. */
    170     PGMVIRTHANDLERTYPE_HYPERVISOR
    171 } PGMVIRTHANDLERTYPE;
     170    PGMVIRTHANDLERKIND_HYPERVISOR
     171} PGMVIRTHANDLERKIND;
    172172
    173173/**
     
    357357/** NIL value for PGM physical access handler type handle. */
    358358#define NIL_PGMPHYSHANDLERTYPE  UINT32_MAX
    359 VMMDECL(uint32_t)   PGMHandlerPhysicalTypeRelease(PVM pVM, PGMPHYSHANDLERTYPE hCallbacks);
    360 VMMDECL(uint32_t)   PGMHandlerPhysicalTypeRetain(PVM pVM, PGMPHYSHANDLERTYPE hCallbacks);
     359VMMDECL(uint32_t)   PGMHandlerPhysicalTypeRelease(PVM pVM, PGMPHYSHANDLERTYPE hType);
     360VMMDECL(uint32_t)   PGMHandlerPhysicalTypeRetain(PVM pVM, PGMPHYSHANDLERTYPE hType);
    361361
    362362VMMDECL(int)        PGMHandlerPhysicalRegister(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS GCPhysLast, PGMPHYSHANDLERTYPE hType,
     
    373373VMMDECL(int)        PGMHandlerPhysicalReset(PVM pVM, RTGCPHYS GCPhys);
    374374VMMDECL(bool)       PGMHandlerPhysicalIsRegistered(PVM pVM, RTGCPHYS GCPhys);
    375 VMMDECL(bool)       PGMHandlerVirtualIsRegistered(PVM pVM, RTGCPTR GCPtr);
     375
     376/** PGM virtual access handler type registration handle (heap offset, valid
     377 * cross contexts without needing fixing up).  Callbacks and handler type is
     378 * associated with this and it is shared by all handler registrations. */
     379typedef uint32_t PGMVIRTHANDLERTYPE;
     380/** Pointer to a PGM virtual handler type registration handle. */
     381typedef PGMVIRTHANDLERTYPE *PPGMVIRTHANDLERTYPE;
     382/** NIL value for PGM virtual access handler type handle. */
     383#define NIL_PGMVIRTHANDLERTYPE  UINT32_MAX
     384VMM_INT_DECL(uint32_t) PGMHandlerVirtualTypeRelease(PVM pVM, PGMVIRTHANDLERTYPE hType);
     385VMM_INT_DECL(uint32_t) PGMHandlerVirtualTypeRetain(PVM pVM, PGMVIRTHANDLERTYPE hType);
     386VMM_INT_DECL(bool)     PGMHandlerVirtualIsRegistered(PVM pVM, RTGCPTR GCPtr);
     387
    376388VMMDECL(bool)       PGMPhysIsA20Enabled(PVMCPU pVCpu);
    377389VMMDECL(bool)       PGMPhysIsGCPhysValid(PVM pVM, RTGCPHYS GCPhys);
     
    521533VMMR3DECL(int)      PGMR3MapRead(PVM pVM, void *pvDst, RTGCPTR GCPtrSrc, size_t cb);
    522534
    523 VMM_INT_DECL(int)  PGMR3HandlerPhysicalTypeRegisterEx(PVM pVM, PGMPHYSHANDLERKIND enmKind,
     535VMMR3_INT_DECL(int) PGMR3HandlerPhysicalTypeRegisterEx(PVM pVM, PGMPHYSHANDLERKIND enmKind,
    524536                                                       PFNPGMR3PHYSHANDLER pfnHandlerR3,
    525537                                                       R0PTRTYPE(PFNPGMR0PHYSHANDLER) pfnHandlerR0,
     
    531543                                                     const char *pszModRC, const char *pszHandlerRC, const char *pszDesc,
    532544                                                     PPGMPHYSHANDLERTYPE phType);
    533 VMMDECL(int)        PGMR3HandlerVirtualRegisterEx(PVM pVM, PGMVIRTHANDLERTYPE enmType, RTGCPTR GCPtr, RTGCPTR GCPtrLast,
    534                                                   R3PTRTYPE(PFNPGMR3VIRTINVALIDATE) pfnInvalidateR3,
    535                                                   R3PTRTYPE(PFNPGMR3VIRTHANDLER) pfnHandlerR3,
    536                                                   RCPTRTYPE(PFNPGMRCVIRTHANDLER) pfnHandlerRC,
    537                                                   R3PTRTYPE(const char *) pszDesc);
    538 VMMR3DECL(int)      PGMR3HandlerVirtualRegister(PVM pVM, PGMVIRTHANDLERTYPE enmType, RTGCPTR GCPtr, RTGCPTR GCPtrLast,
    539                                                 PFNPGMR3VIRTINVALIDATE pfnInvalidateR3,
    540                                                 PFNPGMR3VIRTHANDLER pfnHandlerR3,
    541                                                 const char *pszHandlerRC, const char *pszModRC, const char *pszDesc);
    542 VMMDECL(int)        PGMHandlerVirtualChangeInvalidateCallback(PVM pVM, RTGCPTR GCPtr, R3PTRTYPE(PFNPGMR3VIRTINVALIDATE) pfnInvalidateR3);
    543 VMMDECL(int)        PGMHandlerVirtualDeregister(PVM pVM, RTGCPTR GCPtr);
     545VMMR3_INT_DECL(int) PGMR3HandlerVirtualTypeRegisterEx(PVM pVM, PGMVIRTHANDLERKIND enmKind, bool fRelocUserRC,
     546                                                      PFNPGMR3VIRTINVALIDATE pfnInvalidateR3,
     547                                                      PFNPGMR3VIRTHANDLER pfnHandlerR3,
     548                                                      RCPTRTYPE(PFNPGMRCVIRTHANDLER) pfnHandlerRC,
     549                                                      const char *pszDesc, PPGMVIRTHANDLERTYPE phType);
     550VMMR3_INT_DECL(int) PGMR3HandlerVirtualTypeRegister(PVM pVM, PGMVIRTHANDLERKIND enmKind, bool fRelocUserRC,
     551                                                    PFNPGMR3VIRTINVALIDATE pfnInvalidateR3,
     552                                                    PFNPGMR3VIRTHANDLER pfnHandlerR3,
     553                                                    const char *pszHandlerRC, const char *pszModRC, const char *pszDesc,
     554                                                    PPGMVIRTHANDLERTYPE phType);
     555VMMR3_INT_DECL(int) PGMR3HandlerVirtualRegister(PVM pVM, PVMCPU pVCpu, PGMVIRTHANDLERTYPE hType, RTGCPTR GCPtr,
     556                                                RTGCPTR GCPtrLast, void *pvUserR3, RTRCPTR pvUserRC, const char *pszDesc);
     557VMMR3_INT_DECL(int) PGMHandlerVirtualChangeType(PVM pVM, RTGCPTR GCPtr, PGMVIRTHANDLERTYPE hNewType);
     558VMMDECL(int)        PGMHandlerVirtualDeregister(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, bool fHypervisor);
    544559VMMR3DECL(int)      PGMR3PoolGrow(PVM pVM);
    545560
  • trunk/src/VBox/VMM/VMMAll/PGMAllBth.h

    r55493 r55889  
    1616
    1717/*
    18  * Copyright (C) 2006-2013 Oracle Corporation
     18 * Copyright (C) 2006-2015 Oracle Corporation
    1919 *
    2020 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    320320        if (pCur)
    321321        {
     322            PPGMVIRTHANDLERTYPEINT pCurType = PGMVIRTANDLER_GET_TYPE(pVM, pCur);
    322323            AssertMsg(!(pvFault - pCur->Core.Key < pCur->cb)
    323                       || (     pCur->enmType != PGMVIRTHANDLERTYPE_WRITE
     324                      || (     pCurType->enmKind != PGMVIRTHANDLERKIND_WRITE
    324325                           || !(uErr & X86_TRAP_PF_P)
    325                            || (pCur->enmType == PGMVIRTHANDLERTYPE_WRITE && (uErr & X86_TRAP_PF_RW))),
    326                       ("Unexpected trap for virtual handler: %RGv (phys=%RGp) pPage=%R[pgmpage] uErr=%X, enum=%d\n",
    327                        pvFault, pGstWalk->Core.GCPhys, pPage, uErr, pCur->enmType));
     326                           || (pCurType->enmKind == PGMVIRTHANDLERKIND_WRITE && (uErr & X86_TRAP_PF_RW))),
     327                      ("Unexpected trap for virtual handler: %RGv (phys=%RGp) pPage=%R[pgmpage] uErr=%X, enumKind=%d\n",
     328                       pvFault, pGstWalk->Core.GCPhys, pPage, uErr, pCurType->enmKind));
    328329
    329330            if (    pvFault - pCur->Core.Key < pCur->cb
    330331                &&  (    uErr & X86_TRAP_PF_RW
    331                      ||  pCur->enmType != PGMVIRTHANDLERTYPE_WRITE ) )
     332                     ||  pCurType->enmKind != PGMVIRTHANDLERKIND_WRITE ) )
    332333            {
    333334#   ifdef IN_RC
    334335                STAM_PROFILE_START(&pCur->Stat, h);
    335336                RTGCPTR                     GCPtrStart = pCur->Core.Key;
    336                 CTX_MID(PFNPGM,VIRTHANDLER) pfnHandler = pCur->CTX_SUFF(pfnHandler);
     337                CTX_MID(PFNPGM,VIRTHANDLER) pfnHandler = pCurType->CTX_SUFF(pfnHandler);
    337338                pgmUnlock(pVM);
    338339                *pfLockTaken = false;
     
    363364            rc = pgmHandlerVirtualFindByPhysAddr(pVM, pGstWalk->Core.GCPhys, &pCur, &iPage);
    364365            Assert(RT_SUCCESS(rc) || !pCur);
    365             if (    pCur
    366                 &&  (   uErr & X86_TRAP_PF_RW
    367                      || pCur->enmType != PGMVIRTHANDLERTYPE_WRITE ) )
     366            if (pCur)
    368367            {
    369                 Assert((pCur->aPhysToVirt[iPage].Core.Key & X86_PTE_PAE_PG_MASK) == (pGstWalk->Core.GCPhys & X86_PTE_PAE_PG_MASK));
     368                PPGMVIRTHANDLERTYPEINT pCurType = PGMVIRTANDLER_GET_TYPE(pVM, pCur);
     369                if  (   uErr & X86_TRAP_PF_RW
     370                     || pCurType->enmKind != PGMVIRTHANDLERKIND_WRITE )
     371                {
     372                    Assert(   (pCur->aPhysToVirt[iPage].Core.Key & X86_PTE_PAE_PG_MASK)
     373                           == (pGstWalk->Core.GCPhys & X86_PTE_PAE_PG_MASK));
    370374#   ifdef IN_RC
    371                 STAM_PROFILE_START(&pCur->Stat, h);
    372                 RTGCPTR                     GCPtrStart = pCur->Core.Key;
    373                 CTX_MID(PFNPGM,VIRTHANDLER) pfnHandler = pCur->CTX_SUFF(pfnHandler);
    374                 pgmUnlock(pVM);
    375                 *pfLockTaken = false;
    376 
    377                 RTGCPTR off = (iPage << PAGE_SHIFT)
    378                             + (pvFault    & PAGE_OFFSET_MASK)
    379                             - (GCPtrStart & PAGE_OFFSET_MASK);
    380                 Assert(off < pCur->cb);
    381                 rc = pfnHandler(pVM, uErr, pRegFrame, pvFault, GCPtrStart, off);
     375                    STAM_PROFILE_START(&pCur->Stat, h);
     376                    RTGCPTR                     GCPtrStart = pCur->Core.Key;
     377                    CTX_MID(PFNPGM,VIRTHANDLER) pfnHandler = pCurType->CTX_SUFF(pfnHandler);
     378                    pgmUnlock(pVM);
     379                    *pfLockTaken = false;
     380
     381                    RTGCPTR off = (iPage << PAGE_SHIFT)
     382                                + (pvFault    & PAGE_OFFSET_MASK)
     383                                - (GCPtrStart & PAGE_OFFSET_MASK);
     384                    Assert(off < pCur->cb);
     385                    rc = pfnHandler(pVM, uErr, pRegFrame, pvFault, GCPtrStart, off);
    382386
    383387#    ifdef VBOX_WITH_STATISTICS
    384                 pgmLock(pVM);
    385                 pCur = (PPGMVIRTHANDLER)RTAvlroGCPtrRangeGet(&pVM->pgm.s.CTX_SUFF(pTrees)->VirtHandlers, GCPtrStart);
    386                 if (pCur)
    387                     STAM_PROFILE_STOP(&pCur->Stat, h);
    388                 pgmUnlock(pVM);
     388                    pgmLock(pVM);
     389                    pCur = (PPGMVIRTHANDLER)RTAvlroGCPtrRangeGet(&pVM->pgm.s.CTX_SUFF(pTrees)->VirtHandlers, GCPtrStart);
     390                    if (pCur)
     391                        STAM_PROFILE_STOP(&pCur->Stat, h);
     392                    pgmUnlock(pVM);
    389393#    endif
    390394#   else
    391                 rc = VINF_EM_RAW_EMULATE_INSTR; /** @todo for VMX */
     395                    rc = VINF_EM_RAW_EMULATE_INSTR; /** @todo for VMX */
    392396#   endif
    393                 STAM_COUNTER_INC(&pVCpu->pgm.s.CTX_SUFF(pStats)->StatRZTrap0eHandlersVirtualByPhys);
    394                 STAM_STATS({ pVCpu->pgm.s.CTX_SUFF(pStatTrap0eAttribution) = &pVCpu->pgm.s.CTX_SUFF(pStats)->StatRZTrap0eTime2HndVirt; });
    395                 return rc;
     397                    STAM_COUNTER_INC(&pVCpu->pgm.s.CTX_SUFF(pStats)->StatRZTrap0eHandlersVirtualByPhys);
     398                    STAM_STATS({ pVCpu->pgm.s.CTX_SUFF(pStatTrap0eAttribution) = &pVCpu->pgm.s.CTX_SUFF(pStats)->StatRZTrap0eTime2HndVirt; });
     399                    return rc;
     400                }
    396401            }
    397402        }
     
    720725#   ifdef IN_RC
    721726                    STAM_PROFILE_START(&pCur->Stat, h);
     727                    PPGMVIRTHANDLERTYPEINT pCurType = PGMVIRTANDLER_GET_TYPE(pVM, pCur);
    722728                    pgmUnlock(pVM);
    723                     rc = pCur->CTX_SUFF(pfnHandler)(pVM, uErr, pRegFrame, pvFault, pCur->Core.Key, pvFault - pCur->Core.Key);
     729                    rc = pCurType->CTX_SUFF(pfnHandler)(pVM, uErr, pRegFrame, pvFault, pCur->Core.Key, pvFault - pCur->Core.Key);
    724730                    pgmLock(pVM);
    725731                    STAM_PROFILE_STOP(&pCur->Stat, h);
     
    800806        if (pCur)
    801807        {
     808            PPGMVIRTHANDLERTYPEINT pCurType = PGMVIRTANDLER_GET_TYPE(pVM, pCur);
    802809            AssertMsg(   !(pvFault - pCur->Core.Key < pCur->cb)
    803                       || (    pCur->enmType != PGMVIRTHANDLERTYPE_WRITE
     810                      || (    pCurType->enmKind != PGMVIRTHANDLERKIND_WRITE
    804811                           || !(uErr & X86_TRAP_PF_P)
    805                            || (pCur->enmType == PGMVIRTHANDLERTYPE_WRITE && (uErr & X86_TRAP_PF_RW))),
    806                       ("Unexpected trap for virtual handler: %08X (phys=%08x) %R[pgmpage] uErr=%X, enum=%d\n", pvFault, GCPhys, pPage, uErr, pCur->enmType));
     812                           || (pCurType->enmKind == PGMVIRTHANDLERKIND_WRITE && (uErr & X86_TRAP_PF_RW))),
     813                      ("Unexpected trap for virtual handler: %08X (phys=%08x) %R[pgmpage] uErr=%X, enumKind=%d\n",
     814                       pvFault, GCPhys, pPage, uErr, pCurType->enmKind));
    807815
    808816            if (    pvFault - pCur->Core.Key < pCur->cb
    809817                &&  (    uErr & X86_TRAP_PF_RW
    810                      ||  pCur->enmType != PGMVIRTHANDLERTYPE_WRITE ) )
     818                     ||  pCurType->enmKind != PGMVIRTHANDLERKIND_WRITE ) )
    811819            {
    812820#   ifdef IN_RC
    813821                STAM_PROFILE_START(&pCur->Stat, h);
    814822                pgmUnlock(pVM);
    815                 rc = pCur->CTX_SUFF(pfnHandler)(pVM, uErr, pRegFrame, pvFault, pCur->Core.Key, pvFault - pCur->Core.Key);
     823                rc = pCurType->CTX_SUFF(pfnHandler)(pVM, uErr, pRegFrame, pvFault, pCur->Core.Key, pvFault - pCur->Core.Key);
    816824                pgmLock(pVM);
    817825                STAM_PROFILE_STOP(&pCur->Stat, h);
  • trunk/src/VBox/VMM/VMMAll/PGMAllGst.h

    r44528 r55889  
    55
    66/*
    7  * Copyright (C) 2006-2012 Oracle Corporation
     7 * Copyright (C) 2006-2015 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    462462static DECLCALLBACK(int) PGM_GST_NAME(VirtHandlerUpdateOne)(PAVLROGCPTRNODECORE pNode, void *pvUser)
    463463{
    464     PPGMVIRTHANDLER pCur   = (PPGMVIRTHANDLER)pNode;
    465     PPGMHVUSTATE    pState = (PPGMHVUSTATE)pvUser;
    466     PVM             pVM    = pState->pVM;
    467     PVMCPU          pVCpu  = pState->pVCpu;
    468     Assert(pCur->enmType != PGMVIRTHANDLERTYPE_HYPERVISOR);
     464    PPGMHVUSTATE            pState   = (PPGMHVUSTATE)pvUser;
     465    PVM                     pVM      = pState->pVM;
     466    PVMCPU                  pVCpu    = pState->pVCpu;
     467    PPGMVIRTHANDLER         pCur     = (PPGMVIRTHANDLER)pNode;
     468    PPGMVIRTHANDLERTYPEINT  pCurType = PGMVIRTANDLER_GET_TYPE(pVM, pCur);
     469
     470    Assert(pCurType->enmKind != PGMVIRTHANDLERKIND_HYPERVISOR);
    469471
    470472# if PGM_GST_TYPE == PGM_TYPE_32BIT
  • trunk/src/VBox/VMM/VMMAll/PGMAllHandler.cpp

    r55493 r55889  
    55
    66/*
    7  * Copyright (C) 2006-2013 Oracle Corporation
     7 * Copyright (C) 2006-2015 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    13671367
    13681368/**
     1369 * Internal worker for releasing a virtual handler type registration reference.
     1370 *
     1371 * @returns New reference count. UINT32_MAX if invalid input (asserted).
     1372 * @param   pVM         Pointer to the cross context VM structure.
     1373 * @param   pType       Pointer to the type registration.
     1374 */
     1375DECLINLINE(uint32_t) pgmHandlerVirtualTypeRelease(PVM pVM, PPGMVIRTHANDLERTYPEINT pType)
     1376{
     1377    AssertMsgReturn(pType->u32Magic == PGMVIRTHANDLERTYPEINT_MAGIC, ("%#x\n", pType->u32Magic), UINT32_MAX);
     1378    uint32_t cRefs = ASMAtomicDecU32(&pType->cRefs);
     1379    if (cRefs == 0)
     1380    {
     1381        pgmLock(pVM);
     1382        pType->u32Magic = PGMVIRTHANDLERTYPEINT_MAGIC_DEAD;
     1383        RTListOff32NodeRemove(&pType->ListNode);
     1384        pgmUnlock(pVM);
     1385        MMHyperFree(pVM, pType);
     1386    }
     1387    return cRefs;
     1388}
     1389
     1390
     1391/**
     1392 * Internal worker for retaining a virtual handler type registration reference.
     1393 *
     1394 * @returns New reference count. UINT32_MAX if invalid input (asserted).
     1395 * @param   pVM         Pointer to the cross context VM structure.
     1396 * @param   pType       Pointer to the type registration.
     1397 */
     1398DECLINLINE(uint32_t) pgmHandlerVirtualTypeRetain(PVM pVM, PPGMVIRTHANDLERTYPEINT pType)
     1399{
     1400    AssertMsgReturn(pType->u32Magic == PGMVIRTHANDLERTYPEINT_MAGIC, ("%#x\n", pType->u32Magic), UINT32_MAX);
     1401    uint32_t cRefs = ASMAtomicIncU32(&pType->cRefs);
     1402    Assert(cRefs < _1M && cRefs > 0);
     1403    return cRefs;
     1404}
     1405
     1406
     1407/**
     1408 * Releases a reference to a virtual handler type registration.
     1409 *
     1410 * @returns New reference count. UINT32_MAX if invalid input (asserted).
     1411 * @param   pVM         Pointer to the cross context VM structure.
     1412 * @param   hType       The type regiration handle.
     1413 */
     1414VMM_INT_DECL(uint32_t) PGMHandlerVirtualTypeRelease(PVM pVM, PGMVIRTHANDLERTYPE hType)
     1415{
     1416    if (hType != NIL_PGMVIRTHANDLERTYPE)
     1417        return pgmHandlerVirtualTypeRelease(pVM, PGMVIRTHANDLERTYPEINT_FROM_HANDLE(pVM, hType));
     1418    return 0;
     1419}
     1420
     1421
     1422/**
     1423 * Retains a reference to a virtual handler type registration.
     1424 *
     1425 * @returns New reference count. UINT32_MAX if invalid input (asserted).
     1426 * @param   pVM         Pointer to the cross context VM structure.
     1427 * @param   hType       The type regiration handle.
     1428 */
     1429VMM_INT_DECL(uint32_t) PGMHandlerVirtualTypeRetain(PVM pVM, PGMVIRTHANDLERTYPE hType)
     1430{
     1431    return pgmHandlerVirtualTypeRetain(pVM, PGMVIRTHANDLERTYPEINT_FROM_HANDLE(pVM, hType));
     1432}
     1433
     1434
     1435/**
    13691436 * Check if particular guest's VA is being monitored.
    13701437 *
     
    13751442 * @thread  Any.
    13761443 */
    1377 VMMDECL(bool) PGMHandlerVirtualIsRegistered(PVM pVM, RTGCPTR GCPtr)
     1444VMM_INT_DECL(bool) PGMHandlerVirtualIsRegistered(PVM pVM, RTGCPTR GCPtr)
    13781445{
    13791446    pgmLock(pVM);
     
    14931560     * Iterate the pages and apply the new state.
    14941561     */
    1495     unsigned        uState   = pgmHandlerVirtualCalcState(pCur);
     1562    uint32_t        uState   = PGMVIRTANDLER_GET_TYPE(pVM, pCur)->uState;
    14961563    PPGMRAMRANGE    pRamHint = NULL;
    14971564    RTGCUINTPTR     offPage  = ((RTGCUINTPTR)pCur->Core.Key & PAGE_OFFSET_MASK);
     
    16451712static DECLCALLBACK(int) pgmHandlerVirtualVerifyOne(PAVLROGCPTRNODECORE pNode, void *pvUser)
    16461713{
    1647     PPGMVIRTHANDLER pVirt   = (PPGMVIRTHANDLER)pNode;
    1648     PPGMAHAFIS      pState  = (PPGMAHAFIS)pvUser;
    1649     PVM             pVM     = pState->pVM;
     1714    PPGMAHAFIS              pState  = (PPGMAHAFIS)pvUser;
     1715    PVM                     pVM     = pState->pVM;
     1716    PPGMVIRTHANDLER         pVirt   = (PPGMVIRTHANDLER)pNode;
     1717    PPGMVIRTHANDLERTYPEINT  pType   = PGMVIRTANDLER_GET_TYPE(pVM, pVirt);
    16501718
    16511719    /*
    16521720     * Validate the type and calc state.
    16531721     */
    1654     switch (pVirt->enmType)
    1655     {
    1656         case PGMVIRTHANDLERTYPE_WRITE:
    1657         case PGMVIRTHANDLERTYPE_ALL:
     1722    switch (pType->enmKind)
     1723    {
     1724        case PGMVIRTHANDLERKIND_WRITE:
     1725        case PGMVIRTHANDLERKIND_ALL:
    16581726            break;
    16591727        default:
    1660             AssertMsgFailed(("unknown/wrong enmType=%d\n", pVirt->enmType));
     1728            AssertMsgFailed(("unknown/wrong enmKind=%d\n", pType->enmKind));
    16611729            pState->cErrors++;
    16621730            return 0;
    16631731    }
    1664     const unsigned uState = pgmHandlerVirtualCalcState(pVirt);
     1732    const uint32_t uState = pType->uState;
    16651733
    16661734    /*
     
    18571925                        GCPhysKey = pPhys2Virt->Core.KeyLast;
    18581926                        PPGMVIRTHANDLER pCur = (PPGMVIRTHANDLER)((uintptr_t)pPhys2Virt + pPhys2Virt->offVirtHandler);
    1859                         unsigned uState = pgmHandlerVirtualCalcState(pCur);
     1927                        unsigned uState = PGMVIRTANDLER_GET_TYPE(pVM, pCur)->uState;
    18601928                        State.uVirtStateFound = RT_MAX(State.uVirtStateFound, uState);
    18611929
     
    18651933                            pPhys2Virt = (PPGMPHYS2VIRTHANDLER)((uintptr_t)pPhys2Virt + (pPhys2Virt->offNextAlias & PGMPHYS2VIRTHANDLER_OFF_MASK));
    18661934                            pCur = (PPGMVIRTHANDLER)((uintptr_t)pPhys2Virt + pPhys2Virt->offVirtHandler);
    1867                             uState = pgmHandlerVirtualCalcState(pCur);
     1935                            uState = PGMVIRTANDLER_GET_TYPE(pVM, pCur)->uState;
    18681936                            State.uVirtStateFound = RT_MAX(State.uVirtStateFound, uState);
    18691937                        }
  • trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp

    r55493 r55889  
    55
    66/*
    7  * Copyright (C) 2006-2012 Oracle Corporation
     7 * Copyright (C) 2006-2015 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    21592159        Assert(GCPhys >= pVirt->aPhysToVirt[iPage].Core.Key && GCPhys <= pVirt->aPhysToVirt[iPage].Core.KeyLast);
    21602160
     2161        PPGMVIRTHANDLERTYPEINT pVirtType = PGMVIRTANDLER_GET_TYPE(pVM, pVirt);
    21612162#ifdef IN_RING3
    2162         if (pVirt->pfnHandlerR3)
     2163        if (pVirtType->pfnHandlerR3)
    21632164        {
    21642165            if (!pPhys)
     
    21712172
    21722173            STAM_PROFILE_START(&pVirt->Stat, h);
    2173             rc2 = pVirt->CTX_SUFF(pfnHandler)(pVM, GCPtr, (void *)pvSrc, pvBuf, cb, PGMACCESSTYPE_READ, /*pVirt->CTX_SUFF(pvUser)*/ NULL);
     2174            rc2 = pVirtType->CTX_SUFF(pfnHandler)(pVM, GCPtr, (void *)pvSrc, pvBuf, cb, PGMACCESSTYPE_READ,
     2175                                                  pVirt->CTX_SUFF(pvUser));
    21742176            STAM_PROFILE_STOP(&pVirt->Stat, h);
    21752177            if (rc2 == VINF_SUCCESS)
     
    24302432        if (RT_SUCCESS(rc))
    24312433        {
     2434            PPGMVIRTHANDLERTYPEINT pCurType = PGMVIRTANDLER_GET_TYPE(pVM, pCur);
     2435
    24322436            size_t cbRange = (PAGE_OFFSET_MASK & pCur->Core.KeyLast) - (PAGE_OFFSET_MASK & GCPhys) + 1;
    24332437            if (cbRange > cbWrite)
     
    24472451            {
    24482452                rc = VINF_PGM_HANDLER_DO_DEFAULT;
    2449                 if (pCur->pfnHandlerR3)
     2453                if (pCurType->pfnHandlerR3)
    24502454                {
    24512455                    RTGCUINTPTR GCPtr = ((RTGCUINTPTR)pCur->Core.Key & PAGE_BASE_GC_MASK)
     
    24542458
    24552459                    STAM_PROFILE_START(&pCur->Stat, h);
    2456                     rc = pCur->CTX_SUFF(pfnHandler)(pVM, GCPtr, pvDst, (void *)pvBuf, cbRange, PGMACCESSTYPE_WRITE, /*pCur->CTX_SUFF(pvUser)*/ NULL);
     2460                    rc = pCurType->CTX_SUFF(pfnHandler)(pVM, GCPtr, pvDst, (void *)pvBuf, cbRange, PGMACCESSTYPE_WRITE,
     2461                                                        pCur->CTX_SUFF(pvUser));
    24572462                    STAM_PROFILE_STOP(&pCur->Stat, h);
    24582463                }
     
    26312636            if (cbRange > offPhys)
    26322637                cbRange = offPhys;
     2638
     2639            PPGMVIRTHANDLERTYPEINT pVirtType = PGMVIRTANDLER_GET_TYPE(pVM, pVirt);
    26332640#ifdef IN_RING3
    26342641            Log5(("pgmPhysWriteHandler: GCPhys=%RGp cbRange=%#x pPage=%R[pgmpage] phys %s\n", GCPhys, cbRange, pPage, R3STRING(pVirt->pszDesc) ));
    2635             if (pVirt->pfnHandlerR3)
     2642            if (pVirtType->pfnHandlerR3)
    26362643            {
    26372644                RTGCUINTPTR GCPtr = ((RTGCUINTPTR)pVirt->Core.Key & PAGE_BASE_GC_MASK)
     
    26392646                                  + (GCPhys & PAGE_OFFSET_MASK);
    26402647                STAM_PROFILE_START(&pVirt->Stat, h);
    2641                 rc = pVirt->CTX_SUFF(pfnHandler)(pVM, GCPtr, pvDst, (void *)pvBuf, cbRange, PGMACCESSTYPE_WRITE, /*pCur->CTX_SUFF(pvUser)*/ NULL);
     2648                rc = pVirtType->CTX_SUFF(pfnHandler)(pVM, GCPtr, pvDst, (void *)pvBuf, cbRange, PGMACCESSTYPE_WRITE,
     2649                                                     pVirt->CTX_SUFF(pvUser));
    26422650                STAM_PROFILE_STOP(&pVirt->Stat, h);
    26432651                AssertLogRelMsg(rc == VINF_SUCCESS || rc == VINF_PGM_HANDLER_DO_DEFAULT, ("rc=%Rrc GCPhys=%RGp pPage=%R[pgmpage] %s\n", rc, GCPhys, pPage, pVirt->pszDesc));
     
    26632671                cbRange = offPhysLast + 1;
    26642672
     2673            PPGMVIRTHANDLERTYPEINT pVirtType = PGMVIRTANDLER_GET_TYPE(pVM, pVirt);
    26652674#ifdef IN_RING3
    2666             if (pVirt->pfnHandlerR3)
     2675            if (pVirtType->pfnHandlerR3)
    26672676                Log(("pgmPhysWriteHandler: overlapping phys and virt handlers at %RGp %R[pgmpage]; cbRange=%#x\n", GCPhys, pPage, cbRange));
    26682677            Log5(("pgmPhysWriteHandler: GCPhys=%RGp cbRange=%#x pPage=%R[pgmpage] phys/virt %s/%s\n", GCPhys, cbRange, pPage, R3STRING(pPhys->pszDesc), R3STRING(pVirt->pszDesc) ));
     
    26852694# endif
    26862695            AssertLogRelMsg(rc == VINF_SUCCESS || rc == VINF_PGM_HANDLER_DO_DEFAULT, ("rc=%Rrc GCPhys=%RGp pPage=%R[pgmpage] %s\n", rc, GCPhys, pPage, (pPhys) ? pPhys->pszDesc : ""));
    2687             if (pVirt->pfnHandlerR3)
     2696            if (pVirtType->pfnHandlerR3)
    26882697            {
    26892698
     
    26922701                                  + (GCPhys & PAGE_OFFSET_MASK);
    26932702                STAM_PROFILE_START(&pVirt->Stat, h2);
    2694                 int rc2 = pVirt->CTX_SUFF(pfnHandler)(pVM, GCPtr, pvDst, (void *)pvBuf, cbRange, PGMACCESSTYPE_WRITE, /*pCur->CTX_SUFF(pvUser)*/ NULL);
     2703                int rc2 = pVirtType->CTX_SUFF(pfnHandler)(pVM, GCPtr, pvDst, (void *)pvBuf, cbRange, PGMACCESSTYPE_WRITE,
     2704                                                          pVirt->CTX_SUFF(pvUser));
    26952705                STAM_PROFILE_STOP(&pVirt->Stat, h2);
    26962706                if (rc2 == VINF_SUCCESS && rc == VINF_PGM_HANDLER_DO_DEFAULT)
  • trunk/src/VBox/VMM/VMMR3/CSAM.cpp

    r55001 r55889  
    251251
    252252    /*
     253     * Register virtual handler types.
     254     */
     255    rc = PGMR3HandlerVirtualTypeRegister(pVM, PGMVIRTHANDLERKIND_WRITE, false /*fRelocUserRC*/,
     256                                         NULL /*pfnInvalidateR3 */,
     257                                         CSAMCodePageWriteHandler,
     258                                         "CSAMGCCodePageWriteHandler", NULL /*pszModRC*/,
     259                                         "CSAM code page write handler",
     260                                         &pVM->csam.s.hCodePageWriteType);
     261    AssertLogRelRCReturn(rc, rc);
     262    rc = PGMR3HandlerVirtualTypeRegister(pVM, PGMVIRTHANDLERKIND_WRITE, false /*fRelocUserRC*/,
     263                                         CSAMCodePageInvalidate,
     264                                         CSAMCodePageWriteHandler,
     265                                         "CSAMGCCodePageWriteHandler", NULL /*pszModRC*/,
     266                                         "CSAM code page write and invlpg handler",
     267                                         &pVM->csam.s.hCodePageWriteAndInvPgType);
     268    AssertLogRelRCReturn(rc, rc);
     269
     270    /*
    253271     * Register save and load state notifiers.
    254272     */
     
    18551873    case CSAM_TAG_PATM:
    18561874    case CSAM_TAG_REM:
    1857 #ifdef CSAM_MONITOR_CSAM_CODE_PAGES
     1875# ifdef CSAM_MONITOR_CSAM_CODE_PAGES
    18581876    case CSAM_TAG_CSAM:
    1859 #endif
    1860     {
    1861         rc = PGMR3HandlerVirtualRegister(pVM, PGMVIRTHANDLERTYPE_WRITE, GCPtr, GCPtr + (PAGE_SIZE - 1) /* inclusive! */,
    1862                                          (fMonitorInvalidation) ? CSAMCodePageInvalidate : 0, CSAMCodePageWriteHandler, "CSAMGCCodePageWriteHandler", 0,
    1863                                          csamGetMonitorDescription(enmTag));
    1864         AssertMsg(RT_SUCCESS(rc) || rc == VERR_PGM_HANDLER_VIRTUAL_CONFLICT, ("PGMR3HandlerVirtualRegisterEx %RRv failed with %Rrc\n", GCPtr, rc));
     1877# endif
     1878    {
     1879        rc = PGMR3HandlerVirtualRegister(pVM, pVCpu, fMonitorInvalidation
     1880                                         ? pVM->csam.s.hCodePageWriteAndInvPgType : pVM->csam.s.hCodePageWriteType,
     1881                                         GCPtr, GCPtr + (PAGE_SIZE - 1) /* inclusive! */,
     1882                                         pPage, NIL_RTRCPTR, csamGetMonitorDescription(enmTag));
     1883        AssertMsg(RT_SUCCESS(rc) || rc == VERR_PGM_HANDLER_VIRTUAL_CONFLICT,
     1884                  ("PGMR3HandlerVirtualRegister %RRv failed with %Rrc\n", GCPtr, rc));
    18651885        if (RT_FAILURE(rc))
    1866             Log(("PGMR3HandlerVirtualRegisterEx for %RRv failed with %Rrc\n", GCPtr, rc));
     1886            Log(("PGMR3HandlerVirtualRegister for %RRv failed with %Rrc\n", GCPtr, rc));
    18671887
    18681888        /* Could fail, because it's already monitored. Don't treat that condition as fatal. */
     
    18851905    Log(("csamCreatePageRecord %RRv GCPhys=%RGp\n", GCPtr, pPage->page.GCPhys));
    18861906
    1887 #ifdef VBOX_WITH_STATISTICS
     1907# ifdef VBOX_WITH_STATISTICS
    18881908    switch (enmTag)
    18891909    {
     
    19001920        break; /* to shut up GCC */
    19011921    }
    1902 #endif
     1922# endif
    19031923
    19041924#endif
     
    19211941VMMR3DECL(int) CSAMR3MonitorPage(PVM pVM, RTRCPTR pPageAddrGC, CSAMTAG enmTag)
    19221942{
    1923     PCSAMPAGEREC pPageRec = NULL;
     1943    ;
    19241944    int          rc;
    19251945    bool         fMonitorInvalidation;
     
    19411961    fMonitorInvalidation = (enmTag == CSAM_TAG_PATM);
    19421962
    1943     pPageRec = (PCSAMPAGEREC)RTAvlPVGet(&pVM->csam.s.pPageTree, (AVLPVKEY)(uintptr_t)pPageAddrGC);
     1963    PCSAMPAGEREC pPageRec = (PCSAMPAGEREC)RTAvlPVGet(&pVM->csam.s.pPageTree, (AVLPVKEY)(uintptr_t)pPageAddrGC);
    19441964    if (pPageRec == NULL)
    19451965    {
     
    19721992        Log(("CSAMR3MonitorPage: activate monitoring for %RRv\n", pPageAddrGC));
    19731993
    1974         rc = PGMR3HandlerVirtualRegister(pVM, PGMVIRTHANDLERTYPE_WRITE, pPageAddrGC, pPageAddrGC + (PAGE_SIZE - 1) /* inclusive! */,
    1975                                          (fMonitorInvalidation) ? CSAMCodePageInvalidate : 0, CSAMCodePageWriteHandler, "CSAMGCCodePageWriteHandler", 0,
    1976                                          csamGetMonitorDescription(enmTag));
    1977         AssertMsg(RT_SUCCESS(rc) || rc == VERR_PGM_HANDLER_VIRTUAL_CONFLICT, ("PGMR3HandlerVirtualRegisterEx %RRv failed with %Rrc\n", pPageAddrGC, rc));
     1994        rc = PGMR3HandlerVirtualRegister(pVM, pVCpu, fMonitorInvalidation
     1995                                         ? pVM->csam.s.hCodePageWriteAndInvPgType : pVM->csam.s.hCodePageWriteType,
     1996                                         pPageAddrGC, pPageAddrGC + (PAGE_SIZE - 1) /* inclusive! */,
     1997                                         pPageRec, NIL_RTRCPTR /*pvUserRC*/, csamGetMonitorDescription(enmTag));
     1998        AssertMsg(RT_SUCCESS(rc) || rc == VERR_PGM_HANDLER_VIRTUAL_CONFLICT,
     1999                  ("PGMR3HandlerVirtualRegister %RRv failed with %Rrc\n", pPageAddrGC, rc));
    19782000        if (RT_FAILURE(rc))
    1979             Log(("PGMR3HandlerVirtualRegisterEx for %RRv failed with %Rrc\n", pPageAddrGC, rc));
     2001            Log(("PGMR3HandlerVirtualRegister for %RRv failed with %Rrc\n", pPageAddrGC, rc));
    19802002
    19812003        /* Could fail, because it's already monitored. Don't treat that condition as fatal. */
     
    19982020    {
    19992021        Assert(pPageRec->page.fMonitorActive);
    2000         PGMHandlerVirtualChangeInvalidateCallback(pVM, pPageRec->page.pPageGC, CSAMCodePageInvalidate);
     2022        rc = PGMHandlerVirtualChangeType(pVM, pPageRec->page.pPageGC, pVM->csam.s.hCodePageWriteAndInvPgType);
     2023        AssertRC(rc);
    20012024        pPageRec->page.fMonitorInvalidation = true;
    20022025        STAM_COUNTER_INC(&pVM->csam.s.StatNrPagesInv);
     
    20912114            Assert(!fInCSAMCodePageInvalidate);
    20922115            STAM_COUNTER_DEC(&pVM->csam.s.StatPageMonitor);
    2093             PGMHandlerVirtualDeregister(pVM, GCPtr);
     2116            PGMHandlerVirtualDeregister(pVM, pVCpu, GCPtr, false /*fHypervisor*/);
    20942117        }
    20952118        if (pPageRec->page.enmTag == CSAM_TAG_PATM)
  • trunk/src/VBox/VMM/VMMR3/PATM.cpp

    r54764 r55889  
    367367                          ("%RRv-%RRv => %#x\n", pVM->patm.s.pbPatchHelpersRC, RCPtrEnd, pVM->patm.s.cbPatchHelpers),
    368368                          VERR_INTERNAL_ERROR_4);
    369     return rc;
     369
     370
     371    /*
     372     * Register the virtual page access handler type.
     373     */
     374    rc = PGMR3HandlerVirtualTypeRegister(pVM, PGMVIRTHANDLERKIND_ALL, false /*fRelocUserRC*/,
     375                                         NULL /*pfnInvalidateR3*/,
     376                                         patmVirtPageHandler,
     377                                         "PATMGCMonitorPage", NULL /*pszModRC*/,
     378                                         "PATMMonitorPatchJump", &pVM->patm.s.hMonitorPageType);
     379    AssertRCReturn(rc, rc);
     380
     381    return VINF_SUCCESS;
    370382}
    371383
     
    818830
    819831                    Log(("PATM: Patch page not present -> check later!\n"));
    820                     rc = PGMR3HandlerVirtualRegister(pVM, PGMVIRTHANDLERTYPE_ALL, pPage, pPage + (PAGE_SIZE - 1) /* inclusive! */, 0, patmVirtPageHandler, "PATMGCMonitorPage", 0, "PATMMonitorPatchJump");
     832                    rc = PGMR3HandlerVirtualRegister(pVM, VMMGetCpu(pVM), pVM->patm.s.hMonitorPageType,
     833                                                     pPage,
     834                                                     pPage + (PAGE_SIZE - 1) /* inclusive! */,
     835                                                     (void *)(uintptr_t)pPage, pPage, NULL /*pszDesc*/);
    821836                    Assert(RT_SUCCESS(rc) || rc == VERR_PGM_HANDLER_VIRTUAL_CONFLICT);
    822837                }
     
    896911                {
    897912                    RTRCPTR pPage = pPatch->patch.pPrivInstrGC & PAGE_BASE_GC_MASK;
    898 
    899                     rc = PGMR3HandlerVirtualRegister(pVM, PGMVIRTHANDLERTYPE_ALL, pPage, pPage + (PAGE_SIZE - 1) /* inclusive! */, 0, patmVirtPageHandler, "PATMGCMonitorPage", 0, "PATMMonitorPatchJump");
     913                    Log(("PATM: Patch page not present -> check later!\n"));
     914                    rc = PGMR3HandlerVirtualRegister(pVM, VMMGetCpu(pVM), pVM->patm.s.hMonitorPageType,
     915                                                     pPage,
     916                                                     pPage + (PAGE_SIZE - 1) /* inclusive! */,
     917                                                     (void *)(uintptr_t)pPage, pPage, NULL /*pszDesc*/);
    900918                    Assert(RT_SUCCESS(rc) || rc == VERR_PGM_HANDLER_VIRTUAL_CONFLICT);
    901919                }
     
    66736691{
    66746692    AssertReturn(!HMIsEnabled(pVM), VERR_PATM_HM_IPE);
     6693    PVMCPU pVCpu = VMMGetCpu0(pVM);
    66756694
    66766695    RTRCPTR addr = pVM->patm.s.pvFaultMonitor;
    66776696    addr &= PAGE_BASE_GC_MASK;
    66786697
    6679     int rc = PGMHandlerVirtualDeregister(pVM, addr);
     6698    int rc = PGMHandlerVirtualDeregister(pVM, pVCpu, addr, false /*fHypervisor*/);
    66806699    AssertRC(rc); NOREF(rc);
    66816700
  • trunk/src/VBox/VMM/VMMR3/PATMSSM.cpp

    r54764 r55889  
    14791479            {
    14801480                RTRCPTR pPage = pPatch->pPrivInstrGC & PAGE_BASE_GC_MASK;
    1481 
    1482                 rc = PGMR3HandlerVirtualRegister(pVM, PGMVIRTHANDLERTYPE_ALL, pPage, pPage + (PAGE_SIZE - 1) /* inclusive! */, 0, patmVirtPageHandler, "PATMGCMonitorPage", 0, "PATMMonitorPatchJump");
     1481                rc = PGMR3HandlerVirtualRegister(pVM, VMMGetCpu(pVM), pVM->patm.s.hMonitorPageType,
     1482                                                 pPage,
     1483                                                 pPage + (PAGE_SIZE - 1) /* inclusive! */,
     1484                                                 (void *)(uintptr_t)pPage, pPage, NULL /*pszDesc*/);
    14831485                Assert(RT_SUCCESS(rc) || rc == VERR_PGM_HANDLER_VIRTUAL_CONFLICT);
    14841486            }
     
    15211523
    15221524    }
    1523 }
     1525    }
    15241526    return VINF_SUCCESS;
    15251527}
  • trunk/src/VBox/VMM/VMMR3/PGM.cpp

    r55503 r55889  
    55
    66/*
    7  * Copyright (C) 2006-2013 Oracle Corporation
     7 * Copyright (C) 2006-2015 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    164164 *
    165165 * We currently implement three types of virtual access handlers:  ALL, WRITE
    166  * and HYPERVISOR (WRITE). See PGMVIRTHANDLERTYPE for some more details.
     166 * and HYPERVISOR (WRITE). See PGMVIRTHANDLERKIND for some more details.
    167167 *
    168168 * The HYPERVISOR access handlers is kept in a separate tree since it doesn't apply
     
    646646#include <iprt/string.h>
    647647#include <iprt/thread.h>
     648
     649
     650/*******************************************************************************
     651*   Structures and Typedefs                                                    *
     652*******************************************************************************/
     653/**
     654 * Argument package for pgmR3RElocatePhysHnadler, pgmR3RelocateVirtHandler and
     655 * pgmR3RelocateHyperVirtHandler.
     656 */
     657typedef struct PGMRELOCHANDLERARGS
     658{
     659    RTGCINTPTR  offDelta;
     660    PVM         pVM;
     661} PGMRELOCHANDLERARGS;
     662/** Pointer to a page access handlere relocation argument package. */
     663typedef PGMRELOCHANDLERARGS const *PCPGMRELOCHANDLERARGS;
    648664
    649665
     
    24072423     * Physical and virtual handlers.
    24082424     */
    2409     RTAvlroGCPhysDoWithAll(&pVM->pgm.s.pTreesR3->PhysHandlers,     true, pgmR3RelocatePhysHandler,      &offDelta);
     2425    PGMRELOCHANDLERARGS Args = { offDelta, pVM };
     2426    RTAvlroGCPhysDoWithAll(&pVM->pgm.s.pTreesR3->PhysHandlers,     true, pgmR3RelocatePhysHandler,      &Args);
    24102427    pVM->pgm.s.pLastPhysHandlerRC = NIL_RTRCPTR;
    24112428
     
    24132430    RTListOff32ForEach(&pVM->pgm.s.pTreesR3->HeadPhysHandlerTypes, pCurPhysType, PGMPHYSHANDLERTYPEINT, ListNode)
    24142431    {
    2415         if (pCurPhysType->pfnHandlerRC)
     2432        if (pCurPhysType->pfnHandlerRC != NIL_RTRCPTR)
    24162433            pCurPhysType->pfnHandlerRC += offDelta;
    24172434    }
    24182435
    2419     RTAvlroGCPtrDoWithAll(&pVM->pgm.s.pTreesR3->VirtHandlers,      true, pgmR3RelocateVirtHandler,      &offDelta);
    2420     RTAvlroGCPtrDoWithAll(&pVM->pgm.s.pTreesR3->HyperVirtHandlers, true, pgmR3RelocateHyperVirtHandler, &offDelta);
     2436    RTAvlroGCPtrDoWithAll(&pVM->pgm.s.pTreesR3->VirtHandlers,      true, pgmR3RelocateVirtHandler,      &Args);
     2437    RTAvlroGCPtrDoWithAll(&pVM->pgm.s.pTreesR3->HyperVirtHandlers, true, pgmR3RelocateHyperVirtHandler, &Args);
     2438
     2439    PPGMVIRTHANDLERTYPEINT pCurVirtType;
     2440    RTListOff32ForEach(&pVM->pgm.s.pTreesR3->HeadVirtHandlerTypes, pCurVirtType, PGMVIRTHANDLERTYPEINT, ListNode)
     2441    {
     2442        if (pCurVirtType->pfnHandlerRC != NIL_RTRCPTR)
     2443            pCurVirtType->pfnHandlerRC += offDelta;
     2444    }
    24212445
    24222446    /*
     
    24412465 * @returns 0 (continue enum)
    24422466 * @param   pNode       Pointer to a PGMPHYSHANDLER node.
    2443  * @param   pvUser      Pointer to the offDelta. This is a pointer to the delta since we're
    2444  *                      not certain the delta will fit in a void pointer for all possible configs.
     2467 * @param   pvUser      Pointer to a PGMRELOCHANDLERARGS.
    24452468 */
    24462469static DECLCALLBACK(int) pgmR3RelocatePhysHandler(PAVLROGCPHYSNODECORE pNode, void *pvUser)
    24472470{
    2448     PPGMPHYSHANDLER pHandler = (PPGMPHYSHANDLER)pNode;
    2449     RTGCINTPTR      offDelta = *(PRTGCINTPTR)pvUser;
     2471    PPGMPHYSHANDLER         pHandler = (PPGMPHYSHANDLER)pNode;
     2472    PCPGMRELOCHANDLERARGS   pArgs    = (PCPGMRELOCHANDLERARGS)pvUser;
    24502473    if (pHandler->pvUserRC >= 0x10000)
    2451         pHandler->pvUserRC += offDelta;
     2474        pHandler->pvUserRC += pArgs->offDelta;
    24522475    return 0;
    24532476}
     
    24592482 * @returns 0 (continue enum)
    24602483 * @param   pNode       Pointer to a PGMVIRTHANDLER node.
    2461  * @param   pvUser      Pointer to the offDelta. This is a pointer to the delta since we're
    2462  *                      not certain the delta will fit in a void pointer for all possible configs.
     2484 * @param   pvUser      Pointer to a PGMRELOCHANDLERARGS.
    24632485 */
    24642486static DECLCALLBACK(int) pgmR3RelocateVirtHandler(PAVLROGCPTRNODECORE pNode, void *pvUser)
    24652487{
    2466     PPGMVIRTHANDLER pHandler = (PPGMVIRTHANDLER)pNode;
    2467     RTGCINTPTR      offDelta = *(PRTGCINTPTR)pvUser;
    2468     Assert(     pHandler->enmType == PGMVIRTHANDLERTYPE_ALL
    2469            ||   pHandler->enmType == PGMVIRTHANDLERTYPE_WRITE);
    2470     Assert(pHandler->pfnHandlerRC);
    2471     pHandler->pfnHandlerRC += offDelta;
     2488    PPGMVIRTHANDLER         pHandler = (PPGMVIRTHANDLER)pNode;
     2489    PCPGMRELOCHANDLERARGS   pArgs    = (PCPGMRELOCHANDLERARGS)pvUser;
     2490    Assert(PGMVIRTANDLER_GET_TYPE(pArgs->pVM, pHandler)->enmKind != PGMVIRTHANDLERKIND_HYPERVISOR);
     2491
     2492    if (   pHandler->pvUserRC != NIL_RTRCPTR
     2493        && PGMVIRTANDLER_GET_TYPE(pArgs->pVM, pHandler)->fRelocUserRC)
     2494        pHandler->pvUserRC += pArgs->offDelta;
    24722495    return 0;
    24732496}
     
    24792502 * @returns 0 (continue enum)
    24802503 * @param   pNode       Pointer to a PGMVIRTHANDLER node.
    2481  * @param   pvUser      Pointer to the offDelta. This is a pointer to the delta since we're
    2482  *                      not certain the delta will fit in a void pointer for all possible configs.
     2504 * @param   pvUser      Pointer to a PGMRELOCHANDLERARGS.
    24832505 */
    24842506static DECLCALLBACK(int) pgmR3RelocateHyperVirtHandler(PAVLROGCPTRNODECORE pNode, void *pvUser)
    24852507{
    2486     PPGMVIRTHANDLER pHandler = (PPGMVIRTHANDLER)pNode;
    2487     RTGCINTPTR      offDelta = *(PRTGCINTPTR)pvUser;
    2488     Assert(pHandler->enmType == PGMVIRTHANDLERTYPE_HYPERVISOR);
    2489     Assert(pHandler->pfnHandlerRC);
    2490     pHandler->pfnHandlerRC  += offDelta;
     2508    PPGMVIRTHANDLER         pHandler = (PPGMVIRTHANDLER)pNode;
     2509    PCPGMRELOCHANDLERARGS   pArgs    = (PCPGMRELOCHANDLERARGS)pvUser;
     2510    Assert(PGMVIRTANDLER_GET_TYPE(pArgs->pVM, pHandler)->enmKind == PGMVIRTHANDLERKIND_HYPERVISOR);
     2511
     2512    if (   pHandler->pvUserRC != NIL_RTRCPTR
     2513        && PGMVIRTANDLER_GET_TYPE(pArgs->pVM, pHandler)->fRelocUserRC)
     2514        pHandler->pvUserRC += pArgs->offDelta;
    24912515    return 0;
    24922516}
  • trunk/src/VBox/VMM/VMMR3/PGMHandler.cpp

    r55493 r55889  
    55
    66/*
    7  * Copyright (C) 2006-2012 Oracle Corporation
     7 * Copyright (C) 2006-2015 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    7979 *                          safe).
    8080 */
    81 VMM_INT_DECL(int) PGMR3HandlerPhysicalTypeRegisterEx(PVM pVM, PGMPHYSHANDLERKIND enmKind,
    82                                                      PFNPGMR3PHYSHANDLER pfnHandlerR3,
    83                                                      R0PTRTYPE(PFNPGMR0PHYSHANDLER) pfnHandlerR0,
    84                                                      RCPTRTYPE(PFNPGMRCPHYSHANDLER) pfnHandlerRC,
    85                                                      const char *pszDesc, PPGMPHYSHANDLERTYPE phType)
     81VMMR3_INT_DECL(int) PGMR3HandlerPhysicalTypeRegisterEx(PVM pVM, PGMPHYSHANDLERKIND enmKind,
     82                                                       PFNPGMR3PHYSHANDLER pfnHandlerR3,
     83                                                       R0PTRTYPE(PFNPGMR0PHYSHANDLER) pfnHandlerR0,
     84                                                       RCPTRTYPE(PFNPGMRCPHYSHANDLER) pfnHandlerRC,
     85                                                       const char *pszDesc, PPGMPHYSHANDLERTYPE phType)
    8686{
    8787    AssertPtrReturn(pfnHandlerR3, VERR_INVALID_POINTER);
     
    273273
    274274/**
     275 * Register a virtual page access handler type, extended version.
     276 *
     277 * @returns VBox status code.
     278 * @param   pVM             Pointer to the cross context VM structure.
     279 * @param   enmKind         The kind of access handler.
     280 * @param   fRelocUserRC    Whether the pvUserRC argument should be
     281 *                          automatically relocated or not.
     282 * @param   pfnInvalidateR3 Pointer to the ring-3 invalidation handler callback.
     283 * @param   pfnHandlerR3    Pointer to the ring-3 handler callback.
     284 * @param   pfnHandlerRC    Pointer to the raw-mode context handler callback.
     285 * @param   pszDesc         The type description.
     286 * @param   phType          Where to return the type handle (cross context
     287 *                          safe).
     288 * @remarks No virtual handlers when executing using HM (i.e. ring-0).
     289 */
     290VMMR3_INT_DECL(int) PGMR3HandlerVirtualTypeRegisterEx(PVM pVM, PGMVIRTHANDLERKIND enmKind, bool fRelocUserRC,
     291                                                      PFNPGMR3VIRTINVALIDATE pfnInvalidateR3,
     292                                                      PFNPGMR3VIRTHANDLER pfnHandlerR3,
     293                                                      RCPTRTYPE(PFNPGMRCVIRTHANDLER) pfnHandlerRC,
     294                                                      const char *pszDesc, PPGMVIRTHANDLERTYPE phType)
     295{
     296    AssertReturn(!HMIsEnabled(pVM), VERR_NOT_AVAILABLE); /* Not supported/relevant for VT-x and AMD-V. */
     297    AssertReturn(RT_VALID_PTR(pfnHandlerR3) || enmKind == PGMVIRTHANDLERKIND_HYPERVISOR, VERR_INVALID_POINTER);
     298    AssertPtrNullReturn(pfnInvalidateR3, VERR_INVALID_POINTER);
     299    AssertReturn(pfnHandlerRC != NIL_RTRCPTR, VERR_INVALID_POINTER);
     300    AssertPtrReturn(pszDesc, VERR_INVALID_POINTER);
     301    AssertReturn(   enmKind == PGMVIRTHANDLERKIND_WRITE
     302                 || enmKind == PGMVIRTHANDLERKIND_ALL
     303                 || enmKind == PGMVIRTHANDLERKIND_HYPERVISOR,
     304                 VERR_INVALID_PARAMETER);
     305
     306    PPGMVIRTHANDLERTYPEINT pType;
     307    int rc = MMHyperAlloc(pVM, sizeof(*pType), 0, MM_TAG_PGM_HANDLER_TYPES, (void **)&pType);
     308    if (RT_SUCCESS(rc))
     309    {
     310        pType->u32Magic         = PGMVIRTHANDLERTYPEINT_MAGIC;
     311        pType->cRefs            = 1;
     312        pType->enmKind          = enmKind;
     313        pType->fRelocUserRC     = fRelocUserRC;
     314        pType->uState           = enmKind == PGMVIRTHANDLERKIND_ALL
     315                                ? PGM_PAGE_HNDL_VIRT_STATE_ALL : PGM_PAGE_HNDL_VIRT_STATE_WRITE;
     316        pType->pfnInvalidateR3  = pfnInvalidateR3;
     317        pType->pfnHandlerR3     = pfnHandlerR3;
     318        pType->pfnHandlerRC     = pfnHandlerRC;
     319        pType->pszDesc          = pszDesc;
     320
     321        pgmLock(pVM);
     322        RTListOff32Append(&pVM->pgm.s.CTX_SUFF(pTrees)->HeadVirtHandlerTypes, &pType->ListNode);
     323        pgmUnlock(pVM);
     324
     325        *phType = MMHyperHeapPtrToOffset(pVM, pType);
     326        LogFlow(("PGMR3HandlerVirtualTypeRegisterEx: %p/%#x: enmKind=%d pfnInvalidateR3=%RHv pfnHandlerR3=%RHv pfnHandlerRC=%RRv pszDesc=%s\n",
     327                 pType, *phType, enmKind, pfnInvalidateR3, pfnHandlerR3, pfnHandlerRC, pszDesc));
     328        return VINF_SUCCESS;
     329    }
     330    *phType = NIL_PGMVIRTHANDLERTYPE;
     331    return rc;
     332}
     333
     334
     335/**
     336 * Register a physical page access handler type.
     337 *
     338 * @returns VBox status code.
     339 * @param   pVM             Pointer to the cross context VM structure.
     340 * @param   enmKind         The kind of access handler.
     341 * @param   fRelocUserRC    Whether the pvUserRC argument should be
     342 *                          automatically relocated or not.
     343 * @param   pfnInvalidateR3 Pointer to the ring-3 invalidateion callback
     344 *                          (optional, can be NULL).
     345 * @param   pfnHandlerR3    Pointer to the ring-3 handler callback.
     346 * @param   pszModRC        The name of the raw-mode context module, NULL is an
     347 *                          alias for the main RC module.
     348 * @param   pszHandlerRC    The name of the raw-mode context handler, NULL if
     349 *                          the ring-3 handler should be called.
     350 * @param   pszDesc         The type description.
     351 * @param   phType          Where to return the type handle (cross context
     352 *                          safe).
     353 * @remarks No virtual handlers when executing using HM (i.e. ring-0).
     354 */
     355VMMR3_INT_DECL(int) PGMR3HandlerVirtualTypeRegister(PVM pVM, PGMVIRTHANDLERKIND enmKind, bool fRelocUserRC,
     356                                                    PFNPGMR3VIRTINVALIDATE pfnInvalidateR3,
     357                                                    PFNPGMR3VIRTHANDLER pfnHandlerR3,
     358                                                    const char *pszHandlerRC, const char *pszModRC, const char *pszDesc,
     359                                                    PPGMVIRTHANDLERTYPE phType)
     360{
     361    LogFlow(("PGMR3HandlerVirtualTypeRegister: enmKind=%d pfnInvalidateR3=%RHv pfnHandlerR3=%RHv pszModRC=%s pszHandlerRC=%s pszDesc=%s\n",
     362             enmKind, pfnInvalidateR3, pfnHandlerR3, pszHandlerRC, pszModRC, pszDesc));
     363
     364    /*
     365     * Validate input.
     366     */
     367    if (!pszModRC)
     368        pszModRC = VMMGC_MAIN_MODULE_NAME;
     369    if (!pszHandlerRC)
     370        pszHandlerRC = "pgmVirtHandlerRedirectToHC";
     371    AssertPtrReturn(pszHandlerRC, VERR_INVALID_POINTER);
     372
     373    /*
     374     * Resolve the GC handler.
     375     */
     376    RTRCPTR pfnHandlerRC = NIL_RTRCPTR;
     377    int rc = PDMR3LdrGetSymbolRCLazy(pVM, pszModRC, NULL /*pszSearchPath*/, pszHandlerRC, &pfnHandlerRC);
     378    if (RT_SUCCESS(rc))
     379        return PGMR3HandlerVirtualTypeRegisterEx(pVM, enmKind, fRelocUserRC,
     380                                                 pfnInvalidateR3, pfnHandlerR3,
     381                                                 pfnHandlerRC,
     382                                                 pszDesc, phType);
     383
     384    AssertMsgFailed(("Failed to resolve %s.%s, rc=%Rrc.\n", pszModRC, pszHandlerRC, rc));
     385    return rc;
     386}
     387
     388
     389/**
    275390 * Register a access handler for a virtual range.
    276391 *
    277392 * @returns VBox status code.
    278393 * @param   pVM             Pointer to the VM.
    279  * @param   enmType         Handler type. Any of the PGMVIRTHANDLERTYPE_* enums.
     394 * @param   hType           The handler type.
    280395 * @param   GCPtr           Start address.
    281396 * @param   GCPtrLast       Last address (inclusive).
    282  * @param   pfnInvalidateR3 The R3 invalidate callback (can be 0)
    283  * @param   pfnHandlerR3    The R3 handler.
    284  * @param   pszHandlerRC    The RC handler symbol name.
    285  * @param   pszModRC        The RC handler module.
     397 * @param   pvUserR3        The ring-3 context user argument.
     398 * @param   pvUserRC        The raw-mode context user argument.  Whether this is
     399 *                          automatically relocated or not depends on the type.
    286400 * @param   pszDesc         Pointer to description string. This must not be freed.
    287401 */
    288 VMMR3DECL(int) PGMR3HandlerVirtualRegister(PVM pVM, PGMVIRTHANDLERTYPE enmType, RTGCPTR GCPtr, RTGCPTR GCPtrLast,
    289                                            PFNPGMR3VIRTINVALIDATE pfnInvalidateR3,
    290                                            PFNPGMR3VIRTHANDLER pfnHandlerR3,
    291                                            const char *pszHandlerRC, const char *pszModRC,
    292                                            const char *pszDesc)
    293 {
    294     LogFlow(("PGMR3HandlerVirtualRegisterEx: enmType=%d GCPtr=%RGv GCPtrLast=%RGv pszHandlerRC=%p:{%s} pszModRC=%p:{%s} pszDesc=%s\n",
    295              enmType, GCPtr, GCPtrLast, pszHandlerRC, pszHandlerRC, pszModRC, pszModRC, pszDesc));
    296 
    297     /* Not supported/relevant for VT-x and AMD-V. */
    298     if (HMIsEnabled(pVM))
    299         return VERR_NOT_IMPLEMENTED;
     402VMMR3_INT_DECL(int) PGMR3HandlerVirtualRegister(PVM pVM, PVMCPU pVCpu, PGMVIRTHANDLERTYPE hType, RTGCPTR GCPtr, RTGCPTR GCPtrLast,
     403                                                void *pvUserR3, RTRCPTR pvUserRC, const char *pszDesc)
     404{
     405    AssertReturn(!HMIsEnabled(pVM), VERR_NOT_AVAILABLE); /* Not supported/relevant for VT-x and AMD-V. */
     406    PPGMVIRTHANDLERTYPEINT pType = PGMVIRTHANDLERTYPEINT_FROM_HANDLE(pVM, hType);
     407    Log(("PGMR3HandlerVirtualRegister: GCPhys=%RGp GCPhysLast=%RGp pvUserR3=%RHv pvUserGC=%RRv hType=%#x (%d, %s) pszDesc=%RHv:%s\n",
     408         GCPtr, GCPtrLast, pvUserR3, pvUserRC, hType, pType->enmKind, R3STRING(pType->pszDesc), pszDesc, R3STRING(pszDesc)));
    300409
    301410    /*
    302411     * Validate input.
    303412     */
    304     if (!pszModRC)
    305         pszModRC = VMMGC_MAIN_MODULE_NAME;
    306     if (!pszModRC || !*pszModRC || !pszHandlerRC || !*pszHandlerRC)
    307     {
    308         AssertMsgFailed(("pfnHandlerGC or/and pszModRC is missing\n"));
    309         return VERR_INVALID_PARAMETER;
    310     }
    311 
    312     /*
    313      * Resolve the GC handler.
    314      */
    315     RTRCPTR pfnHandlerRC;
    316     int rc = PDMR3LdrGetSymbolRCLazy(pVM, pszModRC, NULL /*pszSearchPath*/, pszHandlerRC, &pfnHandlerRC);
    317     if (RT_SUCCESS(rc))
    318         return PGMR3HandlerVirtualRegisterEx(pVM, enmType, GCPtr, GCPtrLast, pfnInvalidateR3,
    319                                              pfnHandlerR3, pfnHandlerRC, pszDesc);
    320 
    321     AssertMsgFailed(("Failed to resolve %s.%s, rc=%Rrc.\n", pszModRC, pszHandlerRC, rc));
    322     return rc;
    323 }
    324 
    325 
    326 /**
    327  * Register an access handler for a virtual range.
    328  *
    329  * @returns VBox status code.
    330  * @param   pVM             Pointer to the VM.
    331  * @param   enmType         Handler type. Any of the PGMVIRTHANDLERTYPE_* enums.
    332  * @param   GCPtr           Start address.
    333  * @param   GCPtrLast       Last address (inclusive).
    334  * @param   pfnInvalidateR3 The R3 invalidate callback (can be 0)
    335  * @param   pfnHandlerR3    The R3 handler.
    336  * @param   pfnHandlerRC    The RC handler.
    337  * @param   pszDesc         Pointer to description string. This must not be freed.
    338  * @thread  EMT
    339  */
    340 /** @todo create a template for virtual handlers (see async i/o), we're wasting space
    341  * duplicating the function pointers now. (Or we will once we add the missing callbacks.) */
    342 VMMDECL(int) PGMR3HandlerVirtualRegisterEx(PVM pVM, PGMVIRTHANDLERTYPE enmType, RTGCPTR GCPtr, RTGCPTR GCPtrLast,
    343                                            R3PTRTYPE(PFNPGMR3VIRTINVALIDATE) pfnInvalidateR3,
    344                                            R3PTRTYPE(PFNPGMR3VIRTHANDLER) pfnHandlerR3,
    345                                            RCPTRTYPE(PFNPGMRCVIRTHANDLER) pfnHandlerRC,
    346                                            R3PTRTYPE(const char *) pszDesc)
    347 {
    348     Log(("PGMR3HandlerVirtualRegister: enmType=%d GCPtr=%RGv GCPtrLast=%RGv pfnInvalidateR3=%RHv pfnHandlerR3=%RHv pfnHandlerRC=%RRv pszDesc=%s\n",
    349          enmType, GCPtr, GCPtrLast, pfnInvalidateR3, pfnHandlerR3, pfnHandlerRC, pszDesc));
    350 
    351     /* Not supported/relevant for VT-x and AMD-V. */
    352     if (HMIsEnabled(pVM))
    353         return VERR_NOT_IMPLEMENTED;
    354 
    355     /*
    356      * Validate input.
    357      */
    358     switch (enmType)
    359     {
    360         case PGMVIRTHANDLERTYPE_ALL:
     413    AssertReturn(pType->u32Magic == PGMVIRTHANDLERTYPEINT_MAGIC, VERR_INVALID_HANDLE);
     414    AssertMsgReturn(GCPtr < GCPtrLast, ("GCPtr >= GCPtrLast (%RGp >= %RGp)\n", GCPtr, GCPtrLast), VERR_INVALID_PARAMETER);
     415    switch (pType->enmKind)
     416    {
     417        case PGMVIRTHANDLERKIND_ALL:
    361418            AssertReleaseMsgReturn(   (GCPtr     & PAGE_OFFSET_MASK) == 0
    362419                                   && (GCPtrLast & PAGE_OFFSET_MASK) == PAGE_OFFSET_MASK,
    363                                    ("PGMVIRTHANDLERTYPE_ALL: GCPtr=%RGv GCPtrLast=%RGv\n", GCPtr, GCPtrLast),
     420                                   ("PGMVIRTHANDLERKIND_ALL: GCPtr=%RGv GCPtrLast=%RGv\n", GCPtr, GCPtrLast),
    364421                                   VERR_NOT_IMPLEMENTED);
    365422            break;
    366         case PGMVIRTHANDLERTYPE_WRITE:
    367             if (!pfnHandlerR3)
    368             {
    369                 AssertMsgFailed(("No HC handler specified!!\n"));
    370                 return VERR_INVALID_PARAMETER;
    371             }
    372             break;
    373 
    374         case PGMVIRTHANDLERTYPE_HYPERVISOR:
    375             if (pfnHandlerR3)
    376             {
    377                 AssertMsgFailed(("R3 handler specified for hypervisor range!?!\n"));
    378                 return VERR_INVALID_PARAMETER;
    379             }
     423        case PGMVIRTHANDLERKIND_WRITE:
     424        case PGMVIRTHANDLERKIND_HYPERVISOR:
    380425            break;
    381426        default:
    382             AssertMsgFailed(("Invalid enmType! enmType=%d\n", enmType));
    383             return VERR_INVALID_PARAMETER;
    384     }
    385     if (GCPtrLast < GCPtr)
    386     {
    387         AssertMsgFailed(("GCPtrLast < GCPtr (%#x < %#x)\n", GCPtrLast, GCPtr));
    388         return VERR_INVALID_PARAMETER;
    389     }
    390     if (!pfnHandlerRC)
    391     {
    392         AssertMsgFailed(("pfnHandlerRC is missing\n"));
    393         return VERR_INVALID_PARAMETER;
    394     }
     427            AssertMsgFailedReturn(("Invalid enmKind=%d!\n", pType->enmKind), VERR_INVALID_PARAMETER);
     428    }
     429    AssertMsgReturn(   (RTRCUINTPTR)pvUserRC < 0x10000
     430                    || MMHyperR3ToRC(pVM, MMHyperRCToR3(pVM, pvUserRC)) == pvUserRC,
     431                    ("Not RC pointer! pvUserRC=%RRv\n", pvUserRC),
     432                    VERR_INVALID_PARAMETER);
    395433
    396434    /*
     
    406444    pNew->Core.KeyLast  = GCPtrLast;
    407445
    408     pNew->enmType       = enmType;
    409     pNew->pfnInvalidateR3 = pfnInvalidateR3;
    410     pNew->pfnHandlerRC  = pfnHandlerRC;
    411     pNew->pfnHandlerR3  = pfnHandlerR3;
    412     pNew->pszDesc       = pszDesc;
     446    pNew->hType         = hType;
     447    pNew->pvUserRC      = pvUserRC;
     448    pNew->pvUserR3      = pvUserR3;
     449    pNew->pszDesc       = pszDesc ? pszDesc : pType->pszDesc;
    413450    pNew->cb            = GCPtrLast - GCPtr + 1;
    414451    pNew->cPages        = cPages;
     
    428465     * the same range this makes everything much simpler and faster.
    429466     */
    430     AVLROGCPTRTREE *pRoot = enmType != PGMVIRTHANDLERTYPE_HYPERVISOR
     467    AVLROGCPTRTREE *pRoot = pType->enmKind != PGMVIRTHANDLERKIND_HYPERVISOR
    431468                          ? &pVM->pgm.s.CTX_SUFF(pTrees)->VirtHandlers
    432469                          : &pVM->pgm.s.CTX_SUFF(pTrees)->HyperVirtHandlers;
     
    456493    if (RTAvlroGCPtrInsert(pRoot, &pNew->Core))
    457494    {
    458         if (enmType != PGMVIRTHANDLERTYPE_HYPERVISOR)
     495        if (pType->enmKind != PGMVIRTHANDLERKIND_HYPERVISOR)
    459496        {
    460497            PVMCPU pVCpu = VMMGetCpu(pVM);
     
    463500            VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
    464501        }
     502        PGMHandlerVirtualTypeRetain(pVM, hType);
    465503        pgmUnlock(pVM);
    466504
    467505#ifdef VBOX_WITH_STATISTICS
    468         rc = STAMR3RegisterF(pVM, &pNew->Stat, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL, pszDesc,
     506        rc = STAMR3RegisterF(pVM, &pNew->Stat, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL, pNew->pszDesc,
    469507                             "/PGM/VirtHandler/Calls/%RGv-%RGv", pNew->Core.Key, pNew->Core.KeyLast);
    470508        AssertRC(rc);
     
    477515    MMHyperFree(pVM, pNew);
    478516    return VERR_PGM_HANDLER_VIRTUAL_CONFLICT;
    479 }
    480 
    481 
    482 /**
    483  * Modify the page invalidation callback handler for a registered virtual range.
    484  * (add more when needed)
     517
     518}
     519
     520
     521/**
     522 * Changes the type of a virtual handler.
     523 *
     524 * The new and old type must have the same access kind.
    485525 *
    486526 * @returns VBox status code.
    487527 * @param   pVM             Pointer to the VM.
    488  * @param   GCPtr           Start address.
    489  * @param   pfnInvalidateR3 The R3 invalidate callback (can be 0)
    490  * @remarks Doesn't work with the hypervisor access handler type.
    491  */
    492 VMMDECL(int) PGMHandlerVirtualChangeInvalidateCallback(PVM pVM, RTGCPTR GCPtr, PFNPGMR3VIRTINVALIDATE pfnInvalidateR3)
    493 {
     528 * @param   GCPtr           Start address of the virtual handler.
     529 * @param   hNewType        The new handler type.
     530 */
     531VMMR3_INT_DECL(int) PGMHandlerVirtualChangeType(PVM pVM, RTGCPTR GCPtr, PGMVIRTHANDLERTYPE hNewType)
     532{
     533    PPGMVIRTHANDLERTYPEINT pNewType = PGMVIRTHANDLERTYPEINT_FROM_HANDLE(pVM, hNewType);
     534    AssertReturn(pNewType->u32Magic == PGMVIRTHANDLERTYPEINT_MAGIC, VERR_INVALID_HANDLE);
     535
    494536    pgmLock(pVM);
    495537    PPGMVIRTHANDLER pCur = (PPGMVIRTHANDLER)RTAvlroGCPtrGet(&pVM->pgm.s.pTreesR3->VirtHandlers, GCPtr);
    496538    if (pCur)
    497539    {
    498         pCur->pfnInvalidateR3 = pfnInvalidateR3;
     540        PGMVIRTHANDLERTYPE     hOldType = pCur->hType;
     541        PPGMVIRTHANDLERTYPEINT pOldType = PGMVIRTHANDLERTYPEINT_FROM_HANDLE(pVM, hOldType);
     542        if (pOldType != pNewType)
     543        {
     544            AssertReturnStmt(pNewType->enmKind == pOldType->enmKind, pgmUnlock(pVM), VERR_ACCESS_DENIED);
     545            PGMHandlerVirtualTypeRetain(pVM, hNewType);
     546            pCur->hType = hNewType;
     547            PGMHandlerVirtualTypeRelease(pVM, hOldType);
     548        }
    499549        pgmUnlock(pVM);
    500550        return VINF_SUCCESS;
     
    505555}
    506556
     557
    507558/**
    508559 * Deregister an access handler for a virtual range.
     
    510561 * @returns VBox status code.
    511562 * @param   pVM         Pointer to the VM.
     563 * @param   pVCpu       Pointer to the cross context CPU structure for the
     564 *                      calling EMT.
    512565 * @param   GCPtr       Start address.
    513  * @thread  EMT
    514  */
    515 VMMDECL(int) PGMHandlerVirtualDeregister(PVM pVM, RTGCPTR GCPtr)
     566 * @param   fHypervisor Set if PGMVIRTHANDLERKIND_HYPERVISOR, false if not.
     567 * @thread  EMT(pVCpu)
     568 */
     569VMM_INT_DECL(int) PGMHandlerVirtualDeregister(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, bool fHypervisor)
    516570{
    517571    pgmLock(pVM);
    518572
    519     /*
    520      * Find the handler.
    521      * We naturally assume GCPtr is a unique specification.
    522      */
    523     PPGMVIRTHANDLER pCur = (PPGMVIRTHANDLER)RTAvlroGCPtrRemove(&pVM->pgm.s.CTX_SUFF(pTrees)->VirtHandlers, GCPtr);
    524     if (RT_LIKELY(pCur))
    525     {
    526         Log(("PGMHandlerVirtualDeregister: Removing Virtual (%d) Range %RGv-%RGv %s\n", pCur->enmType,
    527              pCur->Core.Key, pCur->Core.KeyLast, pCur->pszDesc));
    528         Assert(pCur->enmType != PGMVIRTHANDLERTYPE_HYPERVISOR);
    529 
     573    PPGMVIRTHANDLER pCur;
     574    if (!fHypervisor)
     575    {
    530576        /*
    531          * Reset the flags and remove phys2virt nodes.
     577         * Normal guest handler.
    532578         */
     579        pCur = (PPGMVIRTHANDLER)RTAvlroGCPtrRemove(&pVM->pgm.s.CTX_SUFF(pTrees)->VirtHandlers, GCPtr);
     580        AssertMsgReturnStmt(pCur, ("GCPtr=%RGv\n", GCPtr), pgmUnlock(pVM), VERR_INVALID_PARAMETER);
     581        Assert(PGMVIRTANDLER_GET_TYPE(pVM, pCur)->enmKind != PGMVIRTHANDLERKIND_HYPERVISOR);
     582
     583        Log(("PGMHandlerVirtualDeregister: Removing Virtual (%d) Range %RGv-%RGv %s\n",
     584             PGMVIRTANDLER_GET_TYPE(pVM, pCur)->enmKind, pCur->Core.Key, pCur->Core.KeyLast, pCur->pszDesc));
     585
     586        /* Reset the flags and remove phys2virt nodes. */
    533587        for (uint32_t iPage = 0; iPage < pCur->cPages; iPage++)
    534588            if (pCur->aPhysToVirt[iPage].offNextAlias & PGMPHYS2VIRTHANDLER_IN_TREE)
    535589                pgmHandlerVirtualClearPage(pVM, pCur, iPage);
    536590
    537         /*
    538          * Schedule CR3 sync.
    539          */
    540         PVMCPU pVCpu = VMMGetCpu(pVM);
    541 
     591        /* Schedule CR3 sync. */
    542592        pVCpu->pgm.s.fSyncFlags |= PGM_SYNC_UPDATE_PAGE_BIT_VIRTUAL | PGM_SYNC_CLEAR_PGM_POOL;
    543593        VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
     
    545595    else
    546596    {
    547         /* must be a hypervisor one then. */
     597        /*
     598         * Hypervisor one (hypervisor relocation or termination only).
     599         */
    548600        pCur = (PPGMVIRTHANDLER)RTAvlroGCPtrRemove(&pVM->pgm.s.CTX_SUFF(pTrees)->HyperVirtHandlers, GCPtr);
    549         if (RT_UNLIKELY(!pCur))
    550         {
    551             pgmUnlock(pVM);
    552 #ifndef DEBUG_sander
    553             AssertMsgFailed(("Range %#x not found!\n", GCPtr));
    554 #endif
    555             return VERR_INVALID_PARAMETER;
    556         }
    557 
    558         Log(("PGMHandlerVirtualDeregister: Removing Hyper Virtual (%d) Range %RGv-%RGv %s\n", pCur->enmType,
     601        AssertMsgReturnStmt(pCur, ("GCPtr=%RGv\n", GCPtr), pgmUnlock(pVM), VERR_INVALID_PARAMETER);
     602        Assert(PGMVIRTANDLER_GET_TYPE(pVM, pCur)->enmKind == PGMVIRTHANDLERKIND_HYPERVISOR);
     603
     604        Log(("PGMHandlerVirtualDeregister: Removing Hyper Virtual Range %RGv-%RGv %s\n",
    559605             pCur->Core.Key, pCur->Core.KeyLast, pCur->pszDesc));
    560         Assert(pCur->enmType == PGMVIRTHANDLERTYPE_HYPERVISOR);
    561606    }
    562607
    563608    pgmUnlock(pVM);
    564609
     610    /*
     611     * Free it.
     612     */
    565613#ifdef VBOX_WITH_STATISTICS
    566614    STAMR3DeregisterF(pVM->pUVM, "/PGM/VirtHandler/Calls/%RGv-%RGv", pCur->Core.Key, pCur->Core.KeyLast);
    567615#endif
     616    PGMHandlerVirtualTypeRelease(pVM, pCur->hType);
    568617    MMHyperFree(pVM, pCur);
    569618
     
    696745static DECLCALLBACK(int) pgmR3InfoHandlersVirtualOne(PAVLROGCPTRNODECORE pNode, void *pvUser)
    697746{
    698     PPGMVIRTHANDLER     pCur = (PPGMVIRTHANDLER)pNode;
    699     PPGMHANDLERINFOARG  pArgs= (PPGMHANDLERINFOARG)pvUser;
    700     PCDBGFINFOHLP       pHlp = pArgs->pHlp;
     747    PPGMVIRTHANDLER         pCur     = (PPGMVIRTHANDLER)pNode;
     748    PPGMHANDLERINFOARG      pArgs    = (PPGMHANDLERINFOARG)pvUser;
     749    PCDBGFINFOHLP           pHlp     = pArgs->pHlp;
     750    PPGMVIRTHANDLERTYPEINT  pCurType = PGMVIRTANDLER_GET_TYPE(pArgs->pVM, pCur);
    701751    const char *pszType;
    702     switch (pCur->enmType)
    703     {
    704         case PGMVIRTHANDLERTYPE_WRITE:      pszType = "Write  "; break;
    705         case PGMVIRTHANDLERTYPE_ALL:        pszType = "All    "; break;
    706         case PGMVIRTHANDLERTYPE_HYPERVISOR: pszType = "WriteHyp "; break;
     752    switch (pCurType->enmKind)
     753    {
     754        case PGMVIRTHANDLERKIND_WRITE:      pszType = "Write  "; break;
     755        case PGMVIRTHANDLERKIND_ALL:        pszType = "All    "; break;
     756        case PGMVIRTHANDLERKIND_HYPERVISOR: pszType = "WriteHyp "; break;
    707757        default:                            pszType = "????"; break;
    708758    }
    709759    pHlp->pfnPrintf(pHlp, "%RGv - %RGv  %RHv  %RRv  %s  %s\n",
    710         pCur->Core.Key, pCur->Core.KeyLast, pCur->pfnHandlerR3, pCur->pfnHandlerRC, pszType, pCur->pszDesc);
     760        pCur->Core.Key, pCur->Core.KeyLast, pCurType->pfnHandlerR3, pCurType->pfnHandlerRC, pszType, pCur->pszDesc);
    711761#ifdef VBOX_WITH_STATISTICS
    712762    if (pArgs->fStats)
  • trunk/src/VBox/VMM/VMMR3/SELM.cpp

    r46420 r55889  
    187187    /* bit set to 1 means no redirection */
    188188    memset(pVM->selm.s.Tss.IntRedirBitmap, 0xff, sizeof(pVM->selm.s.Tss.IntRedirBitmap));
     189
     190    /*
     191     * Register the virtual access handlers.
     192     */
     193    pVM->selm.s.hShadowGdtWriteHandlerType = NIL_PGMVIRTHANDLERTYPE;
     194    pVM->selm.s.hShadowLdtWriteHandlerType = NIL_PGMVIRTHANDLERTYPE;
     195    pVM->selm.s.hShadowTssWriteHandlerType = NIL_PGMVIRTHANDLERTYPE;
     196    pVM->selm.s.hGuestGdtWriteHandlerType  = NIL_PGMVIRTHANDLERTYPE;
     197    pVM->selm.s.hGuestLdtWriteHandlerType  = NIL_PGMVIRTHANDLERTYPE;
     198    pVM->selm.s.hGuestTssWriteHandlerType  = NIL_PGMVIRTHANDLERTYPE;
     199#ifdef VBOX_WITH_RAW_MODE
     200    if (!HMIsEnabled(pVM))
     201    {
     202# ifdef SELM_TRACK_SHADOW_GDT_CHANGES
     203        rc = PGMR3HandlerVirtualTypeRegister(pVM, PGMVIRTHANDLERKIND_HYPERVISOR, false /*fRelocUserRC*/,
     204                                             NULL /*pfnInvalidateR3*/, NULL /*pfnHandlerR3*/,
     205                                             "selmRCShadowGDTWriteHandler", NULL /*pszModRC*/,
     206                                             "Shadow GDT write access handler", &pVM->selm.s.hShadowGdtWriteHandlerType);
     207        AssertRCReturn(rc, rc);
     208# endif
     209# ifdef SELM_TRACK_SHADOW_TSS_CHANGES
     210        rc = PGMR3HandlerVirtualTypeRegister(pVM, PGMVIRTHANDLERKIND_HYPERVISOR, false /*fRelocUserRC*/,
     211                                             NULL /*pfnInvalidateR3*/, NULL /*pfnHandlerR3*/,
     212                                             "selmRCShadowTSSWriteHandler", NULL /*pszModRC*/,
     213                                             "Shadow TSS write access handler", &pVM->selm.s.hShadowTssWriteHandlerType);
     214        AssertRCReturn(rc, rc);
     215# endif
     216# ifdef SELM_TRACK_SHADOW_LDT_CHANGES
     217        rc = PGMR3HandlerVirtualTypeRegister(pVM, PGMVIRTHANDLERKIND_HYPERVISOR, false /*fRelocUserRC*/,
     218                                             NULL /*pfnInvalidateR3*/, NULL /*pfnHandlerR3*/,
     219                                             "selmRCShadowLDTWriteHandler", NULL /*pszModRC*/,
     220                                             "Shadow LDT write access handler", &pVM->selm.s.hShadowLdtWriteHandlerType);
     221        AssertRCReturn(rc, rc);
     222# endif
     223        rc = PGMR3HandlerVirtualTypeRegister(pVM, PGMVIRTHANDLERKIND_WRITE, false /*fRelocUserRC*/,
     224                                             NULL /*pfnInvalidateR3*/, selmR3GuestGDTWriteHandler,
     225                                             "selmRCGuestGDTWriteHandler", NULL /*pszModRC*/,
     226                                             "Guest GDT write access handler", &pVM->selm.s.hGuestGdtWriteHandlerType);
     227        AssertRCReturn(rc, rc);
     228        rc = PGMR3HandlerVirtualTypeRegister(pVM, PGMVIRTHANDLERKIND_WRITE, false /*fRelocUserRC*/,
     229                                             NULL /*pfnInvalidateR3*/, selmR3GuestLDTWriteHandler,
     230                                             "selmRCGuestLDTWriteHandler", NULL /*pszModRC*/,
     231                                             "Guest LDT write access handler", &pVM->selm.s.hGuestLdtWriteHandlerType);
     232        AssertRCReturn(rc, rc);
     233        rc = PGMR3HandlerVirtualTypeRegister(pVM, PGMVIRTHANDLERKIND_WRITE, false /*fRelocUserRC*/,
     234                                             NULL /*pfnInvalidateR3*/, selmR3GuestTSSWriteHandler,
     235                                             "selmRCGuestTSSWriteHandler", NULL /*pszModRC*/,
     236                                             "Guest TSS write access handler", &pVM->selm.s.hGuestTssWriteHandlerType);
     237        AssertRCReturn(rc, rc);
     238    }
     239#endif /* VBOX_WITH_RAW_MODE */
    189240
    190241    /*
     
    499550         * Update shadow GDT/LDT/TSS write access handlers.
    500551         */
     552        PVMCPU pVCpu = VMMGetCpu(pVM); NOREF(pVCpu);
    501553        int rc; NOREF(rc);
    502554#ifdef SELM_TRACK_SHADOW_GDT_CHANGES
    503555        if (pVM->selm.s.paGdtRC != NIL_RTRCPTR)
    504556        {
    505             rc = PGMHandlerVirtualDeregister(pVM, pVM->selm.s.paGdtRC);
     557            rc = PGMHandlerVirtualDeregister(pVM, pVCpu, pVM->selm.s.paGdtRC, true /*fHypervisor*/);
    506558            AssertRC(rc);
    507559        }
    508560        pVM->selm.s.paGdtRC = MMHyperR3ToRC(pVM, paGdt);
    509         rc = PGMR3HandlerVirtualRegister(pVM, PGMVIRTHANDLERTYPE_HYPERVISOR, pVM->selm.s.paGdtRC,
     561        rc = PGMR3HandlerVirtualRegister(pVM, pVCpu, pVM->selm.s.hShadowGdtWriteHandlerType,
     562                                         pVM->selm.s.paGdtRC,
    510563                                         pVM->selm.s.paGdtRC + SELM_GDT_ELEMENTS * sizeof(paGdt[0]) - 1,
    511                                          0, 0, "selmRCShadowGDTWriteHandler", 0, "Shadow GDT write access handler");
     564                                         NULL /*pvUserR3*/, NIL_RTR0PTR /*pvUserRC*/, NULL /*pszDesc*/);
    512565        AssertRC(rc);
    513566#endif
     
    515568        if (pVM->selm.s.pvMonShwTssRC != RTRCPTR_MAX)
    516569        {
    517             rc = PGMHandlerVirtualDeregister(pVM, pVM->selm.s.pvMonShwTssRC);
     570            rc = PGMHandlerVirtualDeregister(pVM, pVCpu, pVM->selm.s.pvMonShwTssRC, true /*fHypervisor*/);
    518571            AssertRC(rc);
    519572        }
    520573        pVM->selm.s.pvMonShwTssRC = VM_RC_ADDR(pVM, &pVM->selm.s.Tss);
    521         rc = PGMR3HandlerVirtualRegister(pVM, PGMVIRTHANDLERTYPE_HYPERVISOR, pVM->selm.s.pvMonShwTssRC,
     574        rc = PGMR3HandlerVirtualRegister(pVM, pVCpu, pVM->selm.s.hShadowTssWriteHandlerType,
     575                                         pVM->selm.s.pvMonShwTssRC,
    522576                                         pVM->selm.s.pvMonShwTssRC + sizeof(pVM->selm.s.Tss) - 1,
    523                                          0, 0, "selmRCShadowTSSWriteHandler", 0, "Shadow TSS write access handler");
     577                                         NULL /*pvUserR3*/, NIL_RTR0PTR /*pvUserRC*/, NULL /*pszDesc*/);
    524578        AssertRC(rc);
    525579#endif
     
    531585        if (pVM->selm.s.pvLdtRC != RTRCPTR_MAX)
    532586        {
    533             rc = PGMHandlerVirtualDeregister(pVM, pVM->selm.s.pvLdtRC);
     587            rc = PGMHandlerVirtualDeregister(pVM, pVCpu, pVM->selm.s.pvLdtRC, true /*fHypervisor*/);
    534588            AssertRC(rc);
    535589        }
     
    537591        pVM->selm.s.pvLdtRC = MMHyperR3ToRC(pVM, pVM->selm.s.pvLdtR3);
    538592#ifdef SELM_TRACK_SHADOW_LDT_CHANGES
    539         rc = PGMR3HandlerVirtualRegister(pVM, PGMVIRTHANDLERTYPE_HYPERVISOR, pVM->selm.s.pvLdtRC,
     593        rc = PGMR3HandlerVirtualRegister(pVM, pVCpu, pVM->selm.s.hShadowLdtWriteHandlerType,
     594                                         pVM->selm.s.pvLdtRC,
    540595                                         pVM->selm.s.pvLdtRC + _64K + PAGE_SIZE - 1,
    541                                          0, 0, "selmRCShadowLDTWriteHandler", 0, "Shadow LDT write access handler");
     596                                         NULL /*pvUserR3*/, NIL_RTR0PTR /*pvUserRC*/, NULL /*pszDesc*/);
    542597        AssertRC(rc);
    543598#endif
     
    578633     * Uninstall guest GDT/LDT/TSS write access handlers.
    579634     */
     635    PVMCPU pVCpu = VMMGetCpu(pVM); NOREF(pVCpu);
    580636    int rc = VINF_SUCCESS;
    581637    if (pVM->selm.s.GuestGdtr.pGdt != RTRCPTR_MAX && pVM->selm.s.fGDTRangeRegistered)
    582638    {
    583639#ifdef SELM_TRACK_GUEST_GDT_CHANGES
    584         rc = PGMHandlerVirtualDeregister(pVM, pVM->selm.s.GuestGdtr.pGdt);
     640        rc = PGMHandlerVirtualDeregister(pVM, pVCpu, pVM->selm.s.GuestGdtr.pGdt, false /*fHypervisor*/);
    585641        AssertRC(rc);
    586642#endif
     
    592648    {
    593649#ifdef SELM_TRACK_GUEST_LDT_CHANGES
    594         rc = PGMHandlerVirtualDeregister(pVM, pVM->selm.s.GCPtrGuestLdt);
     650        rc = PGMHandlerVirtualDeregister(pVM, pVCpu, pVM->selm.s.GCPtrGuestLdt, false /*fHypervisor*/);
    595651        AssertRC(rc);
    596652#endif
     
    600656    {
    601657#ifdef SELM_TRACK_GUEST_TSS_CHANGES
    602         rc = PGMHandlerVirtualDeregister(pVM, pVM->selm.s.GCPtrGuestTss);
     658        rc = PGMHandlerVirtualDeregister(pVM, pVCpu, pVM->selm.s.GCPtrGuestTss, false /*fHypervisor*/);
    603659        AssertRC(rc);
    604660#endif
     
    9871043    {
    9881044        Log(("SELMR3UpdateFromCPUM: Guest's GDT is changed to pGdt=%016RX64 cbGdt=%08X\n", GDTR.pGdt, GDTR.cbGdt));
     1045        PVMCPU pVCpu = VMMGetCpu(pVM);
    9891046
    9901047# ifdef SELM_TRACK_GUEST_GDT_CHANGES
     
    9941051        if (pVM->selm.s.GuestGdtr.pGdt != RTRCPTR_MAX && pVM->selm.s.fGDTRangeRegistered)
    9951052        {
    996             rc = PGMHandlerVirtualDeregister(pVM, pVM->selm.s.GuestGdtr.pGdt);
     1053            rc = PGMHandlerVirtualDeregister(pVM, pVCpu, pVM->selm.s.GuestGdtr.pGdt, false /*fHypervisor*/);
    9971054            AssertRC(rc);
    9981055        }
    999 
    1000         rc = PGMR3HandlerVirtualRegister(pVM, PGMVIRTHANDLERTYPE_WRITE,
     1056        rc = PGMR3HandlerVirtualRegister(pVM, pVCpu, pVM->selm.s.hGuestGdtWriteHandlerType,
    10011057                                         GDTR.pGdt, GDTR.pGdt + GDTR.cbGdt /* already inclusive */,
    1002                                          0, selmR3GuestGDTWriteHandler, "selmRCGuestGDTWriteHandler", 0,
    1003                                          "Guest GDT write access handler");
     1058                                         NULL /*pvUserR3*/, NIL_RTR0PTR /*pvUserRC*/, NULL /*pszDesc*/);
    10041059#  ifdef VBOX_WITH_RAW_RING1
    10051060        /** @todo !HACK ALERT!
    10061061         * Some guest OSes (QNX) share code and the GDT on the same page;
    10071062         * PGMR3HandlerVirtualRegister doesn't support more than one handler,
    1008          * so we kick out the  PATM handler as this one is more important.
    1009          * Fix this properly in PGMR3HandlerVirtualRegister?
     1063         * so we kick out the PATM handler as this one is more important. Fix this
     1064         * properly in PGMR3HandlerVirtualRegister?
    10101065         */
    10111066        if (rc == VERR_PGM_HANDLER_VIRTUAL_CONFLICT)
    10121067        {
    10131068            LogRel(("selmR3UpdateShadowGdt: Virtual handler conflict %RGv -> kick out PATM handler for the higher priority GDT page monitor\n", GDTR.pGdt));
    1014             rc = PGMHandlerVirtualDeregister(pVM, GDTR.pGdt & PAGE_BASE_GC_MASK);
     1069            rc = PGMHandlerVirtualDeregister(pVM, pVCpu, GDTR.pGdt & PAGE_BASE_GC_MASK, false /*fHypervisor*/);
    10151070            AssertRC(rc);
    1016 
    1017             rc = PGMR3HandlerVirtualRegister(pVM, PGMVIRTHANDLERTYPE_WRITE,
     1071            rc = PGMR3HandlerVirtualRegister(pVM, pVCpu, pVM->selm.s.hGuestGdtWriteHandlerType,
    10181072                                             GDTR.pGdt, GDTR.pGdt + GDTR.cbGdt /* already inclusive */,
    1019                                              0, selmR3GuestGDTWriteHandler, "selmRCGuestGDTWriteHandler", 0,
    1020                                              "Guest GDT write access handler");
     1073                                             NULL /*pvUserR3*/, NIL_RTR0PTR /*pvUserRC*/, NULL /*pszDesc*/);
    10211074        }
    10221075#  endif
     
    10731126        if (pVM->selm.s.GCPtrGuestLdt != RTRCPTR_MAX)
    10741127        {
    1075             rc = PGMHandlerVirtualDeregister(pVM, pVM->selm.s.GCPtrGuestLdt);
     1128            rc = PGMHandlerVirtualDeregister(pVM, pVCpu, pVM->selm.s.GCPtrGuestLdt, false /*fHypervisor*/);
    10761129            AssertRC(rc);
    10771130            pVM->selm.s.GCPtrGuestLdt = RTRCPTR_MAX;
     
    11061159        if (pVM->selm.s.GCPtrGuestLdt != RTRCPTR_MAX)
    11071160        {
    1108             rc = PGMHandlerVirtualDeregister(pVM, pVM->selm.s.GCPtrGuestLdt);
     1161            rc = PGMHandlerVirtualDeregister(pVM, pVCpu, pVM->selm.s.GCPtrGuestLdt, false /*fHypervisor*/);
    11091162            AssertRC(rc);
    11101163            pVM->selm.s.GCPtrGuestLdt = RTRCPTR_MAX;
     
    11421195            if (pVM->selm.s.GCPtrGuestLdt != RTRCPTR_MAX)
    11431196            {
    1144                 rc = PGMHandlerVirtualDeregister(pVM, pVM->selm.s.GCPtrGuestLdt);
     1197                rc = PGMHandlerVirtualDeregister(pVM, pVCpu, pVM->selm.s.GCPtrGuestLdt, false /*fHypervisor*/);
    11451198                AssertRC(rc);
    11461199            }
     
    11491202                Log(("LDT selector marked not present!!\n"));
    11501203#  endif
    1151             rc = PGMR3HandlerVirtualRegister(pVM, PGMVIRTHANDLERTYPE_WRITE, GCPtrLdt, GCPtrLdt + cbLdt /* already inclusive */,
    1152                                              0, selmR3GuestLDTWriteHandler, "selmRCGuestLDTWriteHandler", 0, "Guest LDT write access handler");
     1204            rc = PGMR3HandlerVirtualRegister(pVM, pVCpu, pVM->selm.s.hGuestLdtWriteHandlerType,
     1205                                             GCPtrLdt, GCPtrLdt + cbLdt /* already inclusive */,
     1206                                             NULL /*pvUserR3*/, NIL_RTR0PTR /*pvUserRC*/, NULL /*pszDesc*/);
    11531207            if (rc == VERR_PGM_HANDLER_VIRTUAL_CONFLICT)
    11541208            {
     
    16991753        Log(("SELMR3SyncTSS: Guest's TSS is changed to pTss=%RGv cbMonitoredTss=%08X cbGuestTss=%#08x\n",
    17001754             GCPtrTss, cbMonitoredTss, pVM->selm.s.cbGuestTss));
     1755        PVMCPU pVCpu = VMMGetCpu(pVM);
    17011756
    17021757        /* Release the old range first. */
    17031758        if (pVM->selm.s.GCPtrGuestTss != RTRCPTR_MAX)
    17041759        {
    1705             rc = PGMHandlerVirtualDeregister(pVM, pVM->selm.s.GCPtrGuestTss);
     1760            rc = PGMHandlerVirtualDeregister(pVM, pVCpu, pVM->selm.s.GCPtrGuestTss, false /*fHypervisor*/);
    17061761            AssertRC(rc);
    17071762        }
     
    17111766        {
    17121767# ifdef SELM_TRACK_GUEST_TSS_CHANGES
    1713             rc = PGMR3HandlerVirtualRegister(pVM, PGMVIRTHANDLERTYPE_WRITE, GCPtrTss, GCPtrTss + cbMonitoredTss - 1,
    1714                                              0, selmR3GuestTSSWriteHandler,
    1715                                              "selmRCGuestTSSWriteHandler", 0, "Guest TSS write access handler");
     1768            rc = PGMR3HandlerVirtualRegister(pVM, pVCpu, pVM->selm.s.hGuestTssWriteHandlerType,
     1769                                             GCPtrTss, GCPtrTss + cbMonitoredTss - 1,
     1770                                             NULL /*pvUserR3*/, NIL_RTR0PTR /*pvUserRC*/, NULL /*pszDesc*/);
    17161771            if (RT_FAILURE(rc))
    17171772            {
     
    17261781                {
    17271782                    LogRel(("SELMR3SyncTSS: Virtual handler conflict %RGv -> kick out PATM handler for the higher priority TSS page monitor\n", GCPtrTss));
    1728                     rc = PGMHandlerVirtualDeregister(pVM, GCPtrTss & PAGE_BASE_GC_MASK);
     1783                    rc = PGMHandlerVirtualDeregister(pVM, pVCpu, GCPtrTss & PAGE_BASE_GC_MASK, false /*fHypervisor*/);
    17291784                    AssertRC(rc);
    17301785
    1731                     rc = PGMR3HandlerVirtualRegister(pVM, PGMVIRTHANDLERTYPE_WRITE, GCPtrTss, GCPtrTss + cbMonitoredTss - 1,
    1732                                                      0, selmR3GuestTSSWriteHandler,
    1733                                                      "selmRCGuestTSSWriteHandler", 0, "Guest TSS write access handler");
     1786                    rc = PGMR3HandlerVirtualRegister(pVM, pVCpu, pVM->selm.s.hGuestTssWriteHandlerType,
     1787                                                     GCPtrTss, GCPtrTss + cbMonitoredTss - 1,
     1788                                                     NULL /*pvUserR3*/, NIL_RTR0PTR /*pvUserRC*/, NULL /*pszDesc*/);
    17341789                    if (RT_FAILURE(rc))
    17351790                    {
  • trunk/src/VBox/VMM/VMMR3/TRPM.cpp

    r55000 r55889  
    455455{
    456456    LogFlow(("TRPMR3Init\n"));
     457    int rc;
    457458
    458459    /*
     
    490491    {
    491492        bool f;
    492         int rc = CFGMR3QueryBool(pTRPMNode, "SafeToDropGuestIDTMonitoring", &f);
     493        rc = CFGMR3QueryBool(pTRPMNode, "SafeToDropGuestIDTMonitoring", &f);
    493494        if (RT_SUCCESS(rc))
    494495            pVM->trpm.s.fSafeToDropGuestIDTMonitoring = f;
     
    507508
    508509    /*
     510     * Register virtual access handlers.
     511     */
     512    pVM->trpm.s.hShadowIdtWriteHandlerType = NIL_PGMVIRTHANDLERTYPE;
     513    pVM->trpm.s.hGuestIdtWriteHandlerType  = NIL_PGMVIRTHANDLERTYPE;
     514#ifdef VBOX_WITH_RAW_MODE
     515    if (!HMIsEnabled(pVM))
     516    {
     517# ifdef TRPM_TRACK_SHADOW_IDT_CHANGES
     518        rc = PGMR3HandlerVirtualTypeRegister(pVM, PGMVIRTHANDLERKIND_HYPERVISOR, false /*fRelocUserRC*/,
     519                                             NULL /*pfnInvalidateR3*/, NULL /*pfnHandlerR3*/,
     520                                             "trpmRCShadowIDTWriteHandler", NULL /*pszModRC*/,
     521                                             "Shadow IDT write access handler", &pVM->trpm.s.hShadowIdtWriteHandlerType);
     522        AssertRCReturn(rc, rc);
     523# endif
     524        rc = PGMR3HandlerVirtualTypeRegister(pVM, PGMVIRTHANDLERKIND_WRITE, false /*fRelocUserRC*/,
     525                                             NULL /*pfnInvalidateR3*/, trpmR3GuestIDTWriteHandler,
     526                                             "trpmRCGuestIDTWriteHandler", NULL /*pszModRC*/,
     527                                             "Guest IDT write access handler", &pVM->trpm.s.hGuestIdtWriteHandlerType);
     528        AssertRCReturn(rc, rc);
     529    }
     530#endif /* VBOX_WITH_RAW_MODE */
     531
     532    /*
    509533     * Register the saved state data unit.
    510534     */
    511     int rc = SSMR3RegisterInternal(pVM, "trpm", 1, TRPM_SAVED_STATE_VERSION, sizeof(TRPM),
    512                                    NULL, NULL, NULL,
    513                                    NULL, trpmR3Save, NULL,
    514                                    NULL, trpmR3Load, NULL);
     535    rc = SSMR3RegisterInternal(pVM, "trpm", 1, TRPM_SAVED_STATE_VERSION, sizeof(TRPM),
     536                               NULL, NULL, NULL,
     537                               NULL, trpmR3Save, NULL,
     538                               NULL, trpmR3Load, NULL);
    515539    if (RT_FAILURE(rc))
    516540        return rc;
     
    692716    if (pVM->trpm.s.pvMonShwIdtRC != RTRCPTR_MAX)
    693717    {
    694         rc = PGMHandlerVirtualDeregister(pVM, pVM->trpm.s.pvMonShwIdtRC);
     718        rc = PGMHandlerVirtualDeregister(pVM, pVCpu, pVM->trpm.s.pvMonShwIdtRC, true /*fHypervisor*/);
    695719        AssertRC(rc);
    696720    }
    697721    pVM->trpm.s.pvMonShwIdtRC = VM_RC_ADDR(pVM, &pVM->trpm.s.aIdt[0]);
    698     rc = PGMR3HandlerVirtualRegister(pVM, PGMVIRTHANDLERTYPE_HYPERVISOR, pVM->trpm.s.pvMonShwIdtRC, pVM->trpm.s.pvMonShwIdtRC + sizeof(pVM->trpm.s.aIdt) - 1,
    699                                      0, 0, "trpmRCShadowIDTWriteHandler", 0, "Shadow IDT write access handler");
     722    rc = PGMR3HandlerVirtualRegister(pVM, pVCpu, pVM->trpm.s.hShadowIdtWriteHandlerType,
     723                                     pVM->trpm.s.pvMonShwIdtRC, pVM->trpm.s.pvMonShwIdtRC + sizeof(pVM->trpm.s.aIdt) - 1,
     724                                     NULL /*pvUserR3*/, NIL_RTR0PTR /*pvUserRC*/, NULL /*pszDesc*/);
    700725    AssertRC(rc);
    701726# endif
     
    775800        if (!pVM->trpm.s.fSafeToDropGuestIDTMonitoring)
    776801        {
    777             int rc = PGMHandlerVirtualDeregister(pVM, pVM->trpm.s.GuestIdtr.pIdt);
     802            int rc = PGMHandlerVirtualDeregister(pVM, VMMGetCpu(pVM), pVM->trpm.s.GuestIdtr.pIdt, false /*fHypervisor*/);
    778803            AssertRC(rc);
    779804        }
     
    10901115             * [Re]Register write virtual handler for guest's IDT.
    10911116             */
     1117            PVMCPU pVCpu = VMMGetCpu(pVM);
    10921118            if (pVM->trpm.s.GuestIdtr.pIdt != RTRCPTR_MAX)
    10931119            {
    1094                 rc = PGMHandlerVirtualDeregister(pVM, pVM->trpm.s.GuestIdtr.pIdt);
     1120                rc = PGMHandlerVirtualDeregister(pVM, pVCpu, pVM->trpm.s.GuestIdtr.pIdt, false /*fHypervisor*/);
    10951121                AssertRCReturn(rc, rc);
    10961122            }
    10971123            /* limit is including */
    1098             rc = PGMR3HandlerVirtualRegister(pVM, PGMVIRTHANDLERTYPE_WRITE, IDTR.pIdt, IDTR.pIdt + IDTR.cbIdt /* already inclusive */,
    1099                                              0, trpmR3GuestIDTWriteHandler, "trpmRCGuestIDTWriteHandler", 0, "Guest IDT write access handler");
     1124            rc = PGMR3HandlerVirtualRegister(pVM, pVCpu, pVM->trpm.s.hGuestIdtWriteHandlerType,
     1125                                             IDTR.pIdt, IDTR.pIdt + IDTR.cbIdt /* already inclusive */,
     1126                                             NULL /*pvUserR3*/, NIL_RTR0PTR /*pvUserRC*/, NULL /*pszDesc*/);
    11001127
    11011128            if (rc == VERR_PGM_HANDLER_VIRTUAL_CONFLICT)
     
    11061133                    CSAMR3RemovePage(pVM, IDTR.pIdt + IDTR.cbIdt);
    11071134
    1108                 rc = PGMR3HandlerVirtualRegister(pVM, PGMVIRTHANDLERTYPE_WRITE, IDTR.pIdt, IDTR.pIdt + IDTR.cbIdt /* already inclusive */,
    1109                                                  0, trpmR3GuestIDTWriteHandler, "trpmRCGuestIDTWriteHandler", 0, "Guest IDT write access handler");
     1135                rc = PGMR3HandlerVirtualRegister(pVM, pVCpu, pVM->trpm.s.hGuestIdtWriteHandlerType,
     1136                                                 IDTR.pIdt, IDTR.pIdt + IDTR.cbIdt /* already inclusive */,
     1137                                                 NULL /*pvUserR3*/, NIL_RTR0PTR /*pvUserRC*/, NULL /*pszDesc*/);
    11101138            }
    11111139
  • trunk/src/VBox/VMM/include/CSAMInternal.h

    r52771 r55889  
    156156
    157157    RCPTRTYPE(RTRCPTR *)  pPDBitmapGC;
    158     RCPTRTYPE(RTHCPTR *)    pPDHCBitmapGC;
    159     R3PTRTYPE(uint8_t **)   pPDBitmapHC;
     158    RCPTRTYPE(RTHCPTR *)  pPDHCBitmapGC;
     159    R3PTRTYPE(uint8_t **) pPDBitmapHC;
    160160    R3PTRTYPE(RTRCPTR  *) pPDGCBitmapHC;
    161161
     
    175175    /* To keep track of possible code pages */
    176176    uint32_t            cPossibleCodePages;
    177     RTRCPTR           pvPossibleCodePage[CSAM_MAX_CODE_PAGES_FLUSH];
     177    RTRCPTR             pvPossibleCodePage[CSAM_MAX_CODE_PAGES_FLUSH];
    178178
    179179    /* call addresses reported by the recompiler */
    180     RTRCPTR           pvCallInstruction[16];
    181     RTUINT              iCallInstruction;
     180    RTRCPTR             pvCallInstruction[16];
     181    uint32_t            iCallInstruction;
     182
     183    /** Code page write access handler type. */
     184    PGMVIRTHANDLERTYPE  hCodePageWriteType;
     185    /** Code page write & invalidation access handler type. */
     186    PGMVIRTHANDLERTYPE  hCodePageWriteAndInvPgType;
    182187
    183188    /* Set when scanning has started. */
  • trunk/src/VBox/VMM/include/PATMInternal.h

    r54764 r55889  
    528528    RTDBGMOD                    hDbgModPatchMem;
    529529
    530 #if HC_ARCH_BITS == 32
     530    /** Virtual page access handler type (patmVirtPageHandler,
     531     * PATMGCMonitorPage). */
     532    PGMVIRTHANDLERTYPE          hMonitorPageType;
     533
     534#if HC_ARCH_BITS == 64
    531535    /** Align statistics on a 8 byte boundary. */
    532536    uint32_t                    u32Alignment1;
  • trunk/src/VBox/VMM/include/PGMInline.h

    r55493 r55889  
    55
    66/*
    7  * Copyright (C) 2006-2012 Oracle Corporation
     7 * Copyright (C) 2006-2015 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    12001200
    12011201/**
    1202  * Gets the page state for a virtual handler.
    1203  *
    1204  * @returns The virtual handler page state.
    1205  * @param   pCur    The virtual handler in question.
    1206  * @remarks This should never be used on a hypervisor access handler.
    1207  */
    1208 DECLINLINE(unsigned) pgmHandlerVirtualCalcState(PPGMVIRTHANDLER pCur)
    1209 {
    1210     switch (pCur->enmType)
    1211     {
    1212         case PGMVIRTHANDLERTYPE_WRITE:
    1213             return PGM_PAGE_HNDL_VIRT_STATE_WRITE;
    1214         case PGMVIRTHANDLERTYPE_ALL:
    1215             return PGM_PAGE_HNDL_VIRT_STATE_ALL;
    1216         default:
    1217             AssertFatalMsgFailed(("Invalid type %d\n", pCur->enmType));
    1218     }
    1219 }
    1220 
    1221 
    1222 /**
    12231202 * Clears one physical page of a virtual handler.
    12241203 *
  • trunk/src/VBox/VMM/include/PGMInternal.h

    r55493 r55889  
    612612 * @returns PPGMPHYSHANDLERTYPEINT
    613613 * @param   a_pVM           Pointer to the cross context VM structure.
    614  * @param   a_hType         Physical access handler handle.
     614 * @param   a_hType         Physical access handler type handle.
    615615 */
    616616#define PGMPHYSHANDLERTYPEINT_FROM_HANDLE(a_pVM, a_hType) ((PPGMPHYSHANDLERTYPEINT)MMHyperHeapOffsetToPtr(a_pVM, a_hType))
     
    693693
    694694/**
     695 * Virtual page access handler type registration.
     696 */
     697typedef struct PGMVIRTANDLERTYPEINT
     698{
     699    /** Number of references.   */
     700    uint32_t volatile                   cRefs;
     701    /** Magic number (PGMVIRTHANDLERTYPEINT_MAGIC). */
     702    uint32_t                            u32Magic;
     703    /** Link of handler types anchored in PGMTREES::HeadVirtHandlerTypes. */
     704    RTLISTOFF32NODE                     ListNode;
     705    /** The kind of accesses we're handling. */
     706    PGMVIRTHANDLERKIND                  enmKind;
     707    /** The PGM_PAGE_HNDL_PHYS_STATE_XXX value corresponding to enmKind. */
     708    uint32_t                            uState;
     709    /** Whether the pvUserRC argument should be automatically relocated or not. */
     710    bool                                fRelocUserRC;
     711    bool                                afPadding[3];
     712    /** Pointer to RC callback function. */
     713    RCPTRTYPE(PFNPGMRCVIRTHANDLER)      pfnHandlerRC;
     714    /** Pointer to the R3 callback function for invalidation. */
     715    R3PTRTYPE(PFNPGMR3VIRTINVALIDATE)   pfnInvalidateR3;
     716    /** Pointer to R3 callback function. */
     717    R3PTRTYPE(PFNPGMR3VIRTHANDLER)      pfnHandlerR3;
     718    /** Description / Name. For easing debugging. */
     719    R3PTRTYPE(const char *)             pszDesc;
     720} PGMVIRTHANDLERTYPEINT;
     721/** Pointer to a virtual access handler type registration. */
     722typedef PGMVIRTHANDLERTYPEINT *PPGMVIRTHANDLERTYPEINT;
     723/** Magic value for the virtual handler callbacks (Sir Arthur Charles Clarke). */
     724#define PGMVIRTHANDLERTYPEINT_MAGIC        UINT32_C(0x19171216)
     725/** Magic value for the virtual handler callbacks. */
     726#define PGMVIRTHANDLERTYPEINT_MAGIC_DEAD   UINT32_C(0x20080319)
     727
     728/**
     729 * Converts a handle to a pointer.
     730 * @returns PPGMVIRTHANDLERTYPEINT
     731 * @param   a_pVM           Pointer to the cross context VM structure.
     732 * @param   a_hType         Vitual access handler type handle.
     733 */
     734#define PGMVIRTHANDLERTYPEINT_FROM_HANDLE(a_pVM, a_hType) ((PPGMVIRTHANDLERTYPEINT)MMHyperHeapOffsetToPtr(a_pVM, a_hType))
     735
     736
     737/**
    695738 * Virtual page access handler structure.
    696739 *
     
    703746    AVLROGCPTRNODECORE                  Core;
    704747    /** Size of the range (in bytes). */
    705     RTGCPTR                             cb;
     748    uint32_t                            cb;
    706749    /** Number of cache pages. */
    707750    uint32_t                            cPages;
    708     /** Access type. */
    709     PGMVIRTHANDLERTYPE                  enmType;
    710     /** Pointer to the RC callback function. */
    711     RCPTRTYPE(PFNPGMRCVIRTHANDLER)      pfnHandlerRC;
    712 #if HC_ARCH_BITS == 64
    713     RTRCPTR                             padding;
    714 #endif
    715     /** Pointer to the R3 callback function for invalidation. */
    716     R3PTRTYPE(PFNPGMR3VIRTINVALIDATE)   pfnInvalidateR3;
    717     /** Pointer to the R3 callback function. */
    718     R3PTRTYPE(PFNPGMR3VIRTHANDLER)      pfnHandlerR3;
     751    /** Registered handler type handle (heap offset). */
     752    PGMVIRTHANDLERTYPE                  hType;
     753    /** User argument for RC handlers. */
     754    RCPTRTYPE(void *)                   pvUserRC;
     755    /** User argument for R3 handlers. */
     756    R3PTRTYPE(void *)                   pvUserR3;
    719757    /** Description / Name. For easing debugging. */
    720758    R3PTRTYPE(const char *)             pszDesc;
     
    728766/** Pointer to a virtual page access handler structure. */
    729767typedef PGMVIRTHANDLER *PPGMVIRTHANDLER;
     768
     769/**
     770 * Gets the type record for a virtual handler (no reference added).
     771 * @returns PPGMVIRTHANDLERTYPEINT
     772 * @param   a_pVM           Pointer to the cross context VM structure.
     773 * @param   a_pVirtHandler  Pointer to the virtual handler structure
     774 *                          (PGMVIRTHANDLER).
     775 */
     776#define PGMVIRTANDLER_GET_TYPE(a_pVM, a_pVirtHandler) PGMVIRTHANDLERTYPEINT_FROM_HANDLE(a_pVM, (a_pVirtHandler)->hType)
    730777
    731778
     
    26702717     * PGMPHYSHANDLERTYPEINT.  This is needed for relocations. */
    26712718    RTLISTOFF32ANCHOR               HeadPhysHandlerTypes;
     2719    /** List of virtual access handler types (offset pointers) of type
     2720     * PGMVIRTHANDLERTYPEINT.  This is needed for relocations. */
     2721    RTLISTOFF32ANCHOR               HeadVirtHandlerTypes;
    26722722} PGMTREES;
    26732723/** Pointer to PGM trees. */
  • trunk/src/VBox/VMM/include/SELMInternal.h

    r45725 r55889  
    2323#include <VBox/vmm/stam.h>
    2424#include <VBox/vmm/cpum.h>
     25#include <VBox/vmm/pgm.h>
    2526#include <VBox/log.h>
    2627#include <iprt/x86.h>
     
    103104    RTSEL                   aHyperSel[SELM_HYPER_SEL_MAX];
    104105
     106    /** @name GDT
     107     * @{ */
     108    /** Shadow GDT virtual write access handler type. */
     109    PGMVIRTHANDLERTYPE      hShadowGdtWriteHandlerType;
     110    /** Guest GDT virtual write access handler type. */
     111    PGMVIRTHANDLERTYPE      hGuestGdtWriteHandlerType;
    105112    /** Pointer to the GCs - R3 Ptr.
    106113     * This size is governed by SELM_GDT_ELEMENTS. */
     
    114121    VBOXGDTR                GuestGdtr;
    115122    /** The current (last) effective Guest GDT size. */
    116     RTUINT                  cbEffGuestGdtLimit;
    117 
    118     uint32_t                padding0;
    119 
     123    uint32_t                cbEffGuestGdtLimit;
     124    /** Indicates that the Guest GDT access handler have been registered. */
     125    bool                    fGDTRangeRegistered;
     126    /** @} */
     127    bool                    padding0[3];
     128
     129    /** @name LDT
     130     * @{ */
     131    /** Shadow LDT virtual write access handler type. */
     132    PGMVIRTHANDLERTYPE      hShadowLdtWriteHandlerType;
     133    /** Guest LDT virtual write access handler type. */
     134    PGMVIRTHANDLERTYPE      hGuestLdtWriteHandlerType;
    120135    /** R3 pointer to the LDT shadow area in HMA. */
    121136    R3PTRTYPE(void *)       pvLdtR3;
     
    129144    RTGCPTR                 GCPtrGuestLdt;
    130145    /** Current LDT limit, both Guest and Shadow. */
    131     RTUINT                  cbLdtLimit;
     146    uint32_t                cbLdtLimit;
    132147    /** Current LDT offset relative to pvLdtR3/pvLdtRC. */
    133     RTUINT                  offLdtHyper;
     148    uint32_t                offLdtHyper;
    134149#if HC_ARCH_BITS == 32 && GC_ARCH_BITS == 64
    135150    uint32_t                padding2[2];
    136151#endif
     152    /** @} */
     153
     154    /** @name TSS
     155     * @{ */
    137156    /** TSS. (This is 16 byte aligned!)
    138157      * @todo I/O bitmap & interrupt redirection table? */
    139158    VBOXTSS                 Tss;
    140 
    141159    /** TSS for trap 08 (\#DF). */
    142160    VBOXTSS                 TssTrap08;
    143 
     161    /** Shadow TSS virtual write access handler type. */
     162    PGMVIRTHANDLERTYPE      hShadowTssWriteHandlerType;
     163    /** Guerst TSS virtual write access handler type. */
     164    PGMVIRTHANDLERTYPE      hGuestTssWriteHandlerType;
    144165    /** Monitored shadow TSS address. */
    145166    RCPTRTYPE(void *)       pvMonShwTssRC;
     
    151172    RTGCPTR                 GCPtrGuestTss;
    152173    /** The size of the guest TSS. */
    153     RTUINT                  cbGuestTss;
     174    uint32_t                cbGuestTss;
    154175    /** Set if it's a 32-bit TSS. */
    155176    bool                    fGuestTss32Bit;
     177    /** Indicates whether the TSS stack selector & base address need to be refreshed.  */
     178    bool                    fSyncTSSRing0Stack;
    156179    /** The size of the Guest's TSS part we're monitoring. */
    157     RTUINT                  cbMonitoredGuestTss;
     180    uint32_t                cbMonitoredGuestTss;
    158181    /** The guest TSS selector at last sync (part of monitoring).
    159182     * Contains RTSEL_MAX if not set. */
     
    162185     * This is only used if we monitor the bitmap. */
    163186    uint16_t                offGuestIoBitmap;
    164 
    165     /** Indicates that the Guest GDT access handler have been registered. */
    166     bool                    fGDTRangeRegistered;
    167 
    168     /** Indicates whether the TSS stack selector & base address need to be refreshed.  */
    169     bool                    fSyncTSSRing0Stack;
    170     bool                    fPadding2[4];
     187    /** @} */
     188    uint16_t                padding4;
    171189
    172190    /** SELMR3UpdateFromCPUM() profiling. */
  • trunk/src/VBox/VMM/include/TRPMInternal.h

    r45728 r55889  
    2323#include <VBox/vmm/stam.h>
    2424#include <VBox/vmm/cpum.h>
     25#include <VBox/vmm/pgm.h>
    2526
    2627
     
    126127    /** Current (last) Guest's IDTR. */
    127128    VBOXIDTR                GuestIdtr;
    128 
    129129    /** padding. */
    130130    uint8_t                 au8Padding[2];
     131    /** Shadow IDT virtual write access handler type. */
     132    PGMVIRTHANDLERTYPE      hShadowIdtWriteHandlerType;
     133    /** Guest IDT virtual write access handler type. */
     134    PGMVIRTHANDLERTYPE      hGuestIdtWriteHandlerType;
    131135
    132136    /** Checked trap & interrupt handler array */
  • trunk/src/VBox/VMM/include/TRPMInternal.mac

    r45728 r55889  
    3636    .aTmpTrapHandlers   RTRCPTR_RES 256
    3737
    38     .pvMonShwIdtRC            RTRCPTR_RES 1
    39     .GuestIdtr          resb 10
    40     .au8Padding         resb 2
     38    .pvMonShwIdtRC                  RTRCPTR_RES 1
     39    .GuestIdtr                      resb 10
     40    .au8Padding                     resb 2
     41    .hShadowIdtWriteHandlerType     resd 1
     42    .hGuestIdtWriteHandlerType      resd 1
    4143
    4244    .aGuestTrapHandler  RTRCPTR_RES 256
  • trunk/src/VBox/VMM/testcase/tstVMStruct.h

    r55493 r55889  
    799799    GEN_CHECK_SIZE(PGMVIRTHANDLER);
    800800    GEN_CHECK_OFF(PGMVIRTHANDLER, Core);
    801     GEN_CHECK_OFF(PGMVIRTHANDLER, enmType);
     801    GEN_CHECK_OFF(PGMVIRTHANDLER, hType);
    802802    GEN_CHECK_OFF(PGMVIRTHANDLER, cb);
    803     GEN_CHECK_OFF(PGMVIRTHANDLER, pfnHandlerR3);
    804     GEN_CHECK_OFF(PGMVIRTHANDLER, pfnHandlerRC);
     803    GEN_CHECK_OFF(PGMVIRTHANDLER, cPages);
    805804    GEN_CHECK_OFF(PGMVIRTHANDLER, pszDesc);
    806     GEN_CHECK_OFF(PGMVIRTHANDLER, cPages);
    807805    GEN_CHECK_OFF(PGMVIRTHANDLER, aPhysToVirt);
     806    GEN_CHECK_SIZE(PGMVIRTHANDLERTYPEINT);
     807    GEN_CHECK_OFF(PGMVIRTHANDLERTYPEINT, u32Magic);
     808    GEN_CHECK_OFF(PGMVIRTHANDLERTYPEINT, cRefs);
     809    GEN_CHECK_OFF(PGMVIRTHANDLERTYPEINT, ListNode);
     810    GEN_CHECK_OFF(PGMVIRTHANDLERTYPEINT, enmKind);
     811    GEN_CHECK_OFF(PGMVIRTHANDLERTYPEINT, uState);
     812    GEN_CHECK_OFF(PGMVIRTHANDLERTYPEINT, fRelocUserRC);
     813    GEN_CHECK_OFF(PGMVIRTHANDLERTYPEINT, pfnHandlerRC);
     814    GEN_CHECK_OFF(PGMVIRTHANDLERTYPEINT, pfnInvalidateR3);
     815    GEN_CHECK_OFF(PGMVIRTHANDLERTYPEINT, pfnHandlerR3);
     816    GEN_CHECK_OFF(PGMVIRTHANDLERTYPEINT, pszDesc);
    808817    GEN_CHECK_SIZE(PGMPAGE);
    809818    GEN_CHECK_OFF_DOT(PGMPAGE, s.cReadLocksY);
     
    990999    GEN_CHECK_OFF(SELM, aHyperSel[SELM_HYPER_SEL_TSS]);
    9911000    GEN_CHECK_OFF(SELM, aHyperSel[SELM_HYPER_SEL_TSS_TRAP08]);
     1001    GEN_CHECK_OFF(SELM, hShadowGdtWriteHandlerType);
     1002    GEN_CHECK_OFF(SELM, hGuestGdtWriteHandlerType);
    9921003    GEN_CHECK_OFF(SELM, paGdtR3);
    9931004    GEN_CHECK_OFF(SELM, paGdtRC);
    9941005    GEN_CHECK_OFF(SELM, GuestGdtr);
    9951006    GEN_CHECK_OFF(SELM, cbEffGuestGdtLimit);
     1007    GEN_CHECK_OFF(SELM, hShadowLdtWriteHandlerType);
     1008    GEN_CHECK_OFF(SELM, hGuestLdtWriteHandlerType);
    9961009    GEN_CHECK_OFF(SELM, pvLdtR3);
    9971010    GEN_CHECK_OFF(SELM, pvLdtRC);
     
    10011014    GEN_CHECK_OFF(SELM, Tss);
    10021015    GEN_CHECK_OFF(SELM, TssTrap08);
     1016    GEN_CHECK_OFF(SELM, hShadowTssWriteHandlerType);
     1017    GEN_CHECK_OFF(SELM, hGuestTssWriteHandlerType);
    10031018    GEN_CHECK_OFF(SELM, pvMonShwTssRC);
    10041019    GEN_CHECK_OFF(SELM, GCPtrGuestTss);
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