VirtualBox

Changeset 93716 in vbox for trunk/src/VBox/VMM/VMMR3/PGM.cpp


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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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
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