Changeset 93716 in vbox for trunk/src/VBox/VMM/VMMR3/PGM.cpp
- Timestamp:
- Feb 14, 2022 10:36:21 AM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/PGM.cpp
r93650 r93716 606 606 #include <VBox/vmm/hm.h> 607 607 #include "PGMInternal.h" 608 #include <VBox/vmm/vm .h>608 #include <VBox/vmm/vmcc.h> 609 609 #include <VBox/vmm/uvm.h> 610 610 #include "PGMInline.h" … … 933 933 934 934 /* 935 * Trees936 */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 /*942 935 * Setup the zero page (HCPHysZeroPg is set by ring-0). 943 936 */ … … 958 951 AssertRelease(pVM->pgm.s.HCPhysMmioPg != 0); 959 952 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 } 960 989 961 990 /* … … 1219 1248 AssertRC(rc); 1220 1249 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 1221 1262 #define PGM_REG_COUNTER_BYTES(a, b, c) \ 1222 1263 rc = STAMR3RegisterF(pVM, a, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES, c, b); \ … … 1283 1324 PGM_REG_COUNTER(&pStats->StatRZPhysHandlerLookupMisses, "/PGM/RZ/PhysHandlerLookupMisses", "The number of cache misses when looking up physical handlers."); 1284 1325 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 1286 1336 PGM_REG_COUNTER(&pStats->StatRZPageReplaceShared, "/PGM/RZ/Page/ReplacedShared", "Times a shared page was replaced."); 1287 1337 PGM_REG_COUNTER(&pStats->StatRZPageReplaceZero, "/PGM/RZ/Page/ReplacedZero", "Times the zero page was replaced."); … … 1323 1373 1324 1374 #undef PGM_REG_COUNTER 1375 #undef PGM_REG_U64 1376 #undef PGM_REG_U64_RESET 1377 #undef PGM_REG_U32 1325 1378 #undef PGM_REG_PROFILE 1326 1379 #undef PGM_REG_PROFILE_NS … … 2104 2157 pszType = "MMIO"; 2105 2158 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)) 2108 2162 pszMore = pHandler->pszDesc; 2109 2163 PGM_UNLOCK(pVM); … … 2537 2591 { 2538 2592 bool fLeftToRight; /**< true: left-to-right; false: right-to-left. */ 2593 uint32_t cErrors; 2539 2594 PPGMPHYSHANDLER pPrevPhys; 2540 2595 PVM pVM; … … 2548 2603 * @param pvUser pVM. 2549 2604 */ 2550 static DECLCALLBACK(int) pgmR3CheckIntegrityPhysHandlerNode(P AVLROGCPHYSNODECOREpNode, void *pvUser)2605 static DECLCALLBACK(int) pgmR3CheckIntegrityPhysHandlerNode(PPGMPHYSHANDLER pNode, void *pvUser) 2551 2606 { 2552 2607 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; 2566 2626 return 0; 2567 2627 } … … 2580 2640 * Check the trees. 2581 2641 */ 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.