VirtualBox

Changeset 93716 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Feb 14, 2022 10:36:21 AM (3 years ago)
Author:
vboxsync
Message:

VMM/PGM: Moved the physical handler allocation off the hyper heap and into its own slab, changing the it to the 'hardened' avl tree code. bugref:10093

Location:
trunk/src/VBox/VMM
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/PGMAllBth.h

    r93650 r93716  
    240240        const RTGCPHYS  GCPhysFault = PGM_A20_APPLY(pVCpu, (RTGCPHYS)pvFault);
    241241# endif
    242         PPGMPHYSHANDLER pCur = pgmHandlerPhysicalLookup(pVM, GCPhysFault);
    243         if (pCur)
     242        PPGMPHYSHANDLER pCur;
     243        rcStrict = pgmHandlerPhysicalLookup(pVM, GCPhysFault, &pCur);
     244        if (RT_SUCCESS(rcStrict))
    244245        {
    245246            PCPGMPHYSHANDLERTYPEINT const pCurType = PGMPHYSHANDLER_GET_TYPE(pVM, pCur);
     
    322323                                                      : (uintptr_t)PDMDeviceRing0IdxToInstance(pVM, pCur->uUser));
    323324
    324 #  ifdef VBOX_WITH_STATISTICS
    325                     pCur = pgmHandlerPhysicalLookup(pVM, GCPhysFault); /* paranoia in case the handler deregistered itself */
    326                     if (pCur)
    327                         STAM_PROFILE_STOP(&pCur->Stat, h);
    328 #  endif
     325                    STAM_PROFILE_STOP(&pCur->Stat, h); /* no locking needed, entry is unlikely reused before we get here. */
    329326                }
    330327                else
     
    337334                    rcStrict = pCurType->pfnPfHandler(pVM, pVCpu, uErr, pRegFrame, pvFault, GCPhysFault, uUser);
    338335
    339 #  ifdef VBOX_WITH_STATISTICS
    340                     PGM_LOCK_VOID(pVM);
    341                     pCur = pgmHandlerPhysicalLookup(pVM, GCPhysFault);
    342                     if (pCur)
    343                         STAM_PROFILE_STOP(&pCur->Stat, h);
    344                     PGM_UNLOCK(pVM);
    345 #  endif
     336                    STAM_PROFILE_STOP(&pCur->Stat, h); /* no locking needed, entry is unlikely reused before we get here. */
    346337                }
    347338            }
     
    352343            return rcStrict;
    353344        }
     345        AssertMsgReturn(rcStrict == VERR_NOT_FOUND, ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)), rcStrict);
    354346    }
    355347
  • trunk/src/VBox/VMM/VMMAll/PGMAllHandler.cpp

    r93666 r93716  
    111111
    112112/**
    113  * Creates a physical access handler.
     113 * Creates a physical access handler, allocation part.
    114114 *
    115115 * @returns VBox status code.
    116  * @retval  VINF_SUCCESS when successfully installed.
    117  * @retval  VINF_PGM_GCPHYS_ALIASED when the shadow PTs could be updated because
    118  *          the guest page aliased or/and mapped by multiple PTs. A CR3 sync has been
    119  *          flagged together with a pool clearing.
    120  * @retval  VERR_PGM_HANDLER_PHYSICAL_CONFLICT if the range conflicts with an existing
    121  *          one. A debug assertion is raised.
     116 * @retval  VERR_OUT_OF_RESOURCES if no more handlers available.
    122117 *
    123118 * @param   pVM             The cross context VM structure.
     
    146141     * Allocate and initialize the new entry.
    147142     */
    148     PPGMPHYSHANDLER pNew;
    149     int rc = MMHyperAlloc(pVM, sizeof(*pNew), 0, MM_TAG_PGM_HANDLERS, (void **)&pNew);
    150     if (RT_SUCCESS(rc))
    151     {
    152         pNew->Core.Key      = NIL_RTGCPHYS;
    153         pNew->Core.KeyLast  = NIL_RTGCPHYS;
     143    int rc = PGM_LOCK(pVM);
     144    AssertRCReturn(rc, rc);
     145
     146    PPGMPHYSHANDLER pNew = pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator.allocateNode();
     147    if (pNew)
     148    {
     149        pNew->Key           = NIL_RTGCPHYS;
     150        pNew->KeyLast       = NIL_RTGCPHYS;
    154151        pNew->cPages        = 0;
    155152        pNew->cAliasedPages = 0;
     
    163160                            : pVM->pgm.s.aPhysHandlerTypes[hType & PGMPHYSHANDLERTYPE_IDX_MASK].pszDesc;
    164161#endif
     162
     163        PGM_UNLOCK(pVM);
    165164        *ppPhysHandler = pNew;
    166165        return VINF_SUCCESS;
    167166    }
    168167
    169     return rc;
     168    PGM_UNLOCK(pVM);
     169    return VERR_OUT_OF_RESOURCES;
    170170}
    171171
     
    194194 * @returns VBox status code.
    195195 * @retval  VINF_SUCCESS when successfully installed.
     196 * @retval  VINF_PGM_GCPHYS_ALIASED could be returned.
    196197 *
    197198 * @param   pVM             The cross context VM structure.
     
    205206     * Validate input.
    206207     */
     208    AssertReturn(pPhysHandler, VERR_INVALID_POINTER);
    207209    PGMPHYSHANDLERTYPE const      hType = pPhysHandler->hType;
    208210    PCPGMPHYSHANDLERTYPEINT const pType = pgmHandlerPhysicalTypeHandleToPtr(pVM, hType);
     
    214216    Log(("pgmHandlerPhysicalExRegister: GCPhys=%RGp GCPhysLast=%RGp hType=%#x (%d, %s) pszDesc=%RHv:%s\n", GCPhys, GCPhysLast,
    215217         hType, pType->enmKind, pType->pszDesc, pPhysHandler->pszDesc, R3STRING(pPhysHandler->pszDesc)));
    216     AssertReturn(pPhysHandler->Core.Key == NIL_RTGCPHYS, VERR_WRONG_ORDER);
     218    AssertReturn(pPhysHandler->Key == NIL_RTGCPHYS, VERR_WRONG_ORDER);
    217219
    218220    AssertMsgReturn(GCPhys < GCPhysLast, ("GCPhys >= GCPhysLast (%#x >= %#x)\n", GCPhys, GCPhysLast), VERR_INVALID_PARAMETER);
     221    Assert(GCPhysLast - GCPhys < _4G); /* ASSUMPTION in PGMAllPhys.cpp */
     222
    219223    switch (pType->enmKind)
    220224    {
     
    252256     * Try insert into list.
    253257     */
    254     pPhysHandler->Core.Key     = GCPhys;
    255     pPhysHandler->Core.KeyLast = GCPhysLast;
    256     pPhysHandler->cPages       = (GCPhysLast - (GCPhys & X86_PTE_PAE_PG_MASK) + GUEST_PAGE_SIZE) >> GUEST_PAGE_SHIFT;
    257 
    258     PGM_LOCK_VOID(pVM);
    259     if (RTAvlroGCPhysInsert(&pVM->pgm.s.CTX_SUFF(pTrees)->PhysHandlers, &pPhysHandler->Core))
    260     {
    261         int rc = pgmHandlerPhysicalSetRamFlagsAndFlushShadowPTs(pVM, pPhysHandler, pRam, NULL /*pvBitmap*/, 0 /*offBitmap*/);
    262         if (rc == VINF_PGM_SYNC_CR3)
    263             rc = VINF_PGM_GCPHYS_ALIASED;
     258    pPhysHandler->Key     = GCPhys;
     259    pPhysHandler->KeyLast = GCPhysLast;
     260    pPhysHandler->cPages  = (GCPhysLast - (GCPhys & X86_PTE_PAE_PG_MASK) + GUEST_PAGE_SIZE) >> GUEST_PAGE_SHIFT;
     261
     262    int rc = PGM_LOCK(pVM);
     263    if (RT_SUCCESS(rc))
     264    {
     265        rc = pVM->VMCC_CTX(pgm).s.pPhysHandlerTree->insert(&pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator, pPhysHandler);
     266        if (RT_SUCCESS(rc))
     267        {
     268            rc = pgmHandlerPhysicalSetRamFlagsAndFlushShadowPTs(pVM, pPhysHandler, pRam, NULL /*pvBitmap*/, 0 /*offBitmap*/);
     269            if (rc == VINF_PGM_SYNC_CR3)
     270                rc = VINF_PGM_GCPHYS_ALIASED;
    264271
    265272#if defined(IN_RING3) || defined(IN_RING0)
    266         NEMHCNotifyHandlerPhysicalRegister(pVM, pType->enmKind, GCPhys, GCPhysLast - GCPhys + 1);
    267 #endif
     273            NEMHCNotifyHandlerPhysicalRegister(pVM, pType->enmKind, GCPhys, GCPhysLast - GCPhys + 1);
     274#endif
     275            PGM_UNLOCK(pVM);
     276
     277            if (rc != VINF_SUCCESS)
     278                Log(("PGMHandlerPhysicalRegisterEx: returns %Rrc (%RGp-%RGp)\n", rc, GCPhys, GCPhysLast));
     279            return rc;
     280        }
    268281        PGM_UNLOCK(pVM);
    269 
    270         if (rc != VINF_SUCCESS)
    271             Log(("PGMHandlerPhysicalRegisterEx: returns %Rrc (%RGp-%RGp)\n", rc, GCPhys, GCPhysLast));
    272         return rc;
    273     }
    274     PGM_UNLOCK(pVM);
    275 
    276     pPhysHandler->Core.Key     = NIL_RTGCPHYS;
    277     pPhysHandler->Core.KeyLast = NIL_RTGCPHYS;
     282    }
     283
     284    pPhysHandler->Key     = NIL_RTGCPHYS;
     285    pPhysHandler->KeyLast = NIL_RTGCPHYS;
     286
     287    AssertMsgReturn(rc == VERR_ALREADY_EXISTS, ("%Rrc GCPhys=%RGp GCPhysLast=%RGp\n", rc, GCPhys, GCPhysLast), rc);
    278288
    279289#if defined(IN_RING3) && defined(VBOX_STRICT)
     
    352362    const unsigned          uState     = pCurType->uState;
    353363    uint32_t                cPages     = pCur->cPages;
    354     uint32_t                i          = (pCur->Core.Key - pRam->GCPhys) >> GUEST_PAGE_SHIFT;
     364    uint32_t                i          = (pCur->Key - pRam->GCPhys) >> GUEST_PAGE_SHIFT;
    355365    for (;;)
    356366    {
     
    415425{
    416426    LogFlow(("pgmHandlerPhysicalExDeregister: Removing Range %RGp-%RGp %s\n",
    417              pPhysHandler->Core.Key, pPhysHandler->Core.KeyLast, R3STRING(pPhysHandler->pszDesc)));
    418     AssertReturn(pPhysHandler->Core.Key != NIL_RTGCPHYS, VERR_PGM_HANDLER_NOT_FOUND);
     427             pPhysHandler->Key, pPhysHandler->KeyLast, R3STRING(pPhysHandler->pszDesc)));
     428
     429    int rc = PGM_LOCK(pVM);
     430    AssertRCReturn(rc, rc);
     431
     432    RTGCPHYS const GCPhys = pPhysHandler->Key;
     433    AssertReturnStmt(GCPhys != NIL_RTGCPHYS, PGM_UNLOCK(pVM), VERR_PGM_HANDLER_NOT_FOUND);
    419434
    420435    /*
    421436     * Remove the handler from the tree.
    422437     */
    423     PGM_LOCK_VOID(pVM);
    424     PPGMPHYSHANDLER pRemoved = (PPGMPHYSHANDLER)RTAvlroGCPhysRemove(&pVM->pgm.s.CTX_SUFF(pTrees)->PhysHandlers,
    425                                                                     pPhysHandler->Core.Key);
    426     if (pRemoved == pPhysHandler)
    427     {
     438
     439    PPGMPHYSHANDLER pRemoved;
     440    rc = pVM->VMCC_CTX(pgm).s.pPhysHandlerTree->remove(&pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator, GCPhys, &pRemoved);
     441    if (RT_SUCCESS(rc))
     442    {
     443        if (pRemoved == pPhysHandler)
     444        {
     445            /*
     446             * Clear the page bits, notify the REM about this change and clear
     447             * the cache.
     448             */
     449            pgmHandlerPhysicalResetRamFlags(pVM, pPhysHandler);
     450            if (VM_IS_NEM_ENABLED(pVM))
     451                pgmHandlerPhysicalDeregisterNotifyNEM(pVM, pPhysHandler);
     452            pVM->pgm.s.idxLastPhysHandler = 0;
     453
     454            pPhysHandler->Key     = NIL_RTGCPHYS;
     455            pPhysHandler->KeyLast = NIL_RTGCPHYS;
     456
     457            PGM_UNLOCK(pVM);
     458
     459            return VINF_SUCCESS;
     460        }
     461
    428462        /*
    429          * Clear the page bits, notify the REM about this change and clear
    430          * the cache.
     463         * Both of the failure conditions here are considered internal processing
     464         * errors because they can only be caused by race conditions or corruption.
     465         * If we ever need to handle concurrent deregistration, we have to move
     466         * the NIL_RTGCPHYS check inside the PGM lock.
    431467         */
    432         pgmHandlerPhysicalResetRamFlags(pVM, pPhysHandler);
    433         if (VM_IS_NEM_ENABLED(pVM))
    434             pgmHandlerPhysicalDeregisterNotifyNEM(pVM, pPhysHandler);
    435         pVM->pgm.s.pLastPhysHandlerR0 = 0;
    436         pVM->pgm.s.pLastPhysHandlerR3 = 0;
    437 
    438         pPhysHandler->Core.Key     = NIL_RTGCPHYS;
    439         pPhysHandler->Core.KeyLast = NIL_RTGCPHYS;
    440 
    441         PGM_UNLOCK(pVM);
    442 
    443         return VINF_SUCCESS;
    444     }
    445 
    446     /*
    447      * Both of the failure conditions here are considered internal processing
    448      * errors because they can only be caused by race conditions or corruption.
    449      * If we ever need to handle concurrent deregistration, we have to move
    450      * the NIL_RTGCPHYS check inside the PGM lock.
    451      */
    452     if (pRemoved)
    453         RTAvlroGCPhysInsert(&pVM->pgm.s.CTX_SUFF(pTrees)->PhysHandlers, &pRemoved->Core);
     468        pVM->VMCC_CTX(pgm).s.pPhysHandlerTree->insert(&pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator, pRemoved);
     469    }
    454470
    455471    PGM_UNLOCK(pVM);
    456472
    457     if (!pRemoved)
    458         AssertMsgFailed(("Didn't find range starting at %RGp in the tree!\n", pPhysHandler->Core.Key));
     473    if (RT_FAILURE(rc))
     474        AssertMsgFailed(("Didn't find range starting at %RGp in the tree! %Rrc=rc\n", GCPhys, rc));
    459475    else
    460476        AssertMsgFailed(("Found different handle at %RGp in the tree: got %p insteaded of %p\n",
    461                          pPhysHandler->Core.Key, pRemoved, pPhysHandler));
     477                         GCPhys, pRemoved, pPhysHandler));
    462478    return VERR_PGM_HANDLER_IPE_1;
    463479}
     
    478494    {
    479495        AssertPtr(pHandler);
    480         AssertReturn(pHandler->Core.Key == NIL_RTGCPHYS, VERR_WRONG_ORDER);
    481         MMHyperFree(pVM, pHandler);
     496        AssertReturn(pHandler->Key == NIL_RTGCPHYS, VERR_WRONG_ORDER);
     497
     498        int rc = PGM_LOCK(pVM);
     499        if (RT_SUCCESS(rc))
     500        {
     501            rc = pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator.freeNode(pHandler);
     502            PGM_UNLOCK(pVM);
     503        }
     504        return rc;
    482505    }
    483506    return VINF_SUCCESS;
     
    494517VMMDECL(int)  PGMHandlerPhysicalDeregister(PVMCC pVM, RTGCPHYS GCPhys)
    495518{
     519    AssertReturn(pVM->VMCC_CTX(pgm).s.pPhysHandlerTree, VERR_PGM_HANDLER_IPE_1);
     520
    496521    /*
    497522     * Find the handler.
    498523     */
    499     PGM_LOCK_VOID(pVM);
    500     PPGMPHYSHANDLER pRemoved = (PPGMPHYSHANDLER)RTAvlroGCPhysRemove(&pVM->pgm.s.CTX_SUFF(pTrees)->PhysHandlers, GCPhys);
    501     if (pRemoved)
    502     {
     524    int rc = PGM_LOCK(pVM);
     525    AssertRCReturn(rc, rc);
     526
     527    PPGMPHYSHANDLER pRemoved;
     528    rc = pVM->VMCC_CTX(pgm).s.pPhysHandlerTree->remove(&pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator, GCPhys, &pRemoved);
     529    if (RT_SUCCESS(rc))
     530    {
     531        Assert(pRemoved->Key == GCPhys);
    503532        LogFlow(("PGMHandlerPhysicalDeregister: Removing Range %RGp-%RGp %s\n",
    504                  pRemoved->Core.Key, pRemoved->Core.KeyLast, R3STRING(pRemoved->pszDesc)));
     533                 pRemoved->Key, pRemoved->KeyLast, R3STRING(pRemoved->pszDesc)));
    505534
    506535        /*
     
    511540        if (VM_IS_NEM_ENABLED(pVM))
    512541            pgmHandlerPhysicalDeregisterNotifyNEM(pVM, pRemoved);
    513         pVM->pgm.s.pLastPhysHandlerR0 = 0;
    514         pVM->pgm.s.pLastPhysHandlerR3 = 0;
     542        pVM->pgm.s.idxLastPhysHandler = 0;
     543
     544        pRemoved->Key = NIL_RTGCPHYS;
     545        rc = pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator.freeNode(pRemoved);
    515546
    516547        PGM_UNLOCK(pVM);
    517 
    518         pRemoved->Core.Key = NIL_RTGCPHYS;
    519         pgmHandlerPhysicalExDestroy(pVM, pRemoved);
    520         return VINF_SUCCESS;
     548        return rc;
    521549    }
    522550
    523551    PGM_UNLOCK(pVM);
    524552
    525     AssertMsgFailed(("Didn't find range starting at %RGp\n", GCPhys));
    526     return VERR_PGM_HANDLER_NOT_FOUND;
     553    if (rc == VERR_NOT_FOUND)
     554    {
     555        AssertMsgFailed(("Didn't find range starting at %RGp\n", GCPhys));
     556        rc = VERR_PGM_HANDLER_NOT_FOUND;
     557    }
     558    return rc;
    527559}
    528560
     
    535567#ifdef VBOX_WITH_NATIVE_NEM
    536568    PCPGMPHYSHANDLERTYPEINT pCurType    = PGMPHYSHANDLER_GET_TYPE_NO_NULL(pVM, pCur);
    537     RTGCPHYS                GCPhysStart = pCur->Core.Key;
    538     RTGCPHYS                GCPhysLast  = pCur->Core.KeyLast;
     569    RTGCPHYS                GCPhysStart = pCur->Key;
     570    RTGCPHYS                GCPhysLast  = pCur->KeyLast;
    539571
    540572    /*
     
    545577     * included in the REM notification or not.
    546578     */
    547     if (   (pCur->Core.Key           & GUEST_PAGE_OFFSET_MASK)
    548         || ((pCur->Core.KeyLast + 1) & GUEST_PAGE_OFFSET_MASK))
     579    if (   (pCur->Key           & GUEST_PAGE_OFFSET_MASK)
     580        || ((pCur->KeyLast + 1) & GUEST_PAGE_OFFSET_MASK))
    549581    {
    550582        Assert(pCurType->enmKind != PGMPHYSHANDLERKIND_MMIO);
     
    614646    for (;;)
    615647    {
    616         PPGMPHYSHANDLER pCur = (PPGMPHYSHANDLER)RTAvlroGCPhysGetBestFit(&pVM->pgm.s.CTX_SUFF(pTrees)->PhysHandlers, GCPhys, fAbove);
    617         if (   !pCur
    618             || ((fAbove ? pCur->Core.Key : pCur->Core.KeyLast) >> GUEST_PAGE_SHIFT) != (GCPhys >> GUEST_PAGE_SHIFT))
     648        PPGMPHYSHANDLER pCur;
     649        int rc;
     650        if (fAbove)
     651            rc = pVM->VMCC_CTX(pgm).s.pPhysHandlerTree->lookupMatchingOrAbove(&pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator,
     652                                                                              GCPhys, &pCur);
     653        else
     654            rc = pVM->VMCC_CTX(pgm).s.pPhysHandlerTree->lookupMatchingOrBelow(&pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator,
     655                                                                              GCPhys, &pCur);
     656        if (rc == VERR_NOT_FOUND)
     657            break;
     658        AssertRCBreak(rc);
     659        if (((fAbove ? pCur->Key : pCur->KeyLast) >> GUEST_PAGE_SHIFT) != (GCPhys >> GUEST_PAGE_SHIFT))
    619660            break;
    620661        PCPGMPHYSHANDLERTYPEINT pCurType = PGMPHYSHANDLER_GET_TYPE_NO_NULL(pVM, pCur);
     
    623664        /* next? */
    624665        RTGCPHYS GCPhysNext = fAbove
    625                             ? pCur->Core.KeyLast + 1
    626                             : pCur->Core.Key - 1;
     666                            ? pCur->KeyLast + 1
     667                            : pCur->Key    - 1;
    627668        if ((GCPhysNext >> GUEST_PAGE_SHIFT) != (GCPhys >> GUEST_PAGE_SHIFT))
    628669            break;
     
    714755    if (fDoAccounting)
    715756    {
    716         PPGMPHYSHANDLER pHandler = pgmHandlerPhysicalLookup(pVM, GCPhysPage);
    717         if (RT_LIKELY(pHandler))
     757        PPGMPHYSHANDLER pHandler;
     758        rc = pgmHandlerPhysicalLookup(pVM, GCPhysPage, &pHandler);
     759        if (RT_SUCCESS(rc))
    718760        {
    719761            Assert(pHandler->cAliasedPages > 0);
     
    721763        }
    722764        else
    723             AssertFailed();
     765            AssertMsgFailed(("rc=%Rrc GCPhysPage=%RGp\n", rc, GCPhysPage));
    724766    }
    725767
     
    760802     */
    761803    RTUINT          cPages   = pCur->cPages;
    762     RTGCPHYS        GCPhys   = pCur->Core.Key;
     804    RTGCPHYS        GCPhys   = pCur->Key;
    763805    PPGMRAMRANGE    pRamHint = NULL;
    764806    for (;;)
     
    815857     * Check for partial start and end pages.
    816858     */
    817     if (pCur->Core.Key & GUEST_PAGE_OFFSET_MASK)
    818         pgmHandlerPhysicalRecalcPageState(pVM, pCur->Core.Key - 1, false /* fAbove */, &pRamHint);
    819     if ((pCur->Core.KeyLast & GUEST_PAGE_OFFSET_MASK) != GUEST_PAGE_OFFSET_MASK)
    820         pgmHandlerPhysicalRecalcPageState(pVM, pCur->Core.KeyLast + 1, true /* fAbove */, &pRamHint);
     859    if (pCur->Key & GUEST_PAGE_OFFSET_MASK)
     860        pgmHandlerPhysicalRecalcPageState(pVM, pCur->Key - 1, false /* fAbove */, &pRamHint);
     861    if ((pCur->KeyLast & GUEST_PAGE_OFFSET_MASK) != GUEST_PAGE_OFFSET_MASK)
     862        pgmHandlerPhysicalRecalcPageState(pVM, pCur->KeyLast + 1, true /* fAbove */, &pRamHint);
    821863}
    822864
     
    945987     * Find the handler and make the change.
    946988     */
    947     int rc;
    948     PGM_LOCK_VOID(pVM);
    949     PPGMPHYSHANDLER pCur = (PPGMPHYSHANDLER)RTAvlroGCPhysGet(&pVM->pgm.s.CTX_SUFF(pTrees)->PhysHandlers, GCPhys);
    950     if (pCur)
    951     {
     989    int rc = PGM_LOCK(pVM);
     990    AssertRCReturn(rc, rc);
     991
     992    PPGMPHYSHANDLER pCur;
     993    rc = pVM->VMCC_CTX(pgm).s.pPhysHandlerTree->lookup(&pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator, GCPhys, &pCur);
     994    if (RT_SUCCESS(rc))
     995    {
     996        Assert(pCur->Key == GCPhys);
    952997        pCur->uUser = uUser;
    953         rc = VINF_SUCCESS;
    954     }
    955     else
     998    }
     999    else if (rc == VERR_NOT_FOUND)
    9561000    {
    9571001        AssertMsgFailed(("Didn't find range starting at %RGp\n", GCPhys));
     
    11251169{
    11261170    LogFlow(("PGMHandlerPhysicalReset GCPhys=%RGp\n", GCPhys));
    1127     PGM_LOCK_VOID(pVM);
     1171    int rc = PGM_LOCK(pVM);
     1172    AssertRCReturn(rc, rc);
    11281173
    11291174    /*
    11301175     * Find the handler.
    11311176     */
    1132     int rc;
    1133     PPGMPHYSHANDLER pCur = (PPGMPHYSHANDLER)RTAvlroGCPhysGet(&pVM->pgm.s.CTX_SUFF(pTrees)->PhysHandlers, GCPhys);
    1134     if (RT_LIKELY(pCur))
    1135     {
     1177    PPGMPHYSHANDLER pCur;
     1178    rc = pVM->VMCC_CTX(pgm).s.pPhysHandlerTree->lookup(&pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator, GCPhys, &pCur);
     1179    if (RT_SUCCESS(rc))
     1180    {
     1181        Assert(pCur->Key == GCPhys);
     1182
    11361183        /*
    11371184         * Validate kind.
     
    11471194                PPGMRAMRANGE pRam = pgmPhysGetRange(pVM, GCPhys);
    11481195                Assert(pRam);
    1149                 Assert(pRam->GCPhys     <= pCur->Core.Key);
    1150                 Assert(pRam->GCPhysLast >= pCur->Core.KeyLast);
     1196                Assert(pRam->GCPhys     <= pCur->Key);
     1197                Assert(pRam->GCPhysLast >= pCur->KeyLast);
    11511198
    11521199                if (pCurType->enmKind == PGMPHYSHANDLERKIND_MMIO)
     
    11591206                    if (pCur->cAliasedPages)
    11601207                    {
    1161                         PPGMPAGE    pPage      = &pRam->aPages[(pCur->Core.Key - pRam->GCPhys) >> GUEST_PAGE_SHIFT];
    1162                         RTGCPHYS    GCPhysPage = pCur->Core.Key;
     1208                        PPGMPAGE    pPage      = &pRam->aPages[(pCur->Key - pRam->GCPhys) >> GUEST_PAGE_SHIFT];
     1209                        RTGCPHYS    GCPhysPage = pCur->Key;
    11631210                        uint32_t    cLeft      = pCur->cPages;
    11641211                        while (cLeft-- > 0)
     
    12061253        }
    12071254    }
    1208     else
     1255    else if (rc == VERR_NOT_FOUND)
    12091256    {
    12101257        AssertMsgFailed(("Didn't find MMIO Range starting at %#x\n", GCPhys));
     
    12381285     * Find the handler.
    12391286     */
    1240     int rc;
    1241     PPGMPHYSHANDLER pCur = (PPGMPHYSHANDLER)RTAvlroGCPhysGet(&pVM->pgm.s.CTX_SUFF(pTrees)->PhysHandlers, GCPhys);
    1242     if (RT_LIKELY(pCur))
    1243     {
     1287    PPGMPHYSHANDLER pCur;
     1288    int rc = pVM->VMCC_CTX(pgm).s.pPhysHandlerTree->lookup(&pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator, GCPhys, &pCur);
     1289    if (RT_SUCCESS(rc))
     1290    {
     1291        Assert(pCur->Key == GCPhys);
     1292
    12441293        /*
    12451294         * Validate kind.
     
    12531302            PPGMRAMRANGE pRam = pgmPhysGetRange(pVM, GCPhys);
    12541303            Assert(pRam);
    1255             Assert(pRam->GCPhys     <= pCur->Core.Key);
    1256             Assert(pRam->GCPhysLast >= pCur->Core.KeyLast);
     1304            Assert(pRam->GCPhys     <= pCur->Key);
     1305            Assert(pRam->GCPhysLast >= pCur->KeyLast);
    12571306
    12581307            /*
     
    12731322        }
    12741323    }
    1275     else
     1324    else if (rc == VERR_NOT_FOUND)
    12761325    {
    12771326        AssertMsgFailed(("Didn't find MMIO Range starting at %#x\n", GCPhys));
     
    13051354{
    13061355    LogFlow(("PGMHandlerPhysicalPageTempOff GCPhysPage=%RGp\n", GCPhysPage));
    1307     PGM_LOCK_VOID(pVM);
     1356    int rc = PGM_LOCK(pVM);
     1357    AssertRCReturn(rc, rc);
    13081358
    13091359    /*
    13101360     * Validate the range.
    13111361     */
    1312     PPGMPHYSHANDLER pCur = (PPGMPHYSHANDLER)RTAvlroGCPhysGet(&pVM->pgm.s.CTX_SUFF(pTrees)->PhysHandlers, GCPhys);
    1313     if (RT_LIKELY(pCur))
    1314     {
    1315         if (RT_LIKELY(   GCPhysPage >= pCur->Core.Key
    1316                       && GCPhysPage <= pCur->Core.KeyLast))
    1317         {
    1318             Assert(!(pCur->Core.Key & GUEST_PAGE_OFFSET_MASK));
    1319             Assert((pCur->Core.KeyLast & GUEST_PAGE_OFFSET_MASK) == GUEST_PAGE_OFFSET_MASK);
     1362    PPGMPHYSHANDLER pCur;
     1363    rc = pVM->VMCC_CTX(pgm).s.pPhysHandlerTree->lookup(&pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator, GCPhys, &pCur);
     1364    if (RT_SUCCESS(rc))
     1365    {
     1366        Assert(pCur->Key == GCPhys);
     1367        if (RT_LIKELY(   GCPhysPage >= pCur->Key
     1368                      && GCPhysPage <= pCur->KeyLast))
     1369        {
     1370            Assert(!(pCur->Key & GUEST_PAGE_OFFSET_MASK));
     1371            Assert((pCur->KeyLast & GUEST_PAGE_OFFSET_MASK) == GUEST_PAGE_OFFSET_MASK);
    13201372
    13211373            PCPGMPHYSHANDLERTYPEINT const pCurType = PGMPHYSHANDLER_GET_TYPE(pVM, pCur);
     
    13301382            PPGMPAGE     pPage;
    13311383            PPGMRAMRANGE pRam;
    1332             int rc = pgmPhysGetPageAndRangeEx(pVM, GCPhysPage, &pPage, &pRam);
     1384            rc = pgmPhysGetPageAndRangeEx(pVM, GCPhysPage, &pPage, &pRam);
    13331385            AssertReturnStmt(RT_SUCCESS_NP(rc), PGM_UNLOCK(pVM), rc);
    13341386            if (PGM_PAGE_GET_HNDL_PHYS_STATE(pPage) != PGM_PAGE_HNDL_PHYS_STATE_DISABLED)
     
    13541406        }
    13551407        PGM_UNLOCK(pVM);
    1356         AssertMsgFailed(("The page %#x is outside the range %#x-%#x\n",
    1357                          GCPhysPage, pCur->Core.Key, pCur->Core.KeyLast));
     1408        AssertMsgFailed(("The page %#x is outside the range %#x-%#x\n", GCPhysPage, pCur->Key, pCur->KeyLast));
    13581409        return VERR_INVALID_PARAMETER;
    13591410    }
    13601411    PGM_UNLOCK(pVM);
    1361     AssertMsgFailed(("Specified physical handler start address %#x is invalid.\n", GCPhys));
    1362     return VERR_PGM_HANDLER_NOT_FOUND;
     1412
     1413    if (rc == VERR_NOT_FOUND)
     1414    {
     1415        AssertMsgFailed(("Specified physical handler start address %#x is invalid.\n", GCPhys));
     1416        return VERR_PGM_HANDLER_NOT_FOUND;
     1417    }
     1418    return rc;
    13631419}
    13641420
     
    14611517    AssertReturn(!VM_IS_NEM_ENABLED(pVM) || !pVM->pgm.s.fNemMode, VERR_PGM_NOT_SUPPORTED_FOR_NEM_MODE);
    14621518#endif
    1463     PGM_LOCK_VOID(pVM);
     1519    int rc = PGM_LOCK(pVM);
     1520    AssertRCReturn(rc, rc);
    14641521
    14651522    /*
     
    14801537     * Lookup and validate the range.
    14811538     */
    1482     PPGMPHYSHANDLER pCur = (PPGMPHYSHANDLER)RTAvlroGCPhysGet(&pVM->pgm.s.CTX_SUFF(pTrees)->PhysHandlers, GCPhys);
    1483     if (RT_LIKELY(pCur))
    1484     {
    1485         if (RT_LIKELY(   GCPhysPage >= pCur->Core.Key
    1486                       && GCPhysPage <= pCur->Core.KeyLast))
     1539    PPGMPHYSHANDLER pCur;
     1540    rc = pVM->VMCC_CTX(pgm).s.pPhysHandlerTree->lookup(&pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator, GCPhys, &pCur);
     1541    if (RT_SUCCESS(rc))
     1542    {
     1543        Assert(pCur->Key == GCPhys);
     1544        if (RT_LIKELY(   GCPhysPage >= pCur->Key
     1545                      && GCPhysPage <= pCur->KeyLast))
    14871546        {
    14881547            PCPGMPHYSHANDLERTYPEINT const pCurType = PGMPHYSHANDLER_GET_TYPE_NO_NULL(pVM, pCur);
    14891548            AssertReturnStmt(pCurType->enmKind == PGMPHYSHANDLERKIND_MMIO, PGM_UNLOCK(pVM), VERR_ACCESS_DENIED);
    1490             AssertReturnStmt(!(pCur->Core.Key & GUEST_PAGE_OFFSET_MASK), PGM_UNLOCK(pVM), VERR_INVALID_PARAMETER);
    1491             AssertReturnStmt((pCur->Core.KeyLast & GUEST_PAGE_OFFSET_MASK) == GUEST_PAGE_OFFSET_MASK,
     1549            AssertReturnStmt(!(pCur->Key & GUEST_PAGE_OFFSET_MASK), PGM_UNLOCK(pVM), VERR_INVALID_PARAMETER);
     1550            AssertReturnStmt((pCur->KeyLast & GUEST_PAGE_OFFSET_MASK) == GUEST_PAGE_OFFSET_MASK,
    14921551                             PGM_UNLOCK(pVM), VERR_INVALID_PARAMETER);
    14931552
     
    14971556            PPGMPAGE     pPage;
    14981557            PPGMRAMRANGE pRam;
    1499             int rc = pgmPhysGetPageAndRangeEx(pVM, GCPhysPage, &pPage, &pRam);
     1558            rc = pgmPhysGetPageAndRangeEx(pVM, GCPhysPage, &pPage, &pRam);
    15001559            AssertReturnStmt(RT_SUCCESS_NP(rc), PGM_UNLOCK(pVM), rc);
    15011560            if (PGM_PAGE_GET_TYPE(pPage) != PGMPAGETYPE_MMIO)
     
    15561615
    15571616        PGM_UNLOCK(pVM);
    1558         AssertMsgFailed(("The page %#x is outside the range %#x-%#x\n",
    1559                          GCPhysPage, pCur->Core.Key, pCur->Core.KeyLast));
     1617        AssertMsgFailed(("The page %#x is outside the range %#x-%#x\n", GCPhysPage, pCur->Key, pCur->KeyLast));
    15601618        return VERR_INVALID_PARAMETER;
    15611619    }
    15621620
    15631621    PGM_UNLOCK(pVM);
    1564     AssertMsgFailed(("Specified physical handler start address %#x is invalid.\n", GCPhys));
    1565     return VERR_PGM_HANDLER_NOT_FOUND;
     1622    if (rc == VERR_NOT_FOUND)
     1623    {
     1624        AssertMsgFailed(("Specified physical handler start address %#x is invalid.\n", GCPhys));
     1625        return VERR_PGM_HANDLER_NOT_FOUND;
     1626    }
     1627    return rc;
    15661628}
    15671629
     
    16041666    AssertReturn(!VM_IS_NEM_ENABLED(pVM) || !pVM->pgm.s.fNemMode, VERR_PGM_NOT_SUPPORTED_FOR_NEM_MODE);
    16051667#endif
    1606     PGM_LOCK_VOID(pVM);
     1668    int rc = PGM_LOCK(pVM);
     1669    AssertRCReturn(rc, rc);
    16071670
    16081671    /*
    16091672     * Lookup and validate the range.
    16101673     */
    1611     PPGMPHYSHANDLER pCur = (PPGMPHYSHANDLER)RTAvlroGCPhysGet(&pVM->pgm.s.CTX_SUFF(pTrees)->PhysHandlers, GCPhys);
    1612     if (RT_LIKELY(pCur))
    1613     {
    1614         if (RT_LIKELY(    GCPhysPage >= pCur->Core.Key
    1615                       &&  GCPhysPage <= pCur->Core.KeyLast))
     1674    PPGMPHYSHANDLER pCur;
     1675    rc = pVM->VMCC_CTX(pgm).s.pPhysHandlerTree->lookup(&pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator, GCPhys, &pCur);
     1676    if (RT_SUCCESS(rc))
     1677    {
     1678        Assert(pCur->Key == GCPhys);
     1679        if (RT_LIKELY(    GCPhysPage >= pCur->Key
     1680                      &&  GCPhysPage <= pCur->KeyLast))
    16161681        {
    16171682            PCPGMPHYSHANDLERTYPEINT const pCurType = PGMPHYSHANDLER_GET_TYPE_NO_NULL(pVM, pCur);
    16181683            AssertReturnStmt(pCurType->enmKind == PGMPHYSHANDLERKIND_MMIO, PGM_UNLOCK(pVM), VERR_ACCESS_DENIED);
    1619             AssertReturnStmt(!(pCur->Core.Key & GUEST_PAGE_OFFSET_MASK), PGM_UNLOCK(pVM), VERR_INVALID_PARAMETER);
    1620             AssertReturnStmt((pCur->Core.KeyLast & GUEST_PAGE_OFFSET_MASK) == GUEST_PAGE_OFFSET_MASK,
     1684            AssertReturnStmt(!(pCur->Key & GUEST_PAGE_OFFSET_MASK), PGM_UNLOCK(pVM), VERR_INVALID_PARAMETER);
     1685            AssertReturnStmt((pCur->KeyLast & GUEST_PAGE_OFFSET_MASK) == GUEST_PAGE_OFFSET_MASK,
    16211686                             PGM_UNLOCK(pVM), VERR_INVALID_PARAMETER);
    16221687
     
    16251690             */
    16261691            PPGMPAGE pPage;
    1627             int rc = pgmPhysGetPageEx(pVM, GCPhysPage, &pPage);
     1692            rc = pgmPhysGetPageEx(pVM, GCPhysPage, &pPage);
    16281693            AssertReturnStmt(RT_SUCCESS_NP(rc), PGM_UNLOCK(pVM), rc);
    16291694            if (PGM_PAGE_GET_TYPE(pPage) != PGMPAGETYPE_MMIO)
     
    16731738        }
    16741739        PGM_UNLOCK(pVM);
    1675         AssertMsgFailed(("The page %#x is outside the range %#x-%#x\n",
    1676                          GCPhysPage, pCur->Core.Key, pCur->Core.KeyLast));
     1740        AssertMsgFailed(("The page %#x is outside the range %#x-%#x\n", GCPhysPage, pCur->Key, pCur->KeyLast));
    16771741        return VERR_INVALID_PARAMETER;
    16781742    }
    16791743    PGM_UNLOCK(pVM);
    16801744
    1681     AssertMsgFailed(("Specified physical handler start address %#x is invalid.\n", GCPhys));
    1682     return VERR_PGM_HANDLER_NOT_FOUND;
     1745    if (rc == VERR_NOT_FOUND)
     1746    {
     1747        AssertMsgFailed(("Specified physical handler start address %#x is invalid.\n", GCPhys));
     1748        return VERR_PGM_HANDLER_NOT_FOUND;
     1749    }
     1750    return rc;
    16831751}
    16841752
     
    16991767     */
    17001768    PGM_LOCK_VOID(pVM);
    1701     PPGMPHYSHANDLER pCur = pgmHandlerPhysicalLookup(pVM, GCPhys);
    1702     if (pCur)
     1769    PPGMPHYSHANDLER pCur;
     1770    int rc = pgmHandlerPhysicalLookup(pVM, GCPhys, &pCur);
     1771    if (RT_SUCCESS(rc))
    17031772    {
    17041773#ifdef VBOX_STRICT
    1705         Assert(GCPhys >= pCur->Core.Key && GCPhys <= pCur->Core.KeyLast);
     1774        Assert(GCPhys >= pCur->Key && GCPhys <= pCur->KeyLast);
    17061775        PCPGMPHYSHANDLERTYPEINT const pCurType = PGMPHYSHANDLER_GET_TYPE_NO_NULL(pVM, pCur);
    17071776        Assert(   pCurType->enmKind == PGMPHYSHANDLERKIND_WRITE
     
    17311800{
    17321801    PGM_LOCK_VOID(pVM);
    1733     PPGMPHYSHANDLER pCur = pgmHandlerPhysicalLookup(pVM, GCPhys);
    1734     if (!pCur)
    1735     {
    1736         PGM_UNLOCK(pVM);
    1737         AssertFailed();
    1738         return true;
    1739     }
     1802    PPGMPHYSHANDLER pCur;
     1803    int rc = pgmHandlerPhysicalLookup(pVM, GCPhys, &pCur);
     1804    AssertRCReturnStmt(rc, PGM_UNLOCK(pVM), true);
    17401805
    17411806    /* Only whole pages can be disabled. */
    1742     Assert(   pCur->Core.Key     <= (GCPhys & ~(RTGCPHYS)GUEST_PAGE_OFFSET_MASK)
    1743            && pCur->Core.KeyLast >= (GCPhys | GUEST_PAGE_OFFSET_MASK));
     1807    Assert(   pCur->Key     <= (GCPhys & ~(RTGCPHYS)GUEST_PAGE_OFFSET_MASK)
     1808           && pCur->KeyLast >= (GCPhys | GUEST_PAGE_OFFSET_MASK));
    17441809
    17451810    PCPGMPHYSHANDLERTYPEINT const pCurType = PGMPHYSHANDLER_GET_TYPE_NO_NULL(pVM, pCur);
     
    17891854     * Check the RAM flags against the handlers.
    17901855     */
     1856    PPGMPHYSHANDLERTREE const pPhysHandlerTree = pVM->VMCC_CTX(pgm).s.pPhysHandlerTree;
    17911857    for (PPGMRAMRANGE pRam = pPGM->CTX_SUFF(pRamRangesX); pRam; pRam = pRam->CTX_SUFF(pNext))
    17921858    {
     
    18061872                {
    18071873                    /* the first */
    1808                     PPGMPHYSHANDLER pPhys = (PPGMPHYSHANDLER)RTAvlroGCPhysRangeGet(&pPGM->CTX_SUFF(pTrees)->PhysHandlers, State.GCPhys);
    1809                     if (!pPhys)
     1874                    PPGMPHYSHANDLER pPhys;
     1875                    int rc = pPhysHandlerTree->lookup(&pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator, State.GCPhys, &pPhys);
     1876                    if (rc == VERR_NOT_FOUND)
    18101877                    {
    1811                         pPhys = (PPGMPHYSHANDLER)RTAvlroGCPhysGetBestFit(&pPGM->CTX_SUFF(pTrees)->PhysHandlers, State.GCPhys, true);
    1812                         if (    pPhys
    1813                             &&  pPhys->Core.Key > (State.GCPhys + GUEST_PAGE_SIZE - 1))
    1814                             pPhys = NULL;
    1815                         Assert(!pPhys || pPhys->Core.Key >= State.GCPhys);
     1878                        rc = pPhysHandlerTree->lookupMatchingOrAbove(&pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator,
     1879                                                                     State.GCPhys, &pPhys);
     1880                        if (RT_SUCCESS(rc))
     1881                        {
     1882                            Assert(pPhys->Key >= State.GCPhys);
     1883                            if (pPhys->Key > (State.GCPhys + GUEST_PAGE_SIZE - 1))
     1884                                pPhys = NULL;
     1885                        }
     1886                        else
     1887                            AssertLogRelMsgReturn(rc == VERR_NOT_FOUND, ("rc=%Rrc GCPhys=%RGp\n", rc, State.GCPhys), 999);
    18161888                    }
     1889                    else
     1890                        AssertLogRelMsgReturn(RT_SUCCESS(rc), ("rc=%Rrc GCPhys=%RGp\n", rc, State.GCPhys), 999);
     1891
    18171892                    if (pPhys)
    18181893                    {
     
    18211896
    18221897                        /* more? */
    1823                         while (pPhys->Core.KeyLast < (State.GCPhys | GUEST_PAGE_OFFSET_MASK))
     1898                        while (pPhys->KeyLast < (State.GCPhys | GUEST_PAGE_OFFSET_MASK))
    18241899                        {
    1825                             PPGMPHYSHANDLER pPhys2 = (PPGMPHYSHANDLER)RTAvlroGCPhysGetBestFit(&pPGM->CTX_SUFF(pTrees)->PhysHandlers,
    1826                                                                                               pPhys->Core.KeyLast + 1, true);
    1827                             if (    !pPhys2
    1828                                 ||  pPhys2->Core.Key > (State.GCPhys | GUEST_PAGE_OFFSET_MASK))
     1900                            PPGMPHYSHANDLER pPhys2;
     1901                            rc = pPhysHandlerTree->lookupMatchingOrAbove(&pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator,
     1902                                                                         pPhys->KeyLast + 1, &pPhys2);
     1903                            if (rc == VERR_NOT_FOUND)
     1904                                break;
     1905                            AssertLogRelMsgReturn(RT_SUCCESS(rc), ("rc=%Rrc KeyLast+1=%RGp\n", rc, pPhys->KeyLast + 1), 999);
     1906                            if (pPhys2->Key > (State.GCPhys | GUEST_PAGE_OFFSET_MASK))
    18291907                                break;
    18301908                            PCPGMPHYSHANDLERTYPEINT pPhysType2 = pgmHandlerPhysicalTypeHandleToPtr(pVM, pPhys2->hType);
  • trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp

    r93650 r93716  
    112112#endif
    113113
     114
     115
     116/**
     117 * Calculate the actual table size.
     118 *
     119 * The memory is layed out like this:
     120 *      - PGMPHYSHANDLERTREE (8 bytes)
     121 *      - Allocation bitmap (8-byte size align)
     122 *      - Slab of PGMPHYSHANDLER. Start is 64 byte aligned.
     123 */
     124uint32_t pgmHandlerPhysicalCalcTableSizes(uint32_t *pcEntries, uint32_t *pcbTreeAndBitmap)
     125{
     126    /*
     127     * A minimum of 64 entries and a maximum of ~64K.
     128     */
     129    uint32_t cEntries = *pcEntries;
     130    if (cEntries <= 64)
     131        cEntries = 64;
     132    else if (cEntries >= _64K)
     133        cEntries = _64K;
     134    else
     135        cEntries = RT_ALIGN_32(cEntries, 16);
     136
     137    /*
     138     * Do the initial calculation.
     139     */
     140    uint32_t cbBitmap        = RT_ALIGN_32(cEntries, 64) / 8;
     141    uint32_t cbTreeAndBitmap = RT_ALIGN_32(sizeof(PGMPHYSHANDLERTREE) + cbBitmap, 64);
     142    uint32_t cbTable         = cEntries * sizeof(PGMPHYSHANDLER);
     143    uint32_t cbTotal         = cbTreeAndBitmap + cbTable;
     144
     145    /*
     146     * Align the total and try use up extra space from that.
     147     */
     148    uint32_t cbTotalAligned = RT_ALIGN_32(cbTotal, RT_MAX(HOST_PAGE_SIZE, _16K));
     149    uint32_t cAvail         = cbTotalAligned - cbTotal;
     150    cAvail /= sizeof(PGMPHYSHANDLER);
     151    if (cAvail >= 1)
     152        for (;;)
     153        {
     154            cbBitmap        = RT_ALIGN_32(cEntries, 64) / 8;
     155            cbTreeAndBitmap = RT_ALIGN_32(sizeof(PGMPHYSHANDLERTREE) + cbBitmap, 64);
     156            cbTable         = cEntries * sizeof(PGMPHYSHANDLER);
     157            cbTotal         = cbTreeAndBitmap + cbTable;
     158            if (cbTotal <= cbTotalAligned)
     159                break;
     160            cEntries--;
     161            Assert(cEntries >= 16);
     162        }
     163
     164    /*
     165     * Return the result.
     166     */
     167    *pcbTreeAndBitmap = cbTreeAndBitmap;
     168    *pcEntries        = cEntries;
     169    return cbTotalAligned;
     170}
    114171
    115172
     
    24072464        || PGM_PAGE_IS_MMIO_OR_SPECIAL_ALIAS(pPage))
    24082465    {
    2409         PPGMPHYSHANDLER pCur = pgmHandlerPhysicalLookup(pVM, GCPhys);
    2410         if (pCur)
    2411         {
    2412             Assert(pCur && GCPhys >= pCur->Core.Key && GCPhys <= pCur->Core.KeyLast);
    2413             Assert((pCur->Core.Key     & GUEST_PAGE_OFFSET_MASK) == 0);
    2414             Assert((pCur->Core.KeyLast & GUEST_PAGE_OFFSET_MASK) == GUEST_PAGE_OFFSET_MASK);
     2466        PPGMPHYSHANDLER pCur;
     2467        rc = pgmHandlerPhysicalLookup(pVM, GCPhys, &pCur);
     2468        if (RT_SUCCESS(rc))
     2469        {
     2470            Assert(pCur && GCPhys >= pCur->Key && GCPhys <= pCur->KeyLast);
     2471            Assert((pCur->Key     & GUEST_PAGE_OFFSET_MASK) == 0);
     2472            Assert((pCur->KeyLast & GUEST_PAGE_OFFSET_MASK) == GUEST_PAGE_OFFSET_MASK);
    24152473#ifndef IN_RING3
    24162474            if (enmOrigin != PGMACCESSORIGIN_IEM)
     
    24352493            PGM_LOCK_VOID(pVM);
    24362494
    2437 #ifdef VBOX_WITH_STATISTICS
    2438             pCur = pgmHandlerPhysicalLookup(pVM, GCPhys);
    2439             if (pCur)
    2440                 STAM_PROFILE_STOP(&pCur->Stat, h);
    2441 #else
     2495            STAM_PROFILE_STOP(&pCur->Stat, h); /* no locking needed, entry is unlikely reused before we get here. */
    24422496            pCur = NULL; /* might not be valid anymore. */
    2443 #endif
    24442497            AssertLogRelMsg(PGM_HANDLER_PHYS_IS_VALID_STATUS(rcStrict, false),
    24452498                            ("rcStrict=%Rrc GCPhys=%RGp\n", VBOXSTRICTRC_VAL(rcStrict), GCPhys));
     
    24512504            }
    24522505        }
     2506        else if (rc == VERR_NOT_FOUND)
     2507            AssertLogRelMsgFailed(("rc=%Rrc GCPhys=%RGp cb=%#x\n", rc, GCPhys, cb));
    24532508        else
    2454             AssertLogRelMsgFailed(("GCPhys=%RGp cb=%#x\n", GCPhys, cb));
     2509            AssertLogRelMsgFailedReturn(("rc=%Rrc GCPhys=%RGp cb=%#x\n", rc, GCPhys, cb), rc);
    24552510    }
    24562511
     
    26462701     */
    26472702    PVMCPUCC pVCpu = VMMGetCpu(pVM);
    2648     PPGMPHYSHANDLER pCur = pgmHandlerPhysicalLookup(pVM, GCPhys);
    2649     if (pCur)
    2650     {
    2651         Assert(GCPhys >= pCur->Core.Key && GCPhys <= pCur->Core.KeyLast);
     2703    PPGMPHYSHANDLER pCur;
     2704    rcStrict = pgmHandlerPhysicalLookup(pVM, GCPhys, &pCur);
     2705    if (RT_SUCCESS(rcStrict))
     2706    {
     2707        Assert(GCPhys >= pCur->Key && GCPhys <= pCur->KeyLast);
    26522708#ifndef IN_RING3
    26532709        if (enmOrigin != PGMACCESSORIGIN_IEM)
     
    26552711            return VERR_PGM_PHYS_WR_HIT_HANDLER;
    26562712#endif
    2657         size_t cbRange = pCur->Core.KeyLast - GCPhys + 1;
     2713        size_t cbRange = pCur->KeyLast - GCPhys + 1;
    26582714        if (cbRange > cbWrite)
    26592715            cbRange = cbWrite;
     
    26872743            }
    26882744
    2689 #ifdef VBOX_WITH_STATISTICS
    2690             pCur = pgmHandlerPhysicalLookup(pVM, GCPhys);
    2691             if (pCur)
    2692                 STAM_PROFILE_STOP(&pCur->Stat, h);
    2693 #else
     2745            STAM_PROFILE_STOP(&pCur->Stat, h); /* no locking needed, entry is unlikely reused before we get here. */
    26942746            pCur = NULL; /* might not be valid anymore. */
    2695 #endif
    26962747            if (rcStrict == VINF_PGM_HANDLER_DO_DEFAULT)
    26972748            {
     
    27212772        pvDst    = (uint8_t *)pvDst + cbRange;
    27222773    }
    2723     else /* The handler is somewhere else in the page, deal with it below. */
     2774    else if (rcStrict == VERR_NOT_FOUND) /* The handler is somewhere else in the page, deal with it below. */
    27242775        rcStrict = VINF_SUCCESS;
     2776    else
     2777        AssertMsgFailedReturn(("rcStrict=%Rrc GCPhys=%RGp\n", VBOXSTRICTRC_VAL(rcStrict), GCPhys), rcStrict);
    27252778    Assert(!PGM_PAGE_IS_MMIO_OR_ALIAS(pPage)); /* MMIO handlers are all GUEST_PAGE_SIZEed! */
    27262779
     
    27522805        if (fMorePhys && !pPhys)
    27532806        {
    2754             pPhys = pgmHandlerPhysicalLookup(pVM, GCPhys);
    2755             if (pPhys)
     2807            rcStrict = pgmHandlerPhysicalLookup(pVM, GCPhys, &pPhys);
     2808            if (RT_SUCCESS_NP(rcStrict))
    27562809            {
    27572810                offPhys = 0;
    2758                 offPhysLast = pPhys->Core.KeyLast - GCPhys; /* ASSUMES < 4GB handlers... */
     2811                offPhysLast = pPhys->KeyLast - GCPhys; /* ASSUMES < 4GB handlers... */
    27592812            }
    27602813            else
    27612814            {
    2762                 pPhys = (PPGMPHYSHANDLER)RTAvlroGCPhysGetBestFit(&pVM->pgm.s.CTX_SUFF(pTrees)->PhysHandlers,
    2763                                                                  GCPhys, true /* fAbove */);
    2764                 if (    pPhys
    2765                     &&  pPhys->Core.Key <= GCPhys + (cbWrite - 1))
     2815                AssertMsgReturn(rcStrict == VERR_NOT_FOUND, ("%Rrc GCPhys=%RGp\n", VBOXSTRICTRC_VAL(rcStrict), GCPhys), rcStrict);
     2816
     2817                rcStrict = pVM->VMCC_CTX(pgm).s.pPhysHandlerTree->lookupMatchingOrAbove(&pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator,
     2818                                                                                        GCPhys, &pPhys);
     2819                AssertMsgReturn(RT_SUCCESS(rcStrict) || rcStrict == VERR_NOT_FOUND,
     2820                                ("%Rrc GCPhys=%RGp\n", VBOXSTRICTRC_VAL(rcStrict), GCPhys), rcStrict);
     2821
     2822                if (   RT_SUCCESS(rcStrict)
     2823                    && pPhys->Key <= GCPhys + (cbWrite - 1))
    27662824                {
    2767                     offPhys     = pPhys->Core.Key     - GCPhys;
    2768                     offPhysLast = pPhys->Core.KeyLast - GCPhys; /* ASSUMES < 4GB handlers... */
     2825                    offPhys     = pPhys->Key     - GCPhys;
     2826                    offPhysLast = pPhys->KeyLast - GCPhys; /* ASSUMES < 4GB handlers... */
     2827                    Assert(pPhys->KeyLast - pPhys->Key < _4G);
    27692828                }
    27702829                else
     
    28182877            }
    28192878
    2820 #ifdef VBOX_WITH_STATISTICS
    2821             pPhys = pgmHandlerPhysicalLookup(pVM, GCPhys);
    2822             if (pPhys)
    2823                 STAM_PROFILE_STOP(&pPhys->Stat, h);
    2824 #else
     2879            STAM_PROFILE_STOP(&pPhys->Stat, h); /* no locking needed, entry is unlikely reused before we get here. */
    28252880            pPhys = NULL; /* might not be valid anymore. */
    2826 #endif
    28272881            AssertLogRelMsg(PGM_HANDLER_PHYS_IS_VALID_STATUS(rcStrict2, true),
    28282882                            ("rcStrict2=%Rrc (rcStrict=%Rrc) GCPhys=%RGp pPage=%R[pgmpage] %s\n", VBOXSTRICTRC_VAL(rcStrict2),
  • trunk/src/VBox/VMM/VMMR0/PGMR0.cpp

    r93650 r93716  
    3535#include <iprt/mem.h>
    3636#include <iprt/memobj.h>
     37#include <iprt/process.h>
    3738#include <iprt/rand.h>
    3839#include <iprt/string.h>
     
    8283        pGVM->pgmr0.s.ahPoolMapObjs[i] = NIL_RTR0MEMOBJ;
    8384    }
     85    pGVM->pgmr0.s.hPhysHandlerMemObj = NIL_RTR0MEMOBJ;
     86    pGVM->pgmr0.s.hPhysHandlerMapObj = NIL_RTR0MEMOBJ;
    8487
    8588    /*
     
    251254            pGVM->pgmr0.s.ahPoolMemObjs[i] = NIL_RTR0MEMOBJ;
    252255        }
     256    }
     257
     258    if (pGVM->pgmr0.s.hPhysHandlerMapObj != NIL_RTR0MEMOBJ)
     259    {
     260        int rc = RTR0MemObjFree(pGVM->pgmr0.s.hPhysHandlerMapObj, true /*fFreeMappings*/);
     261        AssertRC(rc);
     262        pGVM->pgmr0.s.hPhysHandlerMapObj = NIL_RTR0MEMOBJ;
     263    }
     264
     265    if (pGVM->pgmr0.s.hPhysHandlerMemObj != NIL_RTR0MEMOBJ)
     266    {
     267        int rc = RTR0MemObjFree(pGVM->pgmr0.s.hPhysHandlerMemObj, true /*fFreeMappings*/);
     268        AssertRC(rc);
     269        pGVM->pgmr0.s.hPhysHandlerMemObj = NIL_RTR0MEMOBJ;
    253270    }
    254271
     
    749766    return SUPR0PageMapKernel(pGVM->pSession, pvR3, (uint32_t)offSub, (uint32_t)cbSub, 0 /*fFlags*/, ppvMapping);
    750767#endif
     768}
     769
     770
     771/**
     772 * This is called during PGMR3Init to init the physical access handler allocator
     773 * and tree.
     774 *
     775 * @returns VBox status code.
     776 * @param   pGVM        Pointer to the global VM structure.
     777 * @param   cEntries    Desired number of physical access handlers to reserve
     778 *                      space for (will be adjusted).
     779 * @thread  EMT(0)
     780 */
     781VMMR0_INT_DECL(int) PGMR0PhysHandlerInitReqHandler(PGVM pGVM, uint32_t cEntries)
     782{
     783    /*
     784     * Validate the input and state.
     785     */
     786    int rc = GVMMR0ValidateGVMandEMT(pGVM, 0);
     787    AssertRCReturn(rc, rc);
     788    VM_ASSERT_STATE_RETURN(pGVM, VMSTATE_CREATING, VERR_VM_INVALID_VM_STATE); /** @todo ring-0 safe state check. */
     789
     790    AssertReturn(pGVM->pgmr0.s.PhysHandlerAllocator.m_paNodes == NULL, VERR_WRONG_ORDER);
     791    AssertReturn(pGVM->pgm.s.PhysHandlerAllocator.m_paNodes == NULL, VERR_WRONG_ORDER);
     792
     793    AssertLogRelMsgReturn(cEntries <= _64K, ("%#x\n", cEntries), VERR_OUT_OF_RANGE);
     794
     795    /*
     796     * Calculate the table size and allocate it.
     797     */
     798    uint32_t       cbTreeAndBitmap = 0;
     799    uint32_t const cbTotalAligned  = pgmHandlerPhysicalCalcTableSizes(&cEntries, &cbTreeAndBitmap);
     800    RTR0MEMOBJ     hMemObj         = NIL_RTR0MEMOBJ;
     801    rc = RTR0MemObjAllocPage(&hMemObj, cbTotalAligned, false);
     802    if (RT_SUCCESS(rc))
     803    {
     804        RTR0MEMOBJ hMapObj = NIL_RTR0MEMOBJ;
     805        rc = RTR0MemObjMapUser(&hMapObj, hMemObj, (RTR3PTR)-1, 0, RTMEM_PROT_READ | RTMEM_PROT_WRITE, RTR0ProcHandleSelf());
     806        if (RT_SUCCESS(rc))
     807        {
     808            uint8_t *pb = (uint8_t *)RTR0MemObjAddress(hMemObj);
     809            if (!RTR0MemObjWasZeroInitialized(hMemObj))
     810                RT_BZERO(pb, cbTotalAligned);
     811
     812            pGVM->pgmr0.s.PhysHandlerAllocator.initSlabAllocator(cEntries, (PPGMPHYSHANDLER)&pb[cbTreeAndBitmap],
     813                                                                 (uint64_t *)&pb[sizeof(PGMPHYSHANDLERTREE)]);
     814            pGVM->pgmr0.s.pPhysHandlerTree = (PPGMPHYSHANDLERTREE)pb;
     815            pGVM->pgmr0.s.pPhysHandlerTree->initWithAllocator(&pGVM->pgmr0.s.PhysHandlerAllocator);
     816            pGVM->pgmr0.s.hPhysHandlerMemObj = hMemObj;
     817            pGVM->pgmr0.s.hPhysHandlerMapObj = hMapObj;
     818
     819            AssertCompile(sizeof(pGVM->pgm.s.PhysHandlerAllocator) == sizeof(pGVM->pgmr0.s.PhysHandlerAllocator));
     820            RTR3PTR R3Ptr = RTR0MemObjAddressR3(hMapObj);
     821            pGVM->pgm.s.pPhysHandlerTree                    = R3Ptr;
     822            pGVM->pgm.s.PhysHandlerAllocator.m_paNodes      = R3Ptr + cbTreeAndBitmap;
     823            pGVM->pgm.s.PhysHandlerAllocator.m_pbmAlloc     = R3Ptr + sizeof(PGMPHYSHANDLERTREE);
     824            pGVM->pgm.s.PhysHandlerAllocator.m_cNodes       = cEntries;
     825            pGVM->pgm.s.PhysHandlerAllocator.m_cErrors      = 0;
     826            pGVM->pgm.s.PhysHandlerAllocator.m_idxAllocHint = 0;
     827            pGVM->pgm.s.PhysHandlerAllocator.m_uPadding     = 0;
     828            return VINF_SUCCESS;
     829        }
     830
     831        RTR0MemObjFree(hMemObj, true /*fFreeMappings*/);
     832    }
     833    return rc;
    751834}
    752835
     
    11561239     */
    11571240    PGM_LOCK_VOID(pGVM);
    1158     PPGMPHYSHANDLER          pHandler     = pgmHandlerPhysicalLookup(pGVM, GCPhysFault);
    1159     PCPGMPHYSHANDLERTYPEINT  pHandlerType = RT_LIKELY(pHandler) ? PGMPHYSHANDLER_GET_TYPE_NO_NULL(pGVM, pHandler) : NULL;
    1160     if (RT_LIKELY(pHandler && pHandlerType->enmKind != PGMPHYSHANDLERKIND_WRITE))
    1161     {
    1162         /*
    1163          * If the handle has aliases page or pages that have been temporarily
    1164          * disabled, we'll have to take a detour to make sure we resync them
    1165          * to avoid lots of unnecessary exits.
    1166          */
    1167         PPGMPAGE pPage;
    1168         if (   (   pHandler->cAliasedPages
    1169                 || pHandler->cTmpOffPages)
    1170             && (   (pPage = pgmPhysGetPage(pGVM, GCPhysFault)) == NULL
    1171                 || PGM_PAGE_GET_HNDL_PHYS_STATE(pPage) == PGM_PAGE_HNDL_PHYS_STATE_DISABLED)
    1172            )
    1173         {
    1174             Log(("PGMR0Trap0eHandlerNPMisconfig: Resyncing aliases / tmp-off page at %RGp (uErr=%#x) %R[pgmpage]\n", GCPhysFault, uErr, pPage));
    1175             STAM_COUNTER_INC(&pGVCpu->pgm.s.Stats.StatR0NpMiscfgSyncPage);
    1176             rc = pgmShwSyncNestedPageLocked(pGVCpu, GCPhysFault, 1 /*cPages*/, enmShwPagingMode);
    1177             PGM_UNLOCK(pGVM);
    1178         }
    1179         else
    1180         {
    1181             if (pHandlerType->pfnPfHandler)
     1241    PPGMPHYSHANDLER pHandler;
     1242    rc = pgmHandlerPhysicalLookup(pGVM, GCPhysFault, &pHandler);
     1243    if (RT_SUCCESS(rc))
     1244    {
     1245        PCPGMPHYSHANDLERTYPEINT pHandlerType = PGMPHYSHANDLER_GET_TYPE_NO_NULL(pGVM, pHandler);
     1246        if (RT_LIKELY(pHandlerType->enmKind != PGMPHYSHANDLERKIND_WRITE))
     1247        {
     1248            /*
     1249             * If the handle has aliases page or pages that have been temporarily
     1250             * disabled, we'll have to take a detour to make sure we resync them
     1251             * to avoid lots of unnecessary exits.
     1252             */
     1253            PPGMPAGE pPage;
     1254            if (   (   pHandler->cAliasedPages
     1255                    || pHandler->cTmpOffPages)
     1256                && (   (pPage = pgmPhysGetPage(pGVM, GCPhysFault)) == NULL
     1257                    || PGM_PAGE_GET_HNDL_PHYS_STATE(pPage) == PGM_PAGE_HNDL_PHYS_STATE_DISABLED)
     1258               )
    11821259            {
    1183                 uint64_t const uUser = !pHandlerType->fRing0DevInsIdx ? pHandler->uUser
    1184                                      : (uintptr_t)PDMDeviceRing0IdxToInstance(pGVM, pHandler->uUser);
    1185                 STAM_PROFILE_START(&pHandler->Stat, h);
     1260                Log(("PGMR0Trap0eHandlerNPMisconfig: Resyncing aliases / tmp-off page at %RGp (uErr=%#x) %R[pgmpage]\n", GCPhysFault, uErr, pPage));
     1261                STAM_COUNTER_INC(&pGVCpu->pgm.s.Stats.StatR0NpMiscfgSyncPage);
     1262                rc = pgmShwSyncNestedPageLocked(pGVCpu, GCPhysFault, 1 /*cPages*/, enmShwPagingMode);
    11861263                PGM_UNLOCK(pGVM);
    1187 
    1188                 Log6(("PGMR0Trap0eHandlerNPMisconfig: calling %p(,%#x,,%RGp,%p)\n", pHandlerType->pfnPfHandler, uErr, GCPhysFault, uUser));
    1189                 rc = pHandlerType->pfnPfHandler(pGVM, pGVCpu, uErr == UINT32_MAX ? RTGCPTR_MAX : uErr, pRegFrame,
    1190                                                 GCPhysFault, GCPhysFault, uUser);
    1191 
    1192 #ifdef VBOX_WITH_STATISTICS
    1193                 PGM_LOCK_VOID(pGVM);
    1194                 pHandler = pgmHandlerPhysicalLookup(pGVM, GCPhysFault);
    1195                 if (pHandler)
    1196                     STAM_PROFILE_STOP(&pHandler->Stat, h);
    1197                 PGM_UNLOCK(pGVM);
    1198 #endif
    11991264            }
    12001265            else
    12011266            {
    1202                 PGM_UNLOCK(pGVM);
    1203                 Log(("PGMR0Trap0eHandlerNPMisconfig: %RGp (uErr=%#x) -> R3\n", GCPhysFault, uErr));
    1204                 rc = VINF_EM_RAW_EMULATE_INSTR;
     1267                if (pHandlerType->pfnPfHandler)
     1268                {
     1269                    uint64_t const uUser = !pHandlerType->fRing0DevInsIdx ? pHandler->uUser
     1270                                         : (uintptr_t)PDMDeviceRing0IdxToInstance(pGVM, pHandler->uUser);
     1271                    STAM_PROFILE_START(&pHandler->Stat, h);
     1272                    PGM_UNLOCK(pGVM);
     1273
     1274                    Log6(("PGMR0Trap0eHandlerNPMisconfig: calling %p(,%#x,,%RGp,%p)\n", pHandlerType->pfnPfHandler, uErr, GCPhysFault, uUser));
     1275                    rc = pHandlerType->pfnPfHandler(pGVM, pGVCpu, uErr == UINT32_MAX ? RTGCPTR_MAX : uErr, pRegFrame,
     1276                                                    GCPhysFault, GCPhysFault, uUser);
     1277
     1278                    STAM_PROFILE_STOP(&pHandler->Stat, h); /* no locking needed, entry is unlikely reused before we get here. */
     1279                }
     1280                else
     1281                {
     1282                    PGM_UNLOCK(pGVM);
     1283                    Log(("PGMR0Trap0eHandlerNPMisconfig: %RGp (uErr=%#x) -> R3\n", GCPhysFault, uErr));
     1284                    rc = VINF_EM_RAW_EMULATE_INSTR;
     1285                }
    12051286            }
     1287            STAM_PROFILE_STOP(&pGVCpu->pgm.s.Stats.StatR0NpMiscfg, a);
     1288            return rc;
    12061289        }
    12071290    }
    12081291    else
    1209     {
    1210         /*
    1211          * Must be out of sync, so do a SyncPage and restart the instruction.
    1212          *
    1213          * ASSUMES that ALL handlers are page aligned and covers whole pages
    1214          * (assumption asserted in PGMHandlerPhysicalRegisterEx).
    1215          */
    1216         Log(("PGMR0Trap0eHandlerNPMisconfig: Out of sync page at %RGp (uErr=%#x)\n", GCPhysFault, uErr));
    1217         STAM_COUNTER_INC(&pGVCpu->pgm.s.Stats.StatR0NpMiscfgSyncPage);
    1218         rc = pgmShwSyncNestedPageLocked(pGVCpu, GCPhysFault, 1 /*cPages*/, enmShwPagingMode);
    1219         PGM_UNLOCK(pGVM);
    1220     }
     1292        AssertMsgReturn(rc == VERR_NOT_FOUND, ("%Rrc GCPhysFault=%RGp\n", VBOXSTRICTRC_VAL(rc), GCPhysFault), rc);
     1293
     1294    /*
     1295     * Must be out of sync, so do a SyncPage and restart the instruction.
     1296     *
     1297     * ASSUMES that ALL handlers are page aligned and covers whole pages
     1298     * (assumption asserted in PGMHandlerPhysicalRegisterEx).
     1299     */
     1300    Log(("PGMR0Trap0eHandlerNPMisconfig: Out of sync page at %RGp (uErr=%#x)\n", GCPhysFault, uErr));
     1301    STAM_COUNTER_INC(&pGVCpu->pgm.s.Stats.StatR0NpMiscfgSyncPage);
     1302    rc = pgmShwSyncNestedPageLocked(pGVCpu, GCPhysFault, 1 /*cPages*/, enmShwPagingMode);
     1303    PGM_UNLOCK(pGVM);
    12211304
    12221305    STAM_PROFILE_STOP(&pGVCpu->pgm.s.Stats.StatR0NpMiscfg, a);
  • trunk/src/VBox/VMM/VMMR0/VMMR0.cpp

    r93650 r93716  
    19041904            break;
    19051905
     1906        case VMMR0_DO_PGM_PHYS_HANDLER_INIT:
     1907            if (idCpu != 0 || pReqHdr != NULL || u64Arg > UINT32_MAX)
     1908                return VERR_INVALID_PARAMETER;
     1909            rc = PGMR0PhysHandlerInitReqHandler(pGVM, (uint32_t)u64Arg);
     1910            break;
     1911
    19061912        /*
    19071913         * GMM wrappers.
  • trunk/src/VBox/VMM/VMMR3/PGM.cpp

    r93650 r93716  
    606606#include <VBox/vmm/hm.h>
    607607#include "PGMInternal.h"
    608 #include <VBox/vmm/vm.h>
     608#include <VBox/vmm/vmcc.h>
    609609#include <VBox/vmm/uvm.h>
    610610#include "PGMInline.h"
     
    933933
    934934    /*
    935      * Trees
    936      */
    937     rc = MMHyperAlloc(pVM, sizeof(PGMTREES), 0, MM_TAG_PGM, (void **)&pVM->pgm.s.pTreesR3);
    938     if (RT_SUCCESS(rc))
    939         pVM->pgm.s.pTreesR0 = MMHyperR3ToR0(pVM, pVM->pgm.s.pTreesR3);
    940 
    941     /*
    942935     * Setup the zero page (HCPHysZeroPg is set by ring-0).
    943936     */
     
    958951    AssertRelease(pVM->pgm.s.HCPhysMmioPg != 0);
    959952    pVM->pgm.s.HCPhysInvMmioPg = pVM->pgm.s.HCPhysMmioPg;
     953
     954    /*
     955     * Initialize physical access handlers.
     956     */
     957    /** @cfgm{/PGM/MaxPhysicalAccessHandlers, uint32_t, 32, 65536, 6144}
     958     * Number of physical access handlers allowed (subject to rounding).  This is
     959     * managed as one time allocation during initializations.  The default is
     960     * lower for a driverless setup. */
     961    /** @todo can lower it for nested paging too, at least when there is no
     962     *        nested guest involved. */
     963    uint32_t cAccessHandlers = 0;
     964    rc = CFGMR3QueryU32Def(pCfgPGM, "MaxPhysicalAccessHandlers", &cAccessHandlers, !fDriverless ? 6144 : 640);
     965    AssertLogRelRCReturn(rc, rc);
     966    AssertLogRelMsgStmt(cAccessHandlers >= 32, ("cAccessHandlers=%#x, min 32\n", cAccessHandlers), cAccessHandlers = 32);
     967    AssertLogRelMsgStmt(cAccessHandlers <= _64K, ("cAccessHandlers=%#x, max 65536\n", cAccessHandlers), cAccessHandlers = _64K);
     968    if (!fDriverless)
     969    {
     970        rc = VMMR3CallR0(pVM, VMMR0_DO_PGM_PHYS_HANDLER_INIT, cAccessHandlers, NULL);
     971        AssertRCReturn(rc, rc);
     972        AssertPtr(pVM->pgm.s.pPhysHandlerTree);
     973        AssertPtr(pVM->pgm.s.PhysHandlerAllocator.m_paNodes);
     974        AssertPtr(pVM->pgm.s.PhysHandlerAllocator.m_pbmAlloc);
     975    }
     976    else
     977    {
     978        uint32_t       cbTreeAndBitmap = 0;
     979        uint32_t const cbTotalAligned  = pgmHandlerPhysicalCalcTableSizes(&cAccessHandlers, &cbTreeAndBitmap);
     980        uint8_t       *pb = NULL;
     981        rc = SUPR3PageAlloc(cbTotalAligned >> HOST_PAGE_SHIFT, 0, (void **)&pb);
     982        AssertLogRelRCReturn(rc, rc);
     983
     984        pVM->pgm.s.PhysHandlerAllocator.initSlabAllocator(cAccessHandlers, (PPGMPHYSHANDLER)&pb[cbTreeAndBitmap],
     985                                                          (uint64_t *)&pb[sizeof(PGMPHYSHANDLERTREE)]);
     986        pVM->pgm.s.pPhysHandlerTree = (PPGMPHYSHANDLERTREE)pb;
     987        pVM->pgm.s.pPhysHandlerTree->initWithAllocator(&pVM->pgm.s.PhysHandlerAllocator);
     988    }
    960989
    961990    /*
     
    12191248        AssertRC(rc);
    12201249
     1250#define PGM_REG_U64(a, b, c) \
     1251        rc = STAMR3RegisterF(pVM, a, STAMTYPE_U64, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, c, b); \
     1252        AssertRC(rc);
     1253
     1254#define PGM_REG_U64_RESET(a, b, c) \
     1255        rc = STAMR3RegisterF(pVM, a, STAMTYPE_U64_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, c, b); \
     1256        AssertRC(rc);
     1257
     1258#define PGM_REG_U32(a, b, c) \
     1259        rc = STAMR3RegisterF(pVM, a, STAMTYPE_U32, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, c, b); \
     1260        AssertRC(rc);
     1261
    12211262#define PGM_REG_COUNTER_BYTES(a, b, c) \
    12221263        rc = STAMR3RegisterF(pVM, a, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES, c, b); \
     
    12831324    PGM_REG_COUNTER(&pStats->StatRZPhysHandlerLookupMisses,     "/PGM/RZ/PhysHandlerLookupMisses",    "The number of cache misses when looking up physical handlers.");
    12841325    PGM_REG_COUNTER(&pStats->StatR3PhysHandlerLookupMisses,     "/PGM/R3/PhysHandlerLookupMisses",    "The number of cache misses when looking up physical handlers.");
    1285 
     1326#endif /* VBOX_WITH_STATISTICS */
     1327    PPGMPHYSHANDLERTREE pPhysHndlTree = pVM->pgm.s.pPhysHandlerTree;
     1328    PGM_REG_U32(&pPhysHndlTree->m_cErrors,                      "/PGM/PhysHandlerTree/ErrorsTree",    "Physical access handler tree errors.");
     1329    PGM_REG_U32(&pVM->pgm.s.PhysHandlerAllocator.m_cErrors,     "/PGM/PhysHandlerTree/ErrorsAllocatorR3", "Physical access handler tree allocator errors (ring-3 only).");
     1330    PGM_REG_U64_RESET(&pPhysHndlTree->m_cInserts,               "/PGM/PhysHandlerTree/Inserts",       "Physical access handler tree inserts.");
     1331    PGM_REG_U32(&pVM->pgm.s.PhysHandlerAllocator.m_cNodes,      "/PGM/PhysHandlerTree/MaxHandlers",   "Max physical access handlers.");
     1332    PGM_REG_U64_RESET(&pPhysHndlTree->m_cRemovals,              "/PGM/PhysHandlerTree/Removals",      "Physical access handler tree removals.");
     1333    PGM_REG_U64_RESET(&pPhysHndlTree->m_cRebalancingOperations, "/PGM/PhysHandlerTree/RebalancingOperations", "Physical access handler tree rebalancing transformations.");
     1334
     1335#ifdef VBOX_WITH_STATISTICS
    12861336    PGM_REG_COUNTER(&pStats->StatRZPageReplaceShared,           "/PGM/RZ/Page/ReplacedShared",        "Times a shared page was replaced.");
    12871337    PGM_REG_COUNTER(&pStats->StatRZPageReplaceZero,             "/PGM/RZ/Page/ReplacedZero",          "Times the zero page was replaced.");
     
    13231373
    13241374#undef PGM_REG_COUNTER
     1375#undef PGM_REG_U64
     1376#undef PGM_REG_U64_RESET
     1377#undef PGM_REG_U32
    13251378#undef PGM_REG_PROFILE
    13261379#undef PGM_REG_PROFILE_NS
     
    21042157                        pszType = "MMIO";
    21052158                        PGM_LOCK_VOID(pVM);
    2106                         PPGMPHYSHANDLER pHandler = pgmHandlerPhysicalLookup(pVM, iFirstPage * X86_PAGE_SIZE);
    2107                         if (pHandler)
     2159                        PPGMPHYSHANDLER pHandler;
     2160                        int rc = pgmHandlerPhysicalLookup(pVM, iFirstPage * X86_PAGE_SIZE, &pHandler);
     2161                        if (RT_SUCCESS(rc))
    21082162                            pszMore = pHandler->pszDesc;
    21092163                        PGM_UNLOCK(pVM);
     
    25372591{
    25382592    bool                    fLeftToRight;    /**< true: left-to-right; false: right-to-left. */
     2593    uint32_t                cErrors;
    25392594    PPGMPHYSHANDLER         pPrevPhys;
    25402595    PVM                     pVM;
     
    25482603 * @param   pvUser      pVM.
    25492604 */
    2550 static DECLCALLBACK(int) pgmR3CheckIntegrityPhysHandlerNode(PAVLROGCPHYSNODECORE pNode, void *pvUser)
     2605static DECLCALLBACK(int) pgmR3CheckIntegrityPhysHandlerNode(PPGMPHYSHANDLER pNode, void *pvUser)
    25512606{
    25522607    PPGMCHECKINTARGS pArgs = (PPGMCHECKINTARGS)pvUser;
    2553     PPGMPHYSHANDLER pCur = (PPGMPHYSHANDLER)pNode;
    2554     AssertReleaseReturn(!((uintptr_t)pCur & 7), 1);
    2555     AssertReleaseMsg(pCur->Core.Key <= pCur->Core.KeyLast,
    2556                      ("pCur=%p %RGp-%RGp %s\n", pCur, pCur->Core.Key, pCur->Core.KeyLast, pCur->pszDesc));
    2557     AssertReleaseMsg(   !pArgs->pPrevPhys
    2558                      || (  pArgs->fLeftToRight
    2559                          ? pArgs->pPrevPhys->Core.KeyLast < pCur->Core.Key
    2560                          : pArgs->pPrevPhys->Core.KeyLast > pCur->Core.Key),
    2561                      ("pPrevPhys=%p %RGp-%RGp %s\n"
    2562                       "     pCur=%p %RGp-%RGp %s\n",
    2563                       pArgs->pPrevPhys, pArgs->pPrevPhys->Core.Key, pArgs->pPrevPhys->Core.KeyLast, pArgs->pPrevPhys->pszDesc,
    2564                       pCur, pCur->Core.Key, pCur->Core.KeyLast, pCur->pszDesc));
    2565     pArgs->pPrevPhys = pCur;
     2608
     2609    AssertLogRelMsgReturnStmt(!((uintptr_t)pNode & 7), ("pNode=%p\n", pNode), pArgs->cErrors++, VERR_INVALID_POINTER);
     2610
     2611    AssertLogRelMsgStmt(pNode->Key <= pNode->KeyLast,
     2612                        ("pNode=%p %RGp-%RGp %s\n", pNode, pNode->Key, pNode->KeyLast, pNode->pszDesc),
     2613                        pArgs->cErrors++);
     2614
     2615    AssertLogRelMsgStmt(   !pArgs->pPrevPhys
     2616                        || (  pArgs->fLeftToRight
     2617                            ? pArgs->pPrevPhys->KeyLast < pNode->Key
     2618                            : pArgs->pPrevPhys->KeyLast > pNode->Key),
     2619                        ("pPrevPhys=%p %RGp-%RGp %s\n"
     2620                         "    pNode=%p %RGp-%RGp %s\n",
     2621                         pArgs->pPrevPhys, pArgs->pPrevPhys->Key, pArgs->pPrevPhys->KeyLast, pArgs->pPrevPhys->pszDesc,
     2622                         pNode, pNode->Key, pNode->KeyLast, pNode->pszDesc),
     2623                        pArgs->cErrors++);
     2624
     2625    pArgs->pPrevPhys = pNode;
    25662626    return 0;
    25672627}
     
    25802640     * Check the trees.
    25812641     */
    2582     int cErrors = 0;
    2583     const PGMCHECKINTARGS LeftToRight = {  true, NULL, pVM };
    2584     const PGMCHECKINTARGS RightToLeft = { false, NULL, pVM };
    2585     PGMCHECKINTARGS Args = LeftToRight;
    2586     cErrors += RTAvlroGCPhysDoWithAll(&pVM->pgm.s.pTreesR3->PhysHandlers,       true,  pgmR3CheckIntegrityPhysHandlerNode, &Args);
    2587     Args = RightToLeft;
    2588     cErrors += RTAvlroGCPhysDoWithAll(&pVM->pgm.s.pTreesR3->PhysHandlers,       false, pgmR3CheckIntegrityPhysHandlerNode, &Args);
    2589 
    2590     return !cErrors ? VINF_SUCCESS : VERR_INTERNAL_ERROR;
    2591 }
    2592 
     2642    PGMCHECKINTARGS Args = { true, 0, NULL, pVM };
     2643    int rc = pVM->pgm.s.pPhysHandlerTree->doWithAllFromLeft(&pVM->pgm.s.PhysHandlerAllocator,
     2644                                                            pgmR3CheckIntegrityPhysHandlerNode, &Args);
     2645    AssertLogRelRCReturn(rc, rc);
     2646
     2647    Args.fLeftToRight = false;
     2648    Args.pPrevPhys    = NULL;
     2649    rc = pVM->pgm.s.pPhysHandlerTree->doWithAllFromRight(&pVM->pgm.s.PhysHandlerAllocator,
     2650                                                         pgmR3CheckIntegrityPhysHandlerNode, &Args);
     2651    AssertLogRelMsgReturn(pVM->pgm.s.pPhysHandlerTree->m_cErrors == 0,
     2652                          ("m_cErrors=%#x\n", pVM->pgm.s.pPhysHandlerTree->m_cErrors == 0),
     2653                          VERR_INTERNAL_ERROR);
     2654
     2655    return Args.cErrors == 0 ? VINF_SUCCESS : VERR_INTERNAL_ERROR;
     2656}
     2657
  • trunk/src/VBox/VMM/VMMR3/PGMDbg.cpp

    r93554 r93716  
    2525#include <VBox/vmm/stam.h>
    2626#include "PGMInternal.h"
    27 #include <VBox/vmm/vm.h>
     27#include <VBox/vmm/vmcc.h>
    2828#include <VBox/vmm/uvm.h>
    2929#include "PGMInline.h"
  • trunk/src/VBox/VMM/VMMR3/PGMHandler.cpp

    r93667 r93716  
    3434#include <VBox/vmm/ssm.h>
    3535#include "PGMInternal.h"
    36 #include <VBox/vmm/vm.h>
     36#include <VBox/vmm/vmcc.h>
    3737#include "PGMInline.h"
    3838#include <VBox/dbg.h>
     
    5252*   Internal Functions                                                                                                           *
    5353*********************************************************************************************************************************/
    54 static DECLCALLBACK(int) pgmR3HandlerPhysicalOneClear(PAVLROGCPHYSNODECORE pNode, void *pvUser);
    55 static DECLCALLBACK(int) pgmR3HandlerPhysicalOneSet(PAVLROGCPHYSNODECORE pNode, void *pvUser);
    56 static DECLCALLBACK(int) pgmR3InfoHandlersPhysicalOne(PAVLROGCPHYSNODECORE pNode, void *pvUser);
     54static DECLCALLBACK(int) pgmR3HandlerPhysicalOneClear(PPGMPHYSHANDLER pHandler, void *pvUser);
     55static DECLCALLBACK(int) pgmR3HandlerPhysicalOneSet(PPGMPHYSHANDLER pHandler, void *pvUser);
     56static DECLCALLBACK(int) pgmR3InfoHandlersPhysicalOne(PPGMPHYSHANDLER pHandler, void *pvUser);
    5757
    5858
     
    143143     */
    144144    PGM_LOCK_VOID(pVM);
    145     RTAvlroGCPhysDoWithAll(&pVM->pgm.s.CTX_SUFF(pTrees)->PhysHandlers,  true, pgmR3HandlerPhysicalOneClear, pVM);
    146     RTAvlroGCPhysDoWithAll(&pVM->pgm.s.CTX_SUFF(pTrees)->PhysHandlers, false, pgmR3HandlerPhysicalOneSet, pVM);
     145
     146    int rc = pVM->pgm.s.pPhysHandlerTree->doWithAllFromLeft(&pVM->pgm.s.PhysHandlerAllocator, pgmR3HandlerPhysicalOneClear, pVM);
     147    AssertRC(rc);
     148    rc = pVM->pgm.s.pPhysHandlerTree->doWithAllFromRight(&pVM->pgm.s.PhysHandlerAllocator, pgmR3HandlerPhysicalOneSet, pVM);
     149    AssertRC(rc);
     150
    147151    PGM_UNLOCK(pVM);
    148152}
     
    153157 *
    154158 * @returns 0
    155  * @param   pNode   Pointer to a PGMPHYSHANDLER.
    156  * @param   pvUser  Pointer to the VM.
    157  */
    158 static DECLCALLBACK(int) pgmR3HandlerPhysicalOneClear(PAVLROGCPHYSNODECORE pNode, void *pvUser)
    159 {
    160     PPGMPHYSHANDLER pCur     = (PPGMPHYSHANDLER)pNode;
     159 * @param   pHandler    The physical access handler entry.
     160 * @param   pvUser      Pointer to the VM.
     161 */
     162static DECLCALLBACK(int) pgmR3HandlerPhysicalOneClear(PPGMPHYSHANDLER pHandler, void *pvUser)
     163{
    161164    PPGMRAMRANGE    pRamHint = NULL;
    162     RTGCPHYS        GCPhys   = pCur->Core.Key;
    163     RTUINT          cPages   = pCur->cPages;
     165    RTGCPHYS        GCPhys   = pHandler->Key;
     166    RTUINT          cPages   = pHandler->cPages;
    164167    PVM             pVM      = (PVM)pvUser;
    165168    for (;;)
     
    198201 *
    199202 * @returns 0
    200  * @param   pNode   Pointer to a PGMPHYSHANDLER.
    201  * @param   pvUser  Pointer to the VM.
    202  */
    203 static DECLCALLBACK(int) pgmR3HandlerPhysicalOneSet(PAVLROGCPHYSNODECORE pNode, void *pvUser)
     203 * @param   pHandler    The physical access handler entry.
     204 * @param   pvUser      Pointer to the VM.
     205 */
     206static DECLCALLBACK(int) pgmR3HandlerPhysicalOneSet(PPGMPHYSHANDLER pHandler, void *pvUser)
    204207{
    205208    PVM                     pVM       = (PVM)pvUser;
    206     PPGMPHYSHANDLER         pCur      = (PPGMPHYSHANDLER)pNode;
    207     PCPGMPHYSHANDLERTYPEINT pCurType  = PGMPHYSHANDLER_GET_TYPE_NO_NULL(pVM, pCur);
    208     unsigned                uState    = pCurType->uState;
     209    PCPGMPHYSHANDLERTYPEINT pType     = PGMPHYSHANDLER_GET_TYPE_NO_NULL(pVM, pHandler);
     210    unsigned                uState    = pType->uState;
    209211    PPGMRAMRANGE            pRamHint  = NULL;
    210     RTGCPHYS                GCPhys    = pCur->Core.Key;
    211     RTUINT                  cPages    = pCur->cPages;
     212    RTGCPHYS                GCPhys    = pHandler->Key;
     213    RTUINT                  cPages    = pHandler->cPages;
    212214    for (;;)
    213215    {
     
    275277     */
    276278    pHlp->pfnPrintf(pHlp,
    277                     "Physical handlers: (PhysHandlers=%d (%#x))\n"
     279                    "Physical handlers: max %#x, %u allocator error%s, %u tree error%s\n"
    278280                    "%*s %*s %*s uUser             Type     Description\n",
    279                     pVM->pgm.s.pTreesR3->PhysHandlers, pVM->pgm.s.pTreesR3->PhysHandlers,
     281                    pVM->pgm.s.PhysHandlerAllocator.m_cNodes,
     282                    pVM->pgm.s.PhysHandlerAllocator.m_cErrors, pVM->pgm.s.PhysHandlerAllocator.m_cErrors != 0 ? "s" : "",
     283                    pVM->pgm.s.pPhysHandlerTree->m_cErrors, pVM->pgm.s.pPhysHandlerTree->m_cErrors != 0 ? "s" : "",
    280284                    - (int)sizeof(RTGCPHYS) * 2,     "From",
    281285                    - (int)sizeof(RTGCPHYS) * 2 - 3, "- To (incl)",
    282286                    - (int)sizeof(RTHCPTR)  * 2 - 1, "Handler (R3)");
    283     RTAvlroGCPhysDoWithAll(&pVM->pgm.s.pTreesR3->PhysHandlers, true, pgmR3InfoHandlersPhysicalOne, &Args);
     287    pVM->pgm.s.pPhysHandlerTree->doWithAllFromLeft(&pVM->pgm.s.PhysHandlerAllocator, pgmR3InfoHandlersPhysicalOne, &Args);
    284288}
    285289
     
    289293 *
    290294 * @returns 0
    291  * @param   pNode   Pointer to a PGMPHYSHANDLER.
    292  * @param   pvUser  Pointer to command helper functions.
    293  */
    294 static DECLCALLBACK(int) pgmR3InfoHandlersPhysicalOne(PAVLROGCPHYSNODECORE pNode, void *pvUser)
    295 {
    296     PPGMPHYSHANDLER         pCur     = (PPGMPHYSHANDLER)pNode;
    297     PPGMHANDLERINFOARG      pArgs    = (PPGMHANDLERINFOARG)pvUser;
    298     PCDBGFINFOHLP           pHlp     = pArgs->pHlp;
    299     PCPGMPHYSHANDLERTYPEINT pCurType = PGMPHYSHANDLER_GET_TYPE_NO_NULL(pArgs->pVM, pCur);
     295 * @param   pHandler    The physical access handler entry.
     296 * @param   pvUser      Pointer to command helper functions.
     297 */
     298static DECLCALLBACK(int) pgmR3InfoHandlersPhysicalOne(PPGMPHYSHANDLER pHandler, void *pvUser)
     299{
     300    PPGMHANDLERINFOARG      pArgs = (PPGMHANDLERINFOARG)pvUser;
     301    PCDBGFINFOHLP           pHlp  = pArgs->pHlp;
     302    PCPGMPHYSHANDLERTYPEINT pType = PGMPHYSHANDLER_GET_TYPE_NO_NULL(pArgs->pVM, pHandler);
    300303    const char *pszType;
    301     switch (pCurType->enmKind)
     304    switch (pType->enmKind)
    302305    {
    303306        case PGMPHYSHANDLERKIND_MMIO:   pszType = "MMIO   "; break;
     
    309312    char   szFlags[80];
    310313    size_t cchFlags = 0;
    311     if (pCurType->fKeepPgmLock)
     314    if (pType->fKeepPgmLock)
    312315        cchFlags = RTStrPrintf(szFlags, sizeof(szFlags), "(keep-pgm-lock");
    313     if (pCurType->fRing0DevInsIdx)
     316    if (pType->fRing0DevInsIdx)
    314317        cchFlags += RTStrPrintf(&szFlags[cchFlags], sizeof(szFlags) - cchFlags, cchFlags ? ", keep-pgm-lock" : "(keep-pgm-lock");
    315     if (pCurType->fRing0Enabled)
     318    if (pType->fRing0Enabled)
    316319        cchFlags += RTStrPrintf(&szFlags[cchFlags], sizeof(szFlags) - cchFlags, cchFlags ? ", r0-enabled)" : "(r0-enabled)");
    317320    else
     
    320323    pHlp->pfnPrintf(pHlp,
    321324                    "%RGp - %RGp  %p  %016RX64  %s  %s  %s\n",
    322                     pCur->Core.Key, pCur->Core.KeyLast, pCurType->pfnHandler, pCur->uUser, pszType, pCur->pszDesc, szFlags);
     325                    pHandler->Key, pHandler->KeyLast, pType->pfnHandler, pHandler->uUser, pszType, pHandler->pszDesc, szFlags);
    323326#ifdef VBOX_WITH_STATISTICS
    324327    if (pArgs->fStats)
    325328        pHlp->pfnPrintf(pHlp, "   cPeriods: %9RU64  cTicks: %11RU64  Min: %11RU64  Avg: %11RU64 Max: %11RU64\n",
    326                         pCur->Stat.cPeriods, pCur->Stat.cTicks, pCur->Stat.cTicksMin,
    327                         pCur->Stat.cPeriods ? pCur->Stat.cTicks / pCur->Stat.cPeriods : 0, pCur->Stat.cTicksMax);
     329                        pHandler->Stat.cPeriods, pHandler->Stat.cTicks, pHandler->Stat.cTicksMin,
     330                        pHandler->Stat.cPeriods ? pHandler->Stat.cTicks / pHandler->Stat.cPeriods : 0, pHandler->Stat.cTicksMax);
    328331#endif
    329332    return 0;
  • trunk/src/VBox/VMM/VMMR3/PGMPool.cpp

    r93650 r93716  
    101101#include <VBox/vmm/mm.h>
    102102#include "PGMInternal.h"
    103 #include <VBox/vmm/vm.h>
     103#include <VBox/vmm/vmcc.h>
    104104#include <VBox/vmm/uvm.h>
    105105#include "PGMInline.h"
  • trunk/src/VBox/VMM/VMMR3/PGMSavedState.cpp

    r93554 r93716  
    2828#include <VBox/vmm/pdmdev.h>
    2929#include "PGMInternal.h"
    30 #include <VBox/vmm/vm.h>
     30#include <VBox/vmm/vmcc.h>
    3131#include "PGMInline.h"
    3232
  • trunk/src/VBox/VMM/VMMR3/PGMSharedPage.cpp

    r93554 r93716  
    2626#include <VBox/vmm/uvm.h>
    2727#include "PGMInternal.h"
    28 #include <VBox/vmm/vm.h>
     28#include <VBox/vmm/vmcc.h>
    2929#include <VBox/sup.h>
    3030#include <VBox/param.h>
  • trunk/src/VBox/VMM/include/PGMInline.h

    r93650 r93716  
    968968 * Cached physical handler lookup.
    969969 *
    970  * @returns Physical handler covering @a GCPhys.
    971  * @param   pVM                 The cross context VM structure.
    972  * @param   GCPhys              The lookup address.
    973  */
    974 DECLINLINE(PPGMPHYSHANDLER) pgmHandlerPhysicalLookup(PVMCC pVM, RTGCPHYS GCPhys)
    975 {
    976     PPGMPHYSHANDLER pHandler = pVM->pgm.s.CTX_SUFF(pLastPhysHandler);
     970 * @returns VBox status code.
     971 * @retval  VERR_NOT_FOUND if no handler.
     972 * @param   pVM         The cross context VM structure.
     973 * @param   GCPhys      The lookup address.
     974 * @param   ppHandler   Where to return the handler pointer.
     975 */
     976DECLINLINE(int) pgmHandlerPhysicalLookup(PVMCC pVM, RTGCPHYS GCPhys, PPGMPHYSHANDLER *ppHandler)
     977{
     978    PPGMPHYSHANDLER pHandler = pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator.ptrFromInt(pVM->pgm.s.idxLastPhysHandler);
    977979    if (   pHandler
    978         && GCPhys >= pHandler->Core.Key
    979         && GCPhys < pHandler->Core.KeyLast)
     980        && pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator.isPtrRetOkay(pHandler)
     981        && GCPhys >= pHandler->Key
     982        && GCPhys <  pHandler->KeyLast
     983        && pHandler->hType != NIL_PGMPHYSHANDLERTYPE
     984        && pHandler->hType != 0)
     985
    980986    {
    981987        STAM_COUNTER_INC(&pVM->pgm.s.Stats.CTX_MID_Z(Stat,PhysHandlerLookupHits));
    982         return pHandler;
     988        *ppHandler = pHandler;
     989        return VINF_SUCCESS;
    983990    }
    984991
    985992    STAM_COUNTER_INC(&pVM->pgm.s.Stats.CTX_MID_Z(Stat,PhysHandlerLookupMisses));
    986     pHandler = (PPGMPHYSHANDLER)RTAvlroGCPhysRangeGet(&pVM->pgm.s.CTX_SUFF(pTrees)->PhysHandlers, GCPhys);
    987     if (pHandler)
    988         pVM->pgm.s.CTX_SUFF(pLastPhysHandler) = pHandler;
    989     return pHandler;
     993    AssertPtrReturn(pVM->VMCC_CTX(pgm).s.pPhysHandlerTree, VERR_PGM_HANDLER_IPE_1);
     994    int rc = pVM->VMCC_CTX(pgm).s.pPhysHandlerTree->lookup(&pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator, GCPhys, &pHandler);
     995    if (RT_SUCCESS(rc))
     996    {
     997        *ppHandler = pHandler;
     998        pVM->pgm.s.idxLastPhysHandler = pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator.ptrToInt(pHandler);
     999        return VINF_SUCCESS;
     1000    }
     1001    *ppHandler = NULL;
     1002    return rc;
    9901003}
    9911004
  • trunk/src/VBox/VMM/include/PGMInternal.h

    r93650 r93716  
    4343#include <iprt/list-off32.h>
    4444#include <iprt/sha.h>
     45#include <iprt/cpp/hardavlrange.h>
    4546
    4647
     
    563564typedef struct PGMPHYSHANDLER
    564565{
    565     AVLROGCPHYSNODECORE                 Core;
     566    /** @name Tree stuff.
     567     * @{  */
     568    /** First address. */
     569    RTGCPHYS                            Key;
     570    /** Last address. */
     571    RTGCPHYS                            KeyLast;
     572    uint32_t                            idxLeft;
     573    uint32_t                            idxRight;
     574    uint8_t                             cHeight;
     575    /**  @}  */
     576    uint8_t                             abPadding[3];
    566577    /** Number of pages to update. */
    567578    uint32_t                            cPages;
     
    570581    /** Set if we have pages that have temporarily been disabled. */
    571582    uint32_t                            cTmpOffPages;
    572     uint32_t                            u32Padding;
    573583    /** Registered handler type handle.
    574584     * @note Marked volatile to prevent re-reading after validation. */
     
    578588    /** Description / Name. For easing debugging. */
    579589    R3PTRTYPE(const char *)             pszDesc;
    580 #ifdef VBOX_WITH_STATISTICS
    581     /** Profiling of this handler. */
     590    /** Profiling of this handler.
     591     * @note VBOX_WITH_STATISTICS only, but included to keep structure stable. */
    582592    STAMPROFILE                         Stat;
    583 #endif
    584593} PGMPHYSHANDLER;
     594AssertCompileSize(PGMPHYSHANDLER, 12*8);
    585595/** Pointer to a physical page access handler structure. */
    586596typedef PGMPHYSHANDLER *PPGMPHYSHANDLER;
     
    606616#define PGMPHYSHANDLER_GET_TYPE_NO_NULL(a_pVM, a_pPhysHandler) \
    607617    pgmHandlerPhysicalTypeHandleToPtr2(a_pVM, (a_pPhysHandler) ? (a_pPhysHandler)->hType : NIL_PGMPHYSHANDLERTYPE)
     618
     619/** Physical access handler allocator. */
     620typedef RTCHardAvlTreeSlabAllocator<PGMPHYSHANDLER>   PGMPHYSHANDLERALLOCATOR;
     621
     622/** Physical access handler tree. */
     623typedef RTCHardAvlRangeTree<PGMPHYSHANDLER, RTGCPHYS> PGMPHYSHANDLERTREE;
     624/** Pointer to a physical access handler tree. */
     625typedef PGMPHYSHANDLERTREE                           *PPGMPHYSHANDLERTREE;
    608626
    609627
     
    23612379
    23622380/**
    2363  * Roots and anchors for trees and list employing self relative offsets as
    2364  * pointers.
    2365  *
    2366  * When using self-relative offsets instead of pointers, the offsets needs to be
    2367  * the same in all offsets.  Thus the roots and anchors needs to live on the
    2368  * hyper heap just like the nodes.
    2369  */
    2370 typedef struct PGMTREES
    2371 {
    2372     /** Physical access handlers (AVL range+offsetptr tree). */
    2373     AVLROGCPHYSTREE                 PhysHandlers;
    2374     uint32_t                        u32PaddingTo8Bytes;
    2375 } PGMTREES;
    2376 /** Pointer to PGM trees. */
    2377 typedef PGMTREES *PPGMTREES;
    2378 
    2379 
    2380 /**
    23812381 * Guest page table walk for the AMD64 mode.
    23822382 */
     
    29572957    /** Root of the RAM range search tree for ring-3. */
    29582958    R3PTRTYPE(PPGMRAMRANGE)         pRamRangeTreeR3;
    2959     /** PGM offset based trees - R3 Ptr. */
    2960     R3PTRTYPE(PPGMTREES)            pTreesR3;
    2961     /** Caching the last physical handler we looked up in R3. */
    2962     R3PTRTYPE(PPGMPHYSHANDLER)      pLastPhysHandlerR3;
    29632959    /** Shadow Page Pool - R3 Ptr. */
    29642960    R3PTRTYPE(PPGMPOOL)             pPoolR3;
     
    29782974    /** Root of the RAM range search tree for ring-0. */
    29792975    R0PTRTYPE(PPGMRAMRANGE)         pRamRangeTreeR0;
    2980     /** PGM offset based trees - R0 Ptr. */
    2981     R0PTRTYPE(PPGMTREES)            pTreesR0;
    2982     /** Caching the last physical handler we looked up in R0. */
    2983     R0PTRTYPE(PPGMPHYSHANDLER)      pLastPhysHandlerR0;
    29842976    /** Shadow Page Pool - R0 Ptr. */
    29852977    R0PTRTYPE(PPGMPOOL)             pPoolR0;
     
    29982990     * Initialized to callback causing guru meditations and invalid enmKind. */
    29992991    PGMPHYSHANDLERTYPEINTR3         aPhysHandlerTypes[PGMPHYSHANDLERTYPE_COUNT];
     2992    /** Physical handler allocator, ring-3 edition. */
     2993#ifdef IN_RING3
     2994    PGMPHYSHANDLERALLOCATOR         PhysHandlerAllocator;
     2995#else
     2996    RTCHardAvlTreeSlabAllocatorR3_T PhysHandlerAllocator;
     2997#endif
     2998    /** The pointer to the ring-3 mapping of the physical access handler tree. */
     2999    R3PTRTYPE(PPGMPHYSHANDLERTREE)  pPhysHandlerTree;
     3000    /** Caching the last physical handler we looked. */
     3001    uint32_t                        idxLastPhysHandler;
     3002
     3003    uint32_t                        au64Padding3[5];
    30003004
    30013005    /** PGM critical section.
     
    35583562
    35593563
     3564#if defined(IN_RING0) || defined(DOXYGEN_RUNNING)
     3565
    35603566/**
    35613567 * PGM GVMCPU instance data.
     
    35633569typedef struct PGMR0PERVCPU
    35643570{
    3565 #ifdef VBOX_WITH_STATISTICS
     3571# ifdef VBOX_WITH_STATISTICS
    35663572    /** R0: Which statistic this \#PF should be attributed to. */
    35673573    R0PTRTYPE(PSTAMPROFILE)         pStatTrap0eAttributionR0;
    3568 #endif
     3574# endif
    35693575    uint64_t                        u64Dummy;
    35703576} PGMR0PERVCPU;
     
    35893595     * Initialized to callback causing return to ring-3 and invalid enmKind. */
    35903596    PGMPHYSHANDLERTYPEINTR0         aPhysHandlerTypes[PGMPHYSHANDLERTYPE_COUNT];
     3597    /** Physical handler allocator, ring-3 edition. */
     3598    PGMPHYSHANDLERALLOCATOR         PhysHandlerAllocator;
     3599    /** The pointer to the ring-3 mapping of the physical access handler tree. */
     3600    PPGMPHYSHANDLERTREE             pPhysHandlerTree;
     3601    /** The allocation object for the physical access handler tree. */
     3602    RTR0MEMOBJ                      hPhysHandlerMemObj;
     3603    /** The ring-3 mapping object for the physicall access handler tree. */
     3604    RTR0MEMOBJ                      hPhysHandlerMapObj;
    35913605} PGMR0PERVM;
     3606
     3607#endif /* IN_RING0 || DOXYGEN_RUNNING */
    35923608
    35933609RT_C_DECLS_BEGIN
     
    36183634#define PGM_LOCK_ASSERT_OWNER_EX(a_pVM, a_pVCpu)  Assert(PDMCritSectIsOwnerEx((a_pVCpu), &(a_pVM)->pgm.s.CritSectX))
    36193635
     3636uint32_t        pgmHandlerPhysicalCalcTableSizes(uint32_t *pcEntries, uint32_t *pcbTreeAndBitmap);
    36203637int             pgmHandlerPhysicalExCreate(PVMCC pVM, PGMPHYSHANDLERTYPE hType, uint64_t uUser,
    36213638                                           R3PTRTYPE(const char *) pszDesc, PPGMPHYSHANDLER *ppPhysHandler);
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