Changeset 18984 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Apr 17, 2009 9:00:22 AM (16 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/PGM.cpp
r18974 r18984 1629 1629 PGM_REG_COUNTER(&pPGM->StatRCInvlPgSyncMonCR3, "/PGM/RC/InvlPgSyncMonitorCR3", "Number of times PGMInvalidatePage() ran into PGM_SYNC_MONITOR_CR3."); 1630 1630 1631 /* R0 only: */1632 PGM_REG_COUNTER(&pPGM->StatR0DynMapMigrateInvlPg, "/PGM/R0/DynMapMigrateInvlPg", "invlpg count in PGMDynMapMigrateAutoSet.");1633 PGM_REG_PROFILE(&pPGM->StatR0DynMapGCPageInl, "/PGM/R0/DynMapPageGCPageInl", "Calls to pgmR0DynMapGCPageInlined.");1634 PGM_REG_COUNTER(&pPGM->StatR0DynMapGCPageInlHits, "/PGM/R0/DynMapPageGCPageInl/Hits", "Hash table lookup hits.");1635 PGM_REG_COUNTER(&pPGM->StatR0DynMapGCPageInlMisses, "/PGM/R0/DynMapPageGCPageInl/Misses", "Misses that falls back to code common with PGMDynMapHCPage.");1636 PGM_REG_COUNTER(&pPGM->StatR0DynMapGCPageInlRamHits, "/PGM/R0/DynMapPageGCPageInl/RamHits", "1st ram range hits.");1637 PGM_REG_COUNTER(&pPGM->StatR0DynMapGCPageInlRamMisses, "/PGM/R0/DynMapPageGCPageInl/RamMisses", "1st ram range misses, takes slow path.");1638 PGM_REG_PROFILE(&pPGM->StatR0DynMapHCPageInl, "/PGM/R0/DynMapPageHCPageInl", "Calls to pgmR0DynMapHCPageInlined.");1639 PGM_REG_COUNTER(&pPGM->StatR0DynMapHCPageInlHits, "/PGM/R0/DynMapPageHCPageInl/Hits", "Hash table lookup hits.");1640 PGM_REG_COUNTER(&pPGM->StatR0DynMapHCPageInlMisses, "/PGM/R0/DynMapPageHCPageInl/Misses", "Misses that falls back to code common with PGMDynMapHCPage.");1641 PGM_REG_COUNTER(&pPGM->StatR0DynMapPage, "/PGM/R0/DynMapPage", "Calls to pgmR0DynMapPage");1642 PGM_REG_COUNTER(&pPGM->StatR0DynMapSetOptimize, "/PGM/R0/DynMapPage/SetOptimize", "Calls to pgmDynMapOptimizeAutoSet.");1643 PGM_REG_COUNTER(&pPGM->StatR0DynMapSetSearchFlushes, "/PGM/R0/DynMapPage/SetSearchFlushes","Set search restorting to subset flushes.");1644 PGM_REG_COUNTER(&pPGM->StatR0DynMapSetSearchHits, "/PGM/R0/DynMapPage/SetSearchHits", "Set search hits.");1645 PGM_REG_COUNTER(&pPGM->StatR0DynMapSetSearchMisses, "/PGM/R0/DynMapPage/SetSearchMisses", "Set search misses.");1646 PGM_REG_PROFILE(&pPGM->StatR0DynMapHCPage, "/PGM/R0/DynMapPage/HCPage", "Calls to PGMDynMapHCPage (ring-0).");1647 PGM_REG_COUNTER(&pPGM->StatR0DynMapPageHits0, "/PGM/R0/DynMapPage/Hits0", "Hits at iPage+0");1648 PGM_REG_COUNTER(&pPGM->StatR0DynMapPageHits1, "/PGM/R0/DynMapPage/Hits1", "Hits at iPage+1");1649 PGM_REG_COUNTER(&pPGM->StatR0DynMapPageHits2, "/PGM/R0/DynMapPage/Hits2", "Hits at iPage+2");1650 PGM_REG_COUNTER(&pPGM->StatR0DynMapPageInvlPg, "/PGM/R0/DynMapPage/InvlPg", "invlpg count in pgmR0DynMapPageSlow.");1651 PGM_REG_COUNTER(&pPGM->StatR0DynMapPageSlow, "/PGM/R0/DynMapPage/Slow", "Calls to pgmR0DynMapPageSlow - subtract this from pgmR0DynMapPage to get 1st level hits.");1652 PGM_REG_COUNTER(&pPGM->StatR0DynMapPageSlowLoopHits, "/PGM/R0/DynMapPage/SlowLoopHits" , "Hits in the loop path.");1653 PGM_REG_COUNTER(&pPGM->StatR0DynMapPageSlowLoopMisses, "/PGM/R0/DynMapPage/SlowLoopMisses", "Misses in the loop path. NonLoopMisses = Slow - SlowLoopHit - SlowLoopMisses");1654 //PGM_REG_COUNTER(&pPGM->StatR0DynMapPageSlowLostHits, "/PGM/R0/DynMapPage/SlowLostHits", "Lost hits.");1655 PGM_REG_COUNTER(&pPGM->StatR0DynMapSubsets, "/PGM/R0/Subsets", "Times PGMDynMapPushAutoSubset was called.");1656 PGM_REG_COUNTER(&pPGM->StatR0DynMapPopFlushes, "/PGM/R0/SubsetPopFlushes", "Times PGMDynMapPopAutoSubset flushes the subset.");1657 PGM_REG_COUNTER(&pPGM->aStatR0DynMapSetSize[0], "/PGM/R0/SetSize000..09", "00-09% filled");1658 PGM_REG_COUNTER(&pPGM->aStatR0DynMapSetSize[1], "/PGM/R0/SetSize010..19", "10-19% filled");1659 PGM_REG_COUNTER(&pPGM->aStatR0DynMapSetSize[2], "/PGM/R0/SetSize020..29", "20-29% filled");1660 PGM_REG_COUNTER(&pPGM->aStatR0DynMapSetSize[3], "/PGM/R0/SetSize030..39", "30-39% filled");1661 PGM_REG_COUNTER(&pPGM->aStatR0DynMapSetSize[4], "/PGM/R0/SetSize040..49", "40-49% filled");1662 PGM_REG_COUNTER(&pPGM->aStatR0DynMapSetSize[5], "/PGM/R0/SetSize050..59", "50-59% filled");1663 PGM_REG_COUNTER(&pPGM->aStatR0DynMapSetSize[6], "/PGM/R0/SetSize060..69", "60-69% filled");1664 PGM_REG_COUNTER(&pPGM->aStatR0DynMapSetSize[7], "/PGM/R0/SetSize070..79", "70-79% filled");1665 PGM_REG_COUNTER(&pPGM->aStatR0DynMapSetSize[8], "/PGM/R0/SetSize080..89", "80-89% filled");1666 PGM_REG_COUNTER(&pPGM->aStatR0DynMapSetSize[9], "/PGM/R0/SetSize090..99", "90-99% filled");1667 PGM_REG_COUNTER(&pPGM->aStatR0DynMapSetSize[10], "/PGM/R0/SetSize100", "100% filled");1668 1669 1631 # ifdef PGMPOOL_WITH_GCPHYS_TRACKING 1670 1632 PGM_REG_COUNTER(&pPGM->StatTrackVirgin, "/PGM/Track/Virgin", "The number of first time shadowings"); … … 1708 1670 STAMR3RegisterF(pVM, &pPGM->StatSyncPagePD[i], STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_OCCURENCES, 1709 1671 "The number of SyncPage per PD n.", "/PGM/CPU%d/PDSyncPage/%04X", i, j); 1672 1673 /* R0 only: */ 1674 PGM_REG_COUNTER(&pPGM->StatR0DynMapMigrateInvlPg, "/PGM/CPU%d/R0/DynMapMigrateInvlPg", "invlpg count in PGMDynMapMigrateAutoSet."); 1675 PGM_REG_PROFILE(&pPGM->StatR0DynMapGCPageInl, "/PGM/CPU%d/R0/DynMapPageGCPageInl", "Calls to pgmR0DynMapGCPageInlined."); 1676 PGM_REG_COUNTER(&pPGM->StatR0DynMapGCPageInlHits, "/PGM/CPU%d/R0/DynMapPageGCPageInl/Hits", "Hash table lookup hits."); 1677 PGM_REG_COUNTER(&pPGM->StatR0DynMapGCPageInlMisses, "/PGM/CPU%d/R0/DynMapPageGCPageInl/Misses", "Misses that falls back to code common with PGMDynMapHCPage."); 1678 PGM_REG_COUNTER(&pPGM->StatR0DynMapGCPageInlRamHits, "/PGM/CPU%d/R0/DynMapPageGCPageInl/RamHits", "1st ram range hits."); 1679 PGM_REG_COUNTER(&pPGM->StatR0DynMapGCPageInlRamMisses, "/PGM/CPU%d/R0/DynMapPageGCPageInl/RamMisses", "1st ram range misses, takes slow path."); 1680 PGM_REG_PROFILE(&pPGM->StatR0DynMapHCPageInl, "/PGM/CPU%d/R0/DynMapPageHCPageInl", "Calls to pgmR0DynMapHCPageInlined."); 1681 PGM_REG_COUNTER(&pPGM->StatR0DynMapHCPageInlHits, "/PGM/CPU%d/R0/DynMapPageHCPageInl/Hits", "Hash table lookup hits."); 1682 PGM_REG_COUNTER(&pPGM->StatR0DynMapHCPageInlMisses, "/PGM/CPU%d/R0/DynMapPageHCPageInl/Misses", "Misses that falls back to code common with PGMDynMapHCPage."); 1683 PGM_REG_COUNTER(&pPGM->StatR0DynMapPage, "/PGM/CPU%d/R0/DynMapPage", "Calls to pgmR0DynMapPage"); 1684 PGM_REG_COUNTER(&pPGM->StatR0DynMapSetOptimize, "/PGM/CPU%d/R0/DynMapPage/SetOptimize", "Calls to pgmDynMapOptimizeAutoSet."); 1685 PGM_REG_COUNTER(&pPGM->StatR0DynMapSetSearchFlushes, "/PGM/CPU%d/R0/DynMapPage/SetSearchFlushes","Set search restorting to subset flushes."); 1686 PGM_REG_COUNTER(&pPGM->StatR0DynMapSetSearchHits, "/PGM/CPU%d/R0/DynMapPage/SetSearchHits", "Set search hits."); 1687 PGM_REG_COUNTER(&pPGM->StatR0DynMapSetSearchMisses, "/PGM/CPU%d/R0/DynMapPage/SetSearchMisses", "Set search misses."); 1688 PGM_REG_PROFILE(&pPGM->StatR0DynMapHCPage, "/PGM/CPU%d/R0/DynMapPage/HCPage", "Calls to PGMDynMapHCPage (ring-0)."); 1689 PGM_REG_COUNTER(&pPGM->StatR0DynMapPageHits0, "/PGM/CPU%d/R0/DynMapPage/Hits0", "Hits at iPage+0"); 1690 PGM_REG_COUNTER(&pPGM->StatR0DynMapPageHits1, "/PGM/CPU%d/R0/DynMapPage/Hits1", "Hits at iPage+1"); 1691 PGM_REG_COUNTER(&pPGM->StatR0DynMapPageHits2, "/PGM/CPU%d/R0/DynMapPage/Hits2", "Hits at iPage+2"); 1692 PGM_REG_COUNTER(&pPGM->StatR0DynMapPageInvlPg, "/PGM/CPU%d/R0/DynMapPage/InvlPg", "invlpg count in pgmR0DynMapPageSlow."); 1693 PGM_REG_COUNTER(&pPGM->StatR0DynMapPageSlow, "/PGM/CPU%d/R0/DynMapPage/Slow", "Calls to pgmR0DynMapPageSlow - subtract this from pgmR0DynMapPage to get 1st level hits."); 1694 PGM_REG_COUNTER(&pPGM->StatR0DynMapPageSlowLoopHits, "/PGM/CPU%d/R0/DynMapPage/SlowLoopHits" , "Hits in the loop path."); 1695 PGM_REG_COUNTER(&pPGM->StatR0DynMapPageSlowLoopMisses, "/PGM/CPU%d/R0/DynMapPage/SlowLoopMisses", "Misses in the loop path. NonLoopMisses = Slow - SlowLoopHit - SlowLoopMisses"); 1696 //PGM_REG_COUNTER(&pPGM->StatR0DynMapPageSlowLostHits, "/PGM/CPU%d/R0/DynMapPage/SlowLostHits", "Lost hits."); 1697 PGM_REG_COUNTER(&pPGM->StatR0DynMapSubsets, "/PGM/CPU%d/R0/Subsets", "Times PGMDynMapPushAutoSubset was called."); 1698 PGM_REG_COUNTER(&pPGM->StatR0DynMapPopFlushes, "/PGM/CPU%d/R0/SubsetPopFlushes", "Times PGMDynMapPopAutoSubset flushes the subset."); 1699 PGM_REG_COUNTER(&pPGM->aStatR0DynMapSetSize[0], "/PGM/CPU%d/R0/SetSize000..09", "00-09% filled"); 1700 PGM_REG_COUNTER(&pPGM->aStatR0DynMapSetSize[1], "/PGM/CPU%d/R0/SetSize010..19", "10-19% filled"); 1701 PGM_REG_COUNTER(&pPGM->aStatR0DynMapSetSize[2], "/PGM/CPU%d/R0/SetSize020..29", "20-29% filled"); 1702 PGM_REG_COUNTER(&pPGM->aStatR0DynMapSetSize[3], "/PGM/CPU%d/R0/SetSize030..39", "30-39% filled"); 1703 PGM_REG_COUNTER(&pPGM->aStatR0DynMapSetSize[4], "/PGM/CPU%d/R0/SetSize040..49", "40-49% filled"); 1704 PGM_REG_COUNTER(&pPGM->aStatR0DynMapSetSize[5], "/PGM/CPU%d/R0/SetSize050..59", "50-59% filled"); 1705 PGM_REG_COUNTER(&pPGM->aStatR0DynMapSetSize[6], "/PGM/CPU%d/R0/SetSize060..69", "60-69% filled"); 1706 PGM_REG_COUNTER(&pPGM->aStatR0DynMapSetSize[7], "/PGM/CPU%d/R0/SetSize070..79", "70-79% filled"); 1707 PGM_REG_COUNTER(&pPGM->aStatR0DynMapSetSize[8], "/PGM/CPU%d/R0/SetSize080..89", "80-89% filled"); 1708 PGM_REG_COUNTER(&pPGM->aStatR0DynMapSetSize[9], "/PGM/CPU%d/R0/SetSize090..99", "90-99% filled"); 1709 PGM_REG_COUNTER(&pPGM->aStatR0DynMapSetSize[10], "/PGM/CPU%d/R0/SetSize100", "100% filled"); 1710 1710 1711 1711 /* RZ only: */ -
trunk/src/VBox/VMM/PGMInternal.h
r18980 r18984 2197 2197 SUPPAGINGMODE enmHostMode; 2198 2198 2199 #ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R02200 /** Automatically tracked physical memory mapping set.2201 * Ring-0 and strict raw-mode builds. */2202 PGMMAPSET AutoSet;2203 #endif2204 2205 2199 /** 4 MB page mask; 32 or 36 bits depending on PSE-36 (identical for all VCPUs) */ 2206 2200 RTGCPHYS GCPhys4MBPSEMask; … … 2457 2451 STAMCOUNTER StatRCInvlPgConflict; /**< RC: Number of times PGMInvalidatePage() detected a mapping conflict. */ 2458 2452 STAMCOUNTER StatRCInvlPgSyncMonCR3; /**< RC: Number of times PGMInvalidatePage() ran into PGM_SYNC_MONITOR_CR3. */ 2453 2454 # ifdef PGMPOOL_WITH_GCPHYS_TRACKING 2455 STAMCOUNTER StatTrackVirgin; /**< The number of first time shadowings. */ 2456 STAMCOUNTER StatTrackAliased; /**< The number of times switching to cRef2, i.e. the page is being shadowed by two PTs. */ 2457 STAMCOUNTER StatTrackAliasedMany; /**< The number of times we're tracking using cRef2. */ 2458 STAMCOUNTER StatTrackAliasedLots; /**< The number of times we're hitting pages which has overflowed cRef2. */ 2459 STAMCOUNTER StatTrackOverflows; /**< The number of times the extent list grows to long. */ 2460 STAMPROFILE StatTrackDeref; /**< Profiling of SyncPageWorkerTrackDeref (expensive). */ 2461 # endif 2462 #endif 2463 } PGM; 2464 /** Pointer to the PGM instance data. */ 2465 typedef PGM *PPGM; 2466 2467 2468 /** 2469 * Converts a PGMCPU pointer into a VM pointer. 2470 * @returns Pointer to the VM structure the PGM is part of. 2471 * @param pPGM Pointer to PGMCPU instance data. 2472 */ 2473 #define PGMCPU2VM(pPGM) ( (PVM)((char*)pPGM - pPGM->offVM) ) 2474 2475 /** 2476 * Converts a PGMCPU pointer into a PGM pointer. 2477 * @returns Pointer to the VM structure the PGM is part of. 2478 * @param pPGM Pointer to PGMCPU instance data. 2479 */ 2480 #define PGMCPU2PGM(pPGMCpu) ( (PPGM)((char*)pPGMCpu - pPGMCpu->offPGM) ) 2481 2482 /** 2483 * PGMCPU Data (part of VMCPU). 2484 */ 2485 typedef struct PGMCPU 2486 { 2487 /** Offset to the VM structure. */ 2488 RTINT offVM; 2489 /** Offset to the VMCPU structure. */ 2490 RTINT offVCpu; 2491 /** Offset of the PGM structure relative to VMCPU. */ 2492 RTINT offPGM; 2493 RTINT uPadding0; /**< structure size alignment. */ 2494 2495 #ifdef VBOX_WITH_2X_4GB_ADDR_SPACE 2496 /** Automatically tracked physical memory mapping set. 2497 * Ring-0 and strict raw-mode builds. */ 2498 PGMMAPSET AutoSet; 2499 #endif 2500 2501 /** A20 gate mask. 2502 * Our current approach to A20 emulation is to let REM do it and don't bother 2503 * anywhere else. The interesting Guests will be operating with it enabled anyway. 2504 * But whould need arrise, we'll subject physical addresses to this mask. */ 2505 RTGCPHYS GCPhysA20Mask; 2506 /** A20 gate state - boolean! */ 2507 bool fA20Enabled; 2508 2509 /** What needs syncing (PGM_SYNC_*). 2510 * This is used to queue operations for PGMSyncCR3, PGMInvalidatePage, 2511 * PGMFlushTLB, and PGMR3Load. */ 2512 RTUINT fSyncFlags; 2513 2514 /** The shadow paging mode. */ 2515 PGMMODE enmShadowMode; 2516 /** The guest paging mode. */ 2517 PGMMODE enmGuestMode; 2518 2519 /** The current physical address representing in the guest CR3 register. */ 2520 RTGCPHYS GCPhysCR3; 2521 2522 /** @name 32-bit Guest Paging. 2523 * @{ */ 2524 /** The guest's page directory, R3 pointer. */ 2525 R3PTRTYPE(PX86PD) pGst32BitPdR3; 2526 #ifndef VBOX_WITH_2X_4GB_ADDR_SPACE 2527 /** The guest's page directory, R0 pointer. */ 2528 R0PTRTYPE(PX86PD) pGst32BitPdR0; 2529 #endif 2530 /** The guest's page directory, static RC mapping. */ 2531 RCPTRTYPE(PX86PD) pGst32BitPdRC; 2532 /** @} */ 2533 2534 /** @name PAE Guest Paging. 2535 * @{ */ 2536 /** The guest's page directory pointer table, static RC mapping. */ 2537 RCPTRTYPE(PX86PDPT) pGstPaePdptRC; 2538 /** The guest's page directory pointer table, R3 pointer. */ 2539 R3PTRTYPE(PX86PDPT) pGstPaePdptR3; 2540 #ifndef VBOX_WITH_2X_4GB_ADDR_SPACE 2541 /** The guest's page directory pointer table, R0 pointer. */ 2542 R0PTRTYPE(PX86PDPT) pGstPaePdptR0; 2543 #endif 2544 2545 /** The guest's page directories, R3 pointers. 2546 * These are individual pointers and don't have to be adjecent. 2547 * These don't have to be up-to-date - use pgmGstGetPaePD() to access them. */ 2548 R3PTRTYPE(PX86PDPAE) apGstPaePDsR3[4]; 2549 /** The guest's page directories, R0 pointers. 2550 * Same restrictions as apGstPaePDsR3. */ 2551 #ifndef VBOX_WITH_2X_4GB_ADDR_SPACE 2552 R0PTRTYPE(PX86PDPAE) apGstPaePDsR0[4]; 2553 #endif 2554 /** The guest's page directories, static GC mapping. 2555 * Unlike the R3/R0 array the first entry can be accessed as a 2048 entry PD. 2556 * These don't have to be up-to-date - use pgmGstGetPaePD() to access them. */ 2557 RCPTRTYPE(PX86PDPAE) apGstPaePDsRC[4]; 2558 /** The physical addresses of the guest page directories (PAE) pointed to by apGstPagePDsHC/GC. */ 2559 RTGCPHYS aGCPhysGstPaePDs[4]; 2560 /** The physical addresses of the monitored guest page directories (PAE). */ 2561 RTGCPHYS aGCPhysGstPaePDsMonitored[4]; 2562 /** @} */ 2563 2564 /** @name AMD64 Guest Paging. 2565 * @{ */ 2566 /** The guest's page directory pointer table, R3 pointer. */ 2567 R3PTRTYPE(PX86PML4) pGstAmd64Pml4R3; 2568 #ifndef VBOX_WITH_2X_4GB_ADDR_SPACE 2569 /** The guest's page directory pointer table, R0 pointer. */ 2570 R0PTRTYPE(PX86PML4) pGstAmd64Pml4R0; 2571 #endif 2572 /** @} */ 2573 2574 /** Pointer to the page of the current active CR3 - R3 Ptr. */ 2575 R3PTRTYPE(PPGMPOOLPAGE) pShwPageCR3R3; 2576 /** Pointer to the page of the current active CR3 - R0 Ptr. */ 2577 R0PTRTYPE(PPGMPOOLPAGE) pShwPageCR3R0; 2578 /** Pointer to the page of the current active CR3 - RC Ptr. */ 2579 RCPTRTYPE(PPGMPOOLPAGE) pShwPageCR3RC; 2580 /* The shadow page pool index of the user table as specified during allocation; useful for freeing root pages */ 2581 uint32_t iShwUser; 2582 /* The index into the user table (shadowed) as specified during allocation; useful for freeing root pages. */ 2583 uint32_t iShwUserTable; 2584 # if HC_ARCH_BITS == 64 2585 RTRCPTR alignment6; /**< structure size alignment. */ 2586 # endif 2587 /** @} */ 2588 2589 /** @name Function pointers for Shadow paging. 2590 * @{ 2591 */ 2592 DECLR3CALLBACKMEMBER(int, pfnR3ShwRelocate,(PVM pVM, PVMCPU pVCpu, RTGCPTR offDelta)); 2593 DECLR3CALLBACKMEMBER(int, pfnR3ShwExit,(PVM pVM, PVMCPU pVCpu)); 2594 DECLR3CALLBACKMEMBER(int, pfnR3ShwGetPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTHCPHYS pHCPhys)); 2595 DECLR3CALLBACKMEMBER(int, pfnR3ShwModifyPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask)); 2596 2597 DECLRCCALLBACKMEMBER(int, pfnRCShwGetPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTHCPHYS pHCPhys)); 2598 DECLRCCALLBACKMEMBER(int, pfnRCShwModifyPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask)); 2599 2600 DECLR0CALLBACKMEMBER(int, pfnR0ShwGetPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTHCPHYS pHCPhys)); 2601 DECLR0CALLBACKMEMBER(int, pfnR0ShwModifyPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask)); 2602 2603 /** @} */ 2604 2605 /** @name Function pointers for Guest paging. 2606 * @{ 2607 */ 2608 DECLR3CALLBACKMEMBER(int, pfnR3GstRelocate,(PVM pVM, PVMCPU pVCpu, RTGCPTR offDelta)); 2609 DECLR3CALLBACKMEMBER(int, pfnR3GstExit,(PVM pVM, PVMCPU pVCpu)); 2610 DECLR3CALLBACKMEMBER(int, pfnR3GstGetPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTGCPHYS pGCPhys)); 2611 DECLR3CALLBACKMEMBER(int, pfnR3GstModifyPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask)); 2612 DECLR3CALLBACKMEMBER(int, pfnR3GstGetPDE,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, PX86PDEPAE pPde)); 2613 DECLRCCALLBACKMEMBER(int, pfnRCGstGetPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTGCPHYS pGCPhys)); 2614 DECLRCCALLBACKMEMBER(int, pfnRCGstModifyPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask)); 2615 DECLRCCALLBACKMEMBER(int, pfnRCGstGetPDE,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, PX86PDEPAE pPde)); 2616 #if HC_ARCH_BITS == 64 2617 RTRCPTR alignment3; /**< structure size alignment. */ 2618 #endif 2619 2620 DECLR0CALLBACKMEMBER(int, pfnR0GstGetPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTGCPHYS pGCPhys)); 2621 DECLR0CALLBACKMEMBER(int, pfnR0GstModifyPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask)); 2622 DECLR0CALLBACKMEMBER(int, pfnR0GstGetPDE,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, PX86PDEPAE pPde)); 2623 /** @} */ 2624 2625 /** @name Function pointers for Both Shadow and Guest paging. 2626 * @{ 2627 */ 2628 DECLR3CALLBACKMEMBER(int, pfnR3BthRelocate,(PVM pVM, PVMCPU pVCpu, RTGCPTR offDelta)); 2629 /* no pfnR3BthTrap0eHandler */ 2630 DECLR3CALLBACKMEMBER(int, pfnR3BthInvalidatePage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtrPage)); 2631 DECLR3CALLBACKMEMBER(int, pfnR3BthSyncCR3,(PVM pVM, PVMCPU pVCpu, uint64_t cr0, uint64_t cr3, uint64_t cr4, bool fGlobal)); 2632 DECLR3CALLBACKMEMBER(int, pfnR3BthSyncPage,(PVM pVM, PVMCPU pVCpu, X86PDE PdeSrc, RTGCPTR GCPtrPage, unsigned cPages, unsigned uError)); 2633 DECLR3CALLBACKMEMBER(int, pfnR3BthPrefetchPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtrPage)); 2634 DECLR3CALLBACKMEMBER(int, pfnR3BthVerifyAccessSyncPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtrPage, unsigned fFlags, unsigned uError)); 2635 DECLR3CALLBACKMEMBER(unsigned, pfnR3BthAssertCR3,(PVM pVM, PVMCPU pVCpu, uint64_t cr3, uint64_t cr4, RTGCPTR GCPtr, RTGCPTR cb)); 2636 DECLR3CALLBACKMEMBER(int, pfnR3BthMapCR3,(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhysCR3)); 2637 DECLR3CALLBACKMEMBER(int, pfnR3BthUnmapCR3,(PVM pVM, PVMCPU pVCpu)); 2638 2639 DECLR0CALLBACKMEMBER(int, pfnR0BthTrap0eHandler,(PVM pVM, PVMCPU pVCpu, RTGCUINT uErr, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault)); 2640 DECLR0CALLBACKMEMBER(int, pfnR0BthInvalidatePage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtrPage)); 2641 DECLR0CALLBACKMEMBER(int, pfnR0BthSyncCR3,(PVM pVM, PVMCPU pVCpu, uint64_t cr0, uint64_t cr3, uint64_t cr4, bool fGlobal)); 2642 DECLR0CALLBACKMEMBER(int, pfnR0BthSyncPage,(PVM pVM, PVMCPU pVCpu, X86PDE PdeSrc, RTGCPTR GCPtrPage, unsigned cPages, unsigned uError)); 2643 DECLR0CALLBACKMEMBER(int, pfnR0BthPrefetchPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtrPage)); 2644 DECLR0CALLBACKMEMBER(int, pfnR0BthVerifyAccessSyncPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtrPage, unsigned fFlags, unsigned uError)); 2645 DECLR0CALLBACKMEMBER(unsigned, pfnR0BthAssertCR3,(PVM pVM, PVMCPU pVCpu, uint64_t cr3, uint64_t cr4, RTGCPTR GCPtr, RTGCPTR cb)); 2646 DECLR0CALLBACKMEMBER(int, pfnR0BthMapCR3,(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhysCR3)); 2647 DECLR0CALLBACKMEMBER(int, pfnR0BthUnmapCR3,(PVM pVM, PVMCPU pVCpu)); 2648 2649 DECLRCCALLBACKMEMBER(int, pfnRCBthTrap0eHandler,(PVM pVM, PVMCPU pVCpu, RTGCUINT uErr, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault)); 2650 DECLRCCALLBACKMEMBER(int, pfnRCBthInvalidatePage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtrPage)); 2651 DECLRCCALLBACKMEMBER(int, pfnRCBthSyncCR3,(PVM pVM, PVMCPU pVCpu, uint64_t cr0, uint64_t cr3, uint64_t cr4, bool fGlobal)); 2652 DECLRCCALLBACKMEMBER(int, pfnRCBthSyncPage,(PVM pVM, PVMCPU pVCpu, X86PDE PdeSrc, RTGCPTR GCPtrPage, unsigned cPages, unsigned uError)); 2653 DECLRCCALLBACKMEMBER(int, pfnRCBthPrefetchPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtrPage)); 2654 DECLRCCALLBACKMEMBER(int, pfnRCBthVerifyAccessSyncPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtrPage, unsigned fFlags, unsigned uError)); 2655 DECLRCCALLBACKMEMBER(unsigned, pfnRCBthAssertCR3,(PVM pVM, PVMCPU pVCpu, uint64_t cr3, uint64_t cr4, RTGCPTR GCPtr, RTGCPTR cb)); 2656 DECLRCCALLBACKMEMBER(int, pfnRCBthMapCR3,(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhysCR3)); 2657 DECLRCCALLBACKMEMBER(int, pfnRCBthUnmapCR3,(PVM pVM, PVMCPU pVCpu)); 2658 #if HC_ARCH_BITS == 64 2659 RTRCPTR alignment2; /**< structure size alignment. */ 2660 #endif 2661 /** @} */ 2662 2663 /** @name Release Statistics 2664 * @{ */ 2665 /** The number of times the guest has switched mode since last reset or statistics reset. */ 2666 STAMCOUNTER cGuestModeChanges; 2667 /** @} */ 2668 2669 #ifdef VBOX_WITH_STATISTICS /** @todo move this chunk to the heap. */ 2670 /** @name Statistics 2671 * @{ */ 2672 /** RC: Which statistic this \#PF should be attributed to. */ 2673 RCPTRTYPE(PSTAMPROFILE) pStatTrap0eAttributionRC; 2674 RTRCPTR padding0; 2675 /** R0: Which statistic this \#PF should be attributed to. */ 2676 R0PTRTYPE(PSTAMPROFILE) pStatTrap0eAttributionR0; 2677 RTR0PTR padding1; 2678 2679 /* Common */ 2680 STAMCOUNTER StatSyncPtPD[X86_PG_ENTRIES]; /**< SyncPT - PD distribution. */ 2681 STAMCOUNTER StatSyncPagePD[X86_PG_ENTRIES]; /**< SyncPage - PD distribution. */ 2459 2682 2460 2683 /* R0 only: */ … … 2485 2708 STAMCOUNTER StatR0DynMapPopFlushes; /**< R0: Times PGMDynMapPopAutoSubset flushes the subset. */ 2486 2709 STAMCOUNTER aStatR0DynMapSetSize[11]; /**< R0: Set size distribution. */ 2487 2488 # ifdef PGMPOOL_WITH_GCPHYS_TRACKING2489 STAMCOUNTER StatTrackVirgin; /**< The number of first time shadowings. */2490 STAMCOUNTER StatTrackAliased; /**< The number of times switching to cRef2, i.e. the page is being shadowed by two PTs. */2491 STAMCOUNTER StatTrackAliasedMany; /**< The number of times we're tracking using cRef2. */2492 STAMCOUNTER StatTrackAliasedLots; /**< The number of times we're hitting pages which has overflowed cRef2. */2493 STAMCOUNTER StatTrackOverflows; /**< The number of times the extent list grows to long. */2494 STAMPROFILE StatTrackDeref; /**< Profiling of SyncPageWorkerTrackDeref (expensive). */2495 # endif2496 #endif2497 } PGM;2498 /** Pointer to the PGM instance data. */2499 typedef PGM *PPGM;2500 2501 2502 /**2503 * Converts a PGMCPU pointer into a VM pointer.2504 * @returns Pointer to the VM structure the PGM is part of.2505 * @param pPGM Pointer to PGMCPU instance data.2506 */2507 #define PGMCPU2VM(pPGM) ( (PVM)((char*)pPGM - pPGM->offVM) )2508 2509 /**2510 * Converts a PGMCPU pointer into a PGM pointer.2511 * @returns Pointer to the VM structure the PGM is part of.2512 * @param pPGM Pointer to PGMCPU instance data.2513 */2514 #define PGMCPU2PGM(pPGMCpu) ( (PPGM)((char*)pPGMCpu - pPGMCpu->offPGM) )2515 2516 /**2517 * PGMCPU Data (part of VMCPU).2518 */2519 typedef struct PGMCPU2520 {2521 /** Offset to the VM structure. */2522 RTINT offVM;2523 /** Offset to the VMCPU structure. */2524 RTINT offVCpu;2525 /** Offset of the PGM structure relative to VMCPU. */2526 RTINT offPGM;2527 RTINT uPadding0; /**< structure size alignment. */2528 2529 /** A20 gate mask.2530 * Our current approach to A20 emulation is to let REM do it and don't bother2531 * anywhere else. The interesting Guests will be operating with it enabled anyway.2532 * But whould need arrise, we'll subject physical addresses to this mask. */2533 RTGCPHYS GCPhysA20Mask;2534 /** A20 gate state - boolean! */2535 bool fA20Enabled;2536 2537 /** What needs syncing (PGM_SYNC_*).2538 * This is used to queue operations for PGMSyncCR3, PGMInvalidatePage,2539 * PGMFlushTLB, and PGMR3Load. */2540 RTUINT fSyncFlags;2541 2542 /** The shadow paging mode. */2543 PGMMODE enmShadowMode;2544 /** The guest paging mode. */2545 PGMMODE enmGuestMode;2546 2547 /** The current physical address representing in the guest CR3 register. */2548 RTGCPHYS GCPhysCR3;2549 2550 /** @name 32-bit Guest Paging.2551 * @{ */2552 /** The guest's page directory, R3 pointer. */2553 R3PTRTYPE(PX86PD) pGst32BitPdR3;2554 #ifndef VBOX_WITH_2X_4GB_ADDR_SPACE2555 /** The guest's page directory, R0 pointer. */2556 R0PTRTYPE(PX86PD) pGst32BitPdR0;2557 #endif2558 /** The guest's page directory, static RC mapping. */2559 RCPTRTYPE(PX86PD) pGst32BitPdRC;2560 /** @} */2561 2562 /** @name PAE Guest Paging.2563 * @{ */2564 /** The guest's page directory pointer table, static RC mapping. */2565 RCPTRTYPE(PX86PDPT) pGstPaePdptRC;2566 /** The guest's page directory pointer table, R3 pointer. */2567 R3PTRTYPE(PX86PDPT) pGstPaePdptR3;2568 #ifndef VBOX_WITH_2X_4GB_ADDR_SPACE2569 /** The guest's page directory pointer table, R0 pointer. */2570 R0PTRTYPE(PX86PDPT) pGstPaePdptR0;2571 #endif2572 2573 /** The guest's page directories, R3 pointers.2574 * These are individual pointers and don't have to be adjecent.2575 * These don't have to be up-to-date - use pgmGstGetPaePD() to access them. */2576 R3PTRTYPE(PX86PDPAE) apGstPaePDsR3[4];2577 /** The guest's page directories, R0 pointers.2578 * Same restrictions as apGstPaePDsR3. */2579 #ifndef VBOX_WITH_2X_4GB_ADDR_SPACE2580 R0PTRTYPE(PX86PDPAE) apGstPaePDsR0[4];2581 #endif2582 /** The guest's page directories, static GC mapping.2583 * Unlike the R3/R0 array the first entry can be accessed as a 2048 entry PD.2584 * These don't have to be up-to-date - use pgmGstGetPaePD() to access them. */2585 RCPTRTYPE(PX86PDPAE) apGstPaePDsRC[4];2586 /** The physical addresses of the guest page directories (PAE) pointed to by apGstPagePDsHC/GC. */2587 RTGCPHYS aGCPhysGstPaePDs[4];2588 /** The physical addresses of the monitored guest page directories (PAE). */2589 RTGCPHYS aGCPhysGstPaePDsMonitored[4];2590 /** @} */2591 2592 /** @name AMD64 Guest Paging.2593 * @{ */2594 /** The guest's page directory pointer table, R3 pointer. */2595 R3PTRTYPE(PX86PML4) pGstAmd64Pml4R3;2596 #ifndef VBOX_WITH_2X_4GB_ADDR_SPACE2597 /** The guest's page directory pointer table, R0 pointer. */2598 R0PTRTYPE(PX86PML4) pGstAmd64Pml4R0;2599 #endif2600 /** @} */2601 2602 /** Pointer to the page of the current active CR3 - R3 Ptr. */2603 R3PTRTYPE(PPGMPOOLPAGE) pShwPageCR3R3;2604 /** Pointer to the page of the current active CR3 - R0 Ptr. */2605 R0PTRTYPE(PPGMPOOLPAGE) pShwPageCR3R0;2606 /** Pointer to the page of the current active CR3 - RC Ptr. */2607 RCPTRTYPE(PPGMPOOLPAGE) pShwPageCR3RC;2608 /* The shadow page pool index of the user table as specified during allocation; useful for freeing root pages */2609 uint32_t iShwUser;2610 /* The index into the user table (shadowed) as specified during allocation; useful for freeing root pages. */2611 uint32_t iShwUserTable;2612 # if HC_ARCH_BITS == 642613 RTRCPTR alignment6; /**< structure size alignment. */2614 # endif2615 /** @} */2616 2617 /** @name Function pointers for Shadow paging.2618 * @{2619 */2620 DECLR3CALLBACKMEMBER(int, pfnR3ShwRelocate,(PVM pVM, PVMCPU pVCpu, RTGCPTR offDelta));2621 DECLR3CALLBACKMEMBER(int, pfnR3ShwExit,(PVM pVM, PVMCPU pVCpu));2622 DECLR3CALLBACKMEMBER(int, pfnR3ShwGetPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTHCPHYS pHCPhys));2623 DECLR3CALLBACKMEMBER(int, pfnR3ShwModifyPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask));2624 2625 DECLRCCALLBACKMEMBER(int, pfnRCShwGetPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTHCPHYS pHCPhys));2626 DECLRCCALLBACKMEMBER(int, pfnRCShwModifyPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask));2627 2628 DECLR0CALLBACKMEMBER(int, pfnR0ShwGetPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTHCPHYS pHCPhys));2629 DECLR0CALLBACKMEMBER(int, pfnR0ShwModifyPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask));2630 2631 /** @} */2632 2633 /** @name Function pointers for Guest paging.2634 * @{2635 */2636 DECLR3CALLBACKMEMBER(int, pfnR3GstRelocate,(PVM pVM, PVMCPU pVCpu, RTGCPTR offDelta));2637 DECLR3CALLBACKMEMBER(int, pfnR3GstExit,(PVM pVM, PVMCPU pVCpu));2638 DECLR3CALLBACKMEMBER(int, pfnR3GstGetPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTGCPHYS pGCPhys));2639 DECLR3CALLBACKMEMBER(int, pfnR3GstModifyPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask));2640 DECLR3CALLBACKMEMBER(int, pfnR3GstGetPDE,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, PX86PDEPAE pPde));2641 DECLRCCALLBACKMEMBER(int, pfnRCGstGetPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTGCPHYS pGCPhys));2642 DECLRCCALLBACKMEMBER(int, pfnRCGstModifyPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask));2643 DECLRCCALLBACKMEMBER(int, pfnRCGstGetPDE,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, PX86PDEPAE pPde));2644 #if HC_ARCH_BITS == 642645 RTRCPTR alignment3; /**< structure size alignment. */2646 #endif2647 2648 DECLR0CALLBACKMEMBER(int, pfnR0GstGetPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTGCPHYS pGCPhys));2649 DECLR0CALLBACKMEMBER(int, pfnR0GstModifyPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask));2650 DECLR0CALLBACKMEMBER(int, pfnR0GstGetPDE,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, PX86PDEPAE pPde));2651 /** @} */2652 2653 /** @name Function pointers for Both Shadow and Guest paging.2654 * @{2655 */2656 DECLR3CALLBACKMEMBER(int, pfnR3BthRelocate,(PVM pVM, PVMCPU pVCpu, RTGCPTR offDelta));2657 /* no pfnR3BthTrap0eHandler */2658 DECLR3CALLBACKMEMBER(int, pfnR3BthInvalidatePage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtrPage));2659 DECLR3CALLBACKMEMBER(int, pfnR3BthSyncCR3,(PVM pVM, PVMCPU pVCpu, uint64_t cr0, uint64_t cr3, uint64_t cr4, bool fGlobal));2660 DECLR3CALLBACKMEMBER(int, pfnR3BthSyncPage,(PVM pVM, PVMCPU pVCpu, X86PDE PdeSrc, RTGCPTR GCPtrPage, unsigned cPages, unsigned uError));2661 DECLR3CALLBACKMEMBER(int, pfnR3BthPrefetchPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtrPage));2662 DECLR3CALLBACKMEMBER(int, pfnR3BthVerifyAccessSyncPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtrPage, unsigned fFlags, unsigned uError));2663 DECLR3CALLBACKMEMBER(unsigned, pfnR3BthAssertCR3,(PVM pVM, PVMCPU pVCpu, uint64_t cr3, uint64_t cr4, RTGCPTR GCPtr, RTGCPTR cb));2664 DECLR3CALLBACKMEMBER(int, pfnR3BthMapCR3,(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhysCR3));2665 DECLR3CALLBACKMEMBER(int, pfnR3BthUnmapCR3,(PVM pVM, PVMCPU pVCpu));2666 2667 DECLR0CALLBACKMEMBER(int, pfnR0BthTrap0eHandler,(PVM pVM, PVMCPU pVCpu, RTGCUINT uErr, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault));2668 DECLR0CALLBACKMEMBER(int, pfnR0BthInvalidatePage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtrPage));2669 DECLR0CALLBACKMEMBER(int, pfnR0BthSyncCR3,(PVM pVM, PVMCPU pVCpu, uint64_t cr0, uint64_t cr3, uint64_t cr4, bool fGlobal));2670 DECLR0CALLBACKMEMBER(int, pfnR0BthSyncPage,(PVM pVM, PVMCPU pVCpu, X86PDE PdeSrc, RTGCPTR GCPtrPage, unsigned cPages, unsigned uError));2671 DECLR0CALLBACKMEMBER(int, pfnR0BthPrefetchPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtrPage));2672 DECLR0CALLBACKMEMBER(int, pfnR0BthVerifyAccessSyncPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtrPage, unsigned fFlags, unsigned uError));2673 DECLR0CALLBACKMEMBER(unsigned, pfnR0BthAssertCR3,(PVM pVM, PVMCPU pVCpu, uint64_t cr3, uint64_t cr4, RTGCPTR GCPtr, RTGCPTR cb));2674 DECLR0CALLBACKMEMBER(int, pfnR0BthMapCR3,(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhysCR3));2675 DECLR0CALLBACKMEMBER(int, pfnR0BthUnmapCR3,(PVM pVM, PVMCPU pVCpu));2676 2677 DECLRCCALLBACKMEMBER(int, pfnRCBthTrap0eHandler,(PVM pVM, PVMCPU pVCpu, RTGCUINT uErr, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault));2678 DECLRCCALLBACKMEMBER(int, pfnRCBthInvalidatePage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtrPage));2679 DECLRCCALLBACKMEMBER(int, pfnRCBthSyncCR3,(PVM pVM, PVMCPU pVCpu, uint64_t cr0, uint64_t cr3, uint64_t cr4, bool fGlobal));2680 DECLRCCALLBACKMEMBER(int, pfnRCBthSyncPage,(PVM pVM, PVMCPU pVCpu, X86PDE PdeSrc, RTGCPTR GCPtrPage, unsigned cPages, unsigned uError));2681 DECLRCCALLBACKMEMBER(int, pfnRCBthPrefetchPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtrPage));2682 DECLRCCALLBACKMEMBER(int, pfnRCBthVerifyAccessSyncPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtrPage, unsigned fFlags, unsigned uError));2683 DECLRCCALLBACKMEMBER(unsigned, pfnRCBthAssertCR3,(PVM pVM, PVMCPU pVCpu, uint64_t cr3, uint64_t cr4, RTGCPTR GCPtr, RTGCPTR cb));2684 DECLRCCALLBACKMEMBER(int, pfnRCBthMapCR3,(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhysCR3));2685 DECLRCCALLBACKMEMBER(int, pfnRCBthUnmapCR3,(PVM pVM, PVMCPU pVCpu));2686 #if HC_ARCH_BITS == 642687 RTRCPTR alignment2; /**< structure size alignment. */2688 #endif2689 /** @} */2690 2691 /** @name Release Statistics2692 * @{ */2693 /** The number of times the guest has switched mode since last reset or statistics reset. */2694 STAMCOUNTER cGuestModeChanges;2695 /** @} */2696 2697 #ifdef VBOX_WITH_STATISTICS /** @todo move this chunk to the heap. */2698 /** @name Statistics2699 * @{ */2700 /** RC: Which statistic this \#PF should be attributed to. */2701 RCPTRTYPE(PSTAMPROFILE) pStatTrap0eAttributionRC;2702 RTRCPTR padding0;2703 /** R0: Which statistic this \#PF should be attributed to. */2704 R0PTRTYPE(PSTAMPROFILE) pStatTrap0eAttributionR0;2705 RTR0PTR padding1;2706 2707 /* Common */2708 STAMCOUNTER StatSyncPtPD[X86_PG_ENTRIES]; /**< SyncPT - PD distribution. */2709 STAMCOUNTER StatSyncPagePD[X86_PG_ENTRIES]; /**< SyncPage - PD distribution. */2710 2710 2711 2711 /* RZ only: */ … … 3219 3219 DECLINLINE(int) pgmR0DynMapHCPageInlined(PPGM pPGM, RTHCPHYS HCPhys, void **ppv) 3220 3220 { 3221 PVM pVM = PGM2VM(pPGM); 3222 PPGMMAPSET pSet = &pPGM->AutoSet; 3223 3224 STAM_PROFILE_START(&pPGM->StatR0DynMapHCPageInl, a); 3221 PVM pVM = PGM2VM(pPGM); 3222 PPGMCPU pPGMCPU = (PPGMCPU)((uint8_t *)VMMGetCpu(pVM) + pPGM->offVCpuPGM); /* very pretty ;-) */ 3223 PPGMMAPSET pSet = &pPGMCPU->AutoSet; 3224 3225 STAM_PROFILE_START(&pPGMCPU->StatR0DynMapHCPageInl, a); 3225 3226 Assert(!(HCPhys & PAGE_OFFSET_MASK)); 3226 3227 Assert(pSet->cEntries <= RT_ELEMENTS(pSet->aEntries)); … … 3232 3233 { 3233 3234 *ppv = pSet->aEntries[iEntry].pvPage; 3234 STAM_COUNTER_INC(&pPGM ->StatR0DynMapHCPageInlHits);3235 STAM_COUNTER_INC(&pPGMCPU->StatR0DynMapHCPageInlHits); 3235 3236 } 3236 3237 else 3237 3238 { 3238 STAM_COUNTER_INC(&pPGM ->StatR0DynMapHCPageInlMisses);3239 STAM_COUNTER_INC(&pPGMCPU->StatR0DynMapHCPageInlMisses); 3239 3240 pgmR0DynMapHCPageCommon(pVM, pSet, HCPhys, ppv); 3240 3241 } 3241 3242 3242 STAM_PROFILE_STOP(&pPGM ->StatR0DynMapHCPageInl, a);3243 STAM_PROFILE_STOP(&pPGMCPU->StatR0DynMapHCPageInl, a); 3243 3244 return VINF_SUCCESS; 3244 3245 } … … 3256 3257 DECLINLINE(int) pgmR0DynMapGCPageInlined(PPGM pPGM, RTGCPHYS GCPhys, void **ppv) 3257 3258 { 3258 PVM pVM= PGM2VM(pPGM);3259 PPGM MAPSET pSet = &pPGM->AutoSet;3260 3261 STAM_PROFILE_START(&pPGM ->StatR0DynMapGCPageInl, a);3259 PVM pVM = PGM2VM(pPGM); 3260 PPGMCPU pPGMCPU = (PPGMCPU)((uint8_t *)VMMGetCpu(pVM) + pPGM->offVCpuPGM); /* very pretty ;-) */ 3261 3262 STAM_PROFILE_START(&pPGMCPU->StatR0DynMapGCPageInl, a); 3262 3263 Assert(!(GCPhys & PAGE_OFFSET_MASK)); 3263 3264 … … 3271 3272 { 3272 3273 /* This case is not counted into StatR0DynMapGCPageInl. */ 3273 STAM_COUNTER_INC(&pPGM ->StatR0DynMapGCPageInlRamMisses);3274 STAM_COUNTER_INC(&pPGMCPU->StatR0DynMapGCPageInlRamMisses); 3274 3275 return PGMDynMapGCPage(pVM, GCPhys, ppv); 3275 3276 } 3276 3277 3277 3278 RTHCPHYS HCPhys = PGM_PAGE_GET_HCPHYS(&pRam->aPages[off >> PAGE_SHIFT]); 3278 STAM_COUNTER_INC(&pPGM ->StatR0DynMapGCPageInlRamHits);3279 STAM_COUNTER_INC(&pPGMCPU->StatR0DynMapGCPageInlRamHits); 3279 3280 3280 3281 /* 3281 3282 * pgmR0DynMapHCPageInlined with out stats. 3282 3283 */ 3284 PPGMMAPSET pSet = &pPGMCPU->AutoSet; 3283 3285 Assert(!(HCPhys & PAGE_OFFSET_MASK)); 3284 3286 Assert(pSet->cEntries <= RT_ELEMENTS(pSet->aEntries)); … … 3290 3292 { 3291 3293 *ppv = pSet->aEntries[iEntry].pvPage; 3292 STAM_COUNTER_INC(&pPGM ->StatR0DynMapGCPageInlHits);3294 STAM_COUNTER_INC(&pPGMCPU->StatR0DynMapGCPageInlHits); 3293 3295 } 3294 3296 else 3295 3297 { 3296 STAM_COUNTER_INC(&pPGM ->StatR0DynMapGCPageInlMisses);3298 STAM_COUNTER_INC(&pPGMCPU->StatR0DynMapGCPageInlMisses); 3297 3299 pgmR0DynMapHCPageCommon(pVM, pSet, HCPhys, ppv); 3298 3300 } 3299 3301 3300 STAM_PROFILE_STOP(&pPGM ->StatR0DynMapGCPageInl, a);3302 STAM_PROFILE_STOP(&pPGMCPU->StatR0DynMapGCPageInl, a); 3301 3303 return VINF_SUCCESS; 3302 3304 } -
trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp
r18982 r18984 978 978 { 979 979 #ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0 980 uint32_t iPrevSubset = PGMDynMapPushAutoSubset(pV M);980 uint32_t iPrevSubset = PGMDynMapPushAutoSubset(pVCpu); 981 981 pgmPoolMonitorChainChanging(pVCpu, pPool, pPage, GCPhysFault, (RTGCPTR)pu32, NULL); 982 PGMDynMapPopAutoSubset(pV M, iPrevSubset);982 PGMDynMapPopAutoSubset(pVCpu, iPrevSubset); 983 983 #else 984 984 pgmPoolMonitorChainChanging(pVCpu, pPool, pPage, GCPhysFault, (RTGCPTR)pu32, NULL); … … 1034 1034 */ 1035 1035 #ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0 1036 uint32_t iPrevSubset = PGMDynMapPushAutoSubset(pV M);1036 uint32_t iPrevSubset = PGMDynMapPushAutoSubset(pVCpu); 1037 1037 pgmPoolMonitorChainChanging(pVCpu, pPool, pPage, GCPhysFault, pvFault, pCpu); 1038 PGMDynMapPopAutoSubset(pV M, iPrevSubset);1038 PGMDynMapPopAutoSubset(pVCpu, iPrevSubset); 1039 1039 #else 1040 1040 pgmPoolMonitorChainChanging(pVCpu, pPool, pPage, GCPhysFault, pvFault, pCpu); … … 2668 2668 pgmPoolTrackFlushGCPhysPTs will/may kill the pool otherwise. */ 2669 2669 PVMCPU pVCpu = VMMGetCpu(pVM); 2670 uint32_t iPrevSubset = PGMDynMapPushAutoSubset(pV M);2670 uint32_t iPrevSubset = PGMDynMapPushAutoSubset(pVCpu); 2671 2671 # endif 2672 2672 … … 2683 2683 2684 2684 # ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0 2685 PGMDynMapPopAutoSubset(pV M, iPrevSubset);2685 PGMDynMapPopAutoSubset(pVCpu, iPrevSubset); 2686 2686 # endif 2687 2687 } … … 2696 2696 /* Start a subset here because pgmPoolTrackFlushGCPhysPTsSlow kill the pool otherwise. */ 2697 2697 PVMCPU pVCpu = VMMGetCpu(pVM); 2698 uint32_t iPrevSubset = PGMDynMapPushAutoSubset(pV M);2698 uint32_t iPrevSubset = PGMDynMapPushAutoSubset(pVCpu); 2699 2699 # endif 2700 2700 rc = pgmPoolTrackFlushGCPhysPTsSlow(pVM, pPhysPage); … … 2704 2704 2705 2705 # ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0 2706 PGMDynMapPopAutoSubset(pV M, iPrevSubset);2706 PGMDynMapPopAutoSubset(pVCpu, iPrevSubset); 2707 2707 # endif 2708 2708 … … 4001 4001 int pgmPoolFlushPage(PPGMPOOL pPool, PPGMPOOLPAGE pPage) 4002 4002 { 4003 int rc = VINF_SUCCESS; 4004 PVM pVM = pPool->CTX_SUFF(pVM); 4005 4003 int rc = VINF_SUCCESS; 4006 4004 STAM_PROFILE_START(&pPool->StatFlushPage, f); 4007 4005 LogFlow(("pgmPoolFlushPage: pPage=%p:{.Key=%RHp, .idx=%d, .enmKind=%s, .GCPhys=%RGp}\n", … … 4021 4019 * Quietly reject any attempts at flushing the currently active shadow CR3 mapping 4022 4020 */ 4023 if (pgmPoolIsPageLocked(&p VM->pgm.s, pPage))4021 if (pgmPoolIsPageLocked(&pPool->CTX_SUFF(pVM)->pgm.s, pPage)) 4024 4022 { 4025 4023 AssertMsg( pPage->enmKind == PGMPOOLKIND_64BIT_PML4 … … 4032 4030 || pPage->enmKind == PGMPOOLKIND_PAE_PD2_FOR_32BIT_PD 4033 4031 || pPage->enmKind == PGMPOOLKIND_PAE_PD3_FOR_32BIT_PD, 4034 ("Can't free the shadow CR3! (%RHp vs %RHp kind=%d\n", PGMGetHyperCR3(VMMGetCpu(p VM)), pPage->Core.Key, pPage->enmKind));4032 ("Can't free the shadow CR3! (%RHp vs %RHp kind=%d\n", PGMGetHyperCR3(VMMGetCpu(pPool->CTX_SUFF(pVM))), pPage->Core.Key, pPage->enmKind)); 4035 4033 Log(("pgmPoolFlushPage: current active shadow CR3, rejected. enmKind=%s idx=%d\n", pgmPoolPoolKindToStr(pPage->enmKind), pPage->idx)); 4036 4034 return VINF_SUCCESS; … … 4039 4037 #ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0 4040 4038 /* Start a subset so we won't run out of mapping space. */ 4041 uint32_t iPrevSubset = PGMDynMapPushAutoSubset(pVM); 4039 PVMCPU pVCpu = VMMGetCpu(pPool->CTX_SUFF(pVM)); 4040 uint32_t iPrevSubset = PGMDynMapPushAutoSubset(pVCpu); 4042 4041 #endif 4043 4042 … … 4066 4065 #ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0 4067 4066 /* Heavy stuff done. */ 4068 PGMDynMapPopAutoSubset(pV M, iPrevSubset);4067 PGMDynMapPopAutoSubset(pVCpu, iPrevSubset); 4069 4068 #endif 4070 4069 -
trunk/src/VBox/VMM/VMMR0/HWACCMR0.cpp
r18977 r18984 986 986 987 987 #ifdef VBOX_WITH_2X_4GB_ADDR_SPACE 988 PGMDynMapMigrateAutoSet(pV M);988 PGMDynMapMigrateAutoSet(pVCpu); 989 989 #endif 990 990 } … … 1064 1064 1065 1065 #ifdef VBOX_WITH_2X_4GB_ADDR_SPACE 1066 PGMDynMapStartAutoSet(pV M);1066 PGMDynMapStartAutoSet(pVCpu); 1067 1067 #endif 1068 1068 … … 1072 1072 1073 1073 #ifdef VBOX_WITH_2X_4GB_ADDR_SPACE 1074 PGMDynMapReleaseAutoSet(pV M);1074 PGMDynMapReleaseAutoSet(pVCpu); 1075 1075 #endif 1076 1076 return rc; -
trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp
r18976 r18984 2136 2136 #endif 2137 2137 #ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0 2138 PGMDynMapFlushAutoSet(pV M);2138 PGMDynMapFlushAutoSet(pVCpu); 2139 2139 #endif 2140 2140 -
trunk/src/VBox/VMM/VMMR0/PGMR0DynMap.cpp
r18983 r18984 355 355 * Initialize the auto sets. 356 356 */ 357 PPGMMAPSET pSet = &pVM->pgm.s.AutoSet; 358 uint32_t j = RT_ELEMENTS(pSet->aEntries); 359 while (j-- > 0) 360 { 361 pSet->aEntries[j].iPage = UINT16_MAX; 362 pSet->aEntries[j].cRefs = 0; 363 pSet->aEntries[j].pvPage = NULL; 364 pSet->aEntries[j].HCPhys = NIL_RTHCPHYS; 365 } 366 pSet->cEntries = PGMMAPSET_CLOSED; 367 pSet->iSubset = UINT32_MAX; 368 pSet->iCpu = -1; 369 memset(&pSet->aiHashTable[0], 0xff, sizeof(pSet->aiHashTable)); 357 VMCPUID idCpu = pVM->cCPUs; 358 AssertReturn(idCpu > 0 && idCpu <= VMCPU_MAX_CPU_COUNT, VERR_INTERNAL_ERROR); 359 while (idCpu-- > 0) 360 { 361 PPGMMAPSET pSet = &pVM->aCpus[idCpu].pgm.s.AutoSet; 362 uint32_t j = RT_ELEMENTS(pSet->aEntries); 363 while (j-- > 0) 364 { 365 pSet->aEntries[j].iPage = UINT16_MAX; 366 pSet->aEntries[j].cRefs = 0; 367 pSet->aEntries[j].pvPage = NULL; 368 pSet->aEntries[j].HCPhys = NIL_RTHCPHYS; 369 } 370 pSet->cEntries = PGMMAPSET_CLOSED; 371 pSet->iSubset = UINT32_MAX; 372 pSet->iCpu = -1; 373 memset(&pSet->aiHashTable[0], 0xff, sizeof(pSet->aiHashTable)); 374 } 370 375 371 376 /* … … 438 443 * Clean up and check the auto sets. 439 444 */ 440 PPGMMAPSET pSet = &pVM->pgm.s.AutoSet; 441 uint32_t j = pSet->cEntries; 442 if (j <= RT_ELEMENTS(pSet->aEntries)) 443 { 444 /* 445 * The set is open, close it. 446 */ 445 VMCPUID idCpu = pVM->cCPUs; 446 while (idCpu-- > 0) 447 { 448 PPGMMAPSET pSet = &pVM->aCpus[idCpu].pgm.s.AutoSet; 449 uint32_t j = pSet->cEntries; 450 if (j <= RT_ELEMENTS(pSet->aEntries)) 451 { 452 /* 453 * The set is open, close it. 454 */ 455 while (j-- > 0) 456 { 457 int32_t cRefs = pSet->aEntries[j].cRefs; 458 uint32_t iPage = pSet->aEntries[j].iPage; 459 LogRel(("PGMR0DynMapTermVM: %d dangling refs to %#x\n", cRefs, iPage)); 460 if (iPage < pThis->cPages && cRefs > 0) 461 pgmR0DynMapReleasePage(pThis, iPage, cRefs); 462 else 463 AssertLogRelMsgFailed(("cRefs=%d iPage=%#x cPages=%u\n", cRefs, iPage, pThis->cPages)); 464 465 pSet->aEntries[j].iPage = UINT16_MAX; 466 pSet->aEntries[j].cRefs = 0; 467 pSet->aEntries[j].pvPage = NULL; 468 pSet->aEntries[j].HCPhys = NIL_RTHCPHYS; 469 } 470 pSet->cEntries = PGMMAPSET_CLOSED; 471 pSet->iSubset = UINT32_MAX; 472 pSet->iCpu = -1; 473 } 474 else 475 AssertMsg(j == PGMMAPSET_CLOSED, ("cEntries=%#x\n", j)); 476 477 j = RT_ELEMENTS(pSet->aEntries); 447 478 while (j-- > 0) 448 479 { 449 int32_t cRefs = pSet->aEntries[j].cRefs; 450 uint32_t iPage = pSet->aEntries[j].iPage; 451 LogRel(("PGMR0DynMapTermVM: %d dangling refs to %#x\n", cRefs, iPage)); 452 if (iPage < pThis->cPages && cRefs > 0) 453 pgmR0DynMapReleasePage(pThis, iPage, cRefs); 454 else 455 AssertLogRelMsgFailed(("cRefs=%d iPage=%#x cPages=%u\n", cRefs, iPage, pThis->cPages)); 456 457 pSet->aEntries[j].iPage = UINT16_MAX; 458 pSet->aEntries[j].cRefs = 0; 459 pSet->aEntries[j].pvPage = NULL; 460 pSet->aEntries[j].HCPhys = NIL_RTHCPHYS; 461 } 462 pSet->cEntries = PGMMAPSET_CLOSED; 463 pSet->iSubset = UINT32_MAX; 464 pSet->iCpu = -1; 465 } 466 else 467 AssertMsg(j == PGMMAPSET_CLOSED, ("cEntries=%#x\n", j)); 468 469 j = RT_ELEMENTS(pSet->aEntries); 470 while (j-- > 0) 471 { 472 Assert(pSet->aEntries[j].iPage == UINT16_MAX); 473 Assert(!pSet->aEntries[j].cRefs); 480 Assert(pSet->aEntries[j].iPage == UINT16_MAX); 481 Assert(!pSet->aEntries[j].cRefs); 482 } 474 483 } 475 484 … … 1176 1185 static uint32_t pgmR0DynMapPageSlow(PPGMR0DYNMAP pThis, RTHCPHYS HCPhys, uint32_t iPage, PVM pVM) 1177 1186 { 1178 STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapPageSlow); 1187 #ifdef VBOX_WITH_STATISTICS 1188 PVMCPU pVCpu = VMMGetCpu(pVM); 1189 #endif 1190 STAM_COUNTER_INC(&pVCpu->pgm.s.StatR0DynMapPageSlow); 1179 1191 1180 1192 /* … … 1204 1216 if (paPages[iFreePage].HCPhys == HCPhys) 1205 1217 { 1206 STAM_COUNTER_INC(&pV M->pgm.s.StatR0DynMapPageSlowLoopHits);1218 STAM_COUNTER_INC(&pVCpu->pgm.s.StatR0DynMapPageSlowLoopHits); 1207 1219 return iFreePage; 1208 1220 } … … 1215 1227 return UINT32_MAX; 1216 1228 } 1217 STAM_COUNTER_INC(&pV M->pgm.s.StatR0DynMapPageSlowLoopMisses);1229 STAM_COUNTER_INC(&pVCpu->pgm.s.StatR0DynMapPageSlowLoopMisses); 1218 1230 #ifdef VBOX_WITH_STATISTICS 1219 1231 fLooped = true; … … 1227 1239 for (uint32_t iPage2 = (iPage + 3) % cPages; iPage2 != iPage; iPage2 = (iPage2 + 1) % cPages) 1228 1240 if (paPages[iPage2].HCPhys == HCPhys) 1229 STAM_COUNTER_INC(&pV M->pgm.s.StatR0DynMapPageSlowLostHits);1241 STAM_COUNTER_INC(&pVCpu->pgm.s.StatR0DynMapPageSlowLostHits); 1230 1242 #endif 1231 1243 … … 1275 1287 DECLINLINE(uint32_t) pgmR0DynMapPage(PPGMR0DYNMAP pThis, RTHCPHYS HCPhys, int32_t iRealCpu, PVM pVM, void **ppvPage) 1276 1288 { 1289 #ifdef VBOX_WITH_STATISTICS 1290 PVMCPU pVCpu = VMMGetCpu(pVM); 1291 #endif 1277 1292 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; 1278 1293 RTSpinlockAcquire(pThis->hSpinlock, &Tmp); 1279 1294 AssertMsg(!(HCPhys & PAGE_OFFSET_MASK), ("HCPhys=%RHp\n", HCPhys)); 1280 STAM_COUNTER_INC(&pV M->pgm.s.StatR0DynMapPage);1295 STAM_COUNTER_INC(&pVCpu->pgm.s.StatR0DynMapPage); 1281 1296 1282 1297 /* … … 1292 1307 PPGMR0DYNMAPENTRY paPages = pThis->paPages; 1293 1308 if (RT_LIKELY(paPages[iPage].HCPhys == HCPhys)) 1294 STAM_COUNTER_INC(&pV M->pgm.s.StatR0DynMapPageHits0);1309 STAM_COUNTER_INC(&pVCpu->pgm.s.StatR0DynMapPageHits0); 1295 1310 else 1296 1311 { … … 1299 1314 { 1300 1315 iPage = iPage2; 1301 STAM_COUNTER_INC(&pV M->pgm.s.StatR0DynMapPageHits1);1316 STAM_COUNTER_INC(&pVCpu->pgm.s.StatR0DynMapPageHits1); 1302 1317 } 1303 1318 else … … 1307 1322 { 1308 1323 iPage = iPage2; 1309 STAM_COUNTER_INC(&pV M->pgm.s.StatR0DynMapPageHits2);1324 STAM_COUNTER_INC(&pVCpu->pgm.s.StatR0DynMapPageHits2); 1310 1325 } 1311 1326 else … … 1356 1371 if (RT_UNLIKELY(fInvalidateIt)) 1357 1372 { 1358 STAM_COUNTER_INC(&pV M->pgm.s.StatR0DynMapPageInvlPg);1373 STAM_COUNTER_INC(&pVCpu->pgm.s.StatR0DynMapPageInvlPg); 1359 1374 ASMInvalidatePage(pvPage); 1360 1375 } … … 1490 1505 * API is called. 1491 1506 * 1492 * @param pV M Pointer to the shared VM structure.1493 */ 1494 VMMDECL(void) PGMDynMapStartAutoSet(PVM pVM)1495 { 1496 Assert(pV M->pgm.s.AutoSet.cEntries == PGMMAPSET_CLOSED);1497 Assert(pV M->pgm.s.AutoSet.iSubset == UINT32_MAX);1498 pV M->pgm.s.AutoSet.cEntries = 0;1499 pV M->pgm.s.AutoSet.iCpu = RTMpCpuIdToSetIndex(RTMpCpuId());1507 * @param pVCpu The shared data for the current virtual CPU. 1508 */ 1509 VMMDECL(void) PGMDynMapStartAutoSet(PVMCPU pVCpu) 1510 { 1511 Assert(pVCpu->pgm.s.AutoSet.cEntries == PGMMAPSET_CLOSED); 1512 Assert(pVCpu->pgm.s.AutoSet.iSubset == UINT32_MAX); 1513 pVCpu->pgm.s.AutoSet.cEntries = 0; 1514 pVCpu->pgm.s.AutoSet.iCpu = RTMpCpuIdToSetIndex(RTMpCpuId()); 1500 1515 } 1501 1516 … … 1542 1557 * since the PGMDynMapStartAutoSet call. 1543 1558 * 1544 * @param pV M Pointer to the shared VM structure.1545 */ 1546 VMMDECL(void) PGMDynMapReleaseAutoSet(PVM pVM)1547 { 1548 PPGMMAPSET pSet = &pV M->pgm.s.AutoSet;1559 * @param pVCpu The shared data for the current virtual CPU. 1560 */ 1561 VMMDECL(void) PGMDynMapReleaseAutoSet(PVMCPU pVCpu) 1562 { 1563 PPGMMAPSET pSet = &pVCpu->pgm.s.AutoSet; 1549 1564 1550 1565 /* … … 1557 1572 pSet->iCpu = -1; 1558 1573 1559 STAM_COUNTER_INC(&pV M->pgm.s.aStatR0DynMapSetSize[(cEntries * 10 / RT_ELEMENTS(pSet->aEntries)) % 11]);1574 STAM_COUNTER_INC(&pVCpu->pgm.s.aStatR0DynMapSetSize[(cEntries * 10 / RT_ELEMENTS(pSet->aEntries)) % 11]); 1560 1575 AssertMsg(cEntries < PGMMAPSET_MAX_FILL, ("%u\n", cEntries)); 1561 1576 if (cEntries > RT_ELEMENTS(pSet->aEntries) * 50 / 100) … … 1569 1584 * Flushes the set if it's above a certain threshold. 1570 1585 * 1571 * @param pV M Pointer to the shared VM structure.1572 */ 1573 VMMDECL(void) PGMDynMapFlushAutoSet(PVM pVM)1574 { 1575 PPGMMAPSET pSet = &pV M->pgm.s.AutoSet;1586 * @param pVCpu The shared data for the current virtual CPU. 1587 */ 1588 VMMDECL(void) PGMDynMapFlushAutoSet(PVMCPU pVCpu) 1589 { 1590 PPGMMAPSET pSet = &pVCpu->pgm.s.AutoSet; 1576 1591 AssertMsg(pSet->iCpu == RTMpCpuIdToSetIndex(RTMpCpuId()), ("%d %d(%d) efl=%#x\n", pSet->iCpu, RTMpCpuIdToSetIndex(RTMpCpuId()), RTMpCpuId(), ASMGetFlags())); 1577 1592 … … 1581 1596 uint32_t cEntries = pSet->cEntries; 1582 1597 AssertReturnVoid(cEntries != PGMMAPSET_CLOSED); 1583 STAM_COUNTER_INC(&pV M->pgm.s.aStatR0DynMapSetSize[(cEntries * 10 / RT_ELEMENTS(pSet->aEntries)) % 11]);1598 STAM_COUNTER_INC(&pVCpu->pgm.s.aStatR0DynMapSetSize[(cEntries * 10 / RT_ELEMENTS(pSet->aEntries)) % 11]); 1584 1599 if (cEntries >= RT_ELEMENTS(pSet->aEntries) * 45 / 100) 1585 1600 { … … 1605 1620 * the entries will have been flagged as invalidated. 1606 1621 * 1607 * @param pV M Pointer to the shared VM structure.1622 * @param pVCpu The shared data for the current virtual CPU. 1608 1623 * @thread EMT 1609 1624 */ 1610 VMMDECL(void) PGMDynMapMigrateAutoSet(PVM pVM)1611 { 1612 PPGMMAPSET pSet = &pV M->pgm.s.AutoSet;1625 VMMDECL(void) PGMDynMapMigrateAutoSet(PVMCPU pVCpu) 1626 { 1627 PPGMMAPSET pSet = &pVCpu->pgm.s.AutoSet; 1613 1628 int32_t iRealCpu = RTMpCpuIdToSetIndex(RTMpCpuId()); 1614 1629 if (pSet->iCpu != iRealCpu) … … 1635 1650 1636 1651 ASMInvalidatePage(pThis->paPages[iPage].pvPage); 1637 STAM_COUNTER_INC(&pV M->pgm.s.StatR0DynMapMigrateInvlPg);1652 STAM_COUNTER_INC(&pVCpu->pgm.s.StatR0DynMapMigrateInvlPg); 1638 1653 1639 1654 RTSpinlockAcquire(pThis->hSpinlock, &Tmp); … … 1703 1718 * @returns The index of the previous subset. Pass this to 1704 1719 * PGMDynMapPopAutoSubset when poping it. 1705 * @param pV M Pointer to the shared VM structure.1706 */ 1707 VMMDECL(uint32_t) PGMDynMapPushAutoSubset(PVM pVM)1708 { 1709 PPGMMAPSET pSet = &pV M->pgm.s.AutoSet;1720 * @param pVCpu Pointer to the virtual cpu data. 1721 */ 1722 VMMDECL(uint32_t) PGMDynMapPushAutoSubset(PVMCPU pVCpu) 1723 { 1724 PPGMMAPSET pSet = &pVCpu->pgm.s.AutoSet; 1710 1725 AssertReturn(pSet->cEntries != PGMMAPSET_CLOSED, UINT32_MAX); 1711 1726 uint32_t iPrevSubset = pSet->iSubset; 1712 1727 Assert(iPrevSubset == UINT32_MAX); 1713 1728 pSet->iSubset = pSet->cEntries; 1714 STAM_COUNTER_INC(&pV M->pgm.s.StatR0DynMapSubsets);1729 STAM_COUNTER_INC(&pVCpu->pgm.s.StatR0DynMapSubsets); 1715 1730 return iPrevSubset; 1716 1731 } … … 1720 1735 * Pops a subset created by a previous call to PGMDynMapPushAutoSubset. 1721 1736 * 1722 * @param pV M Pointer to the shared VM structure.1737 * @param pVCpu Pointer to the virtual cpu data. 1723 1738 * @param iPrevSubset What PGMDynMapPushAutoSubset returned. 1724 1739 */ 1725 VMMDECL(void) PGMDynMapPopAutoSubset(PVM pVM, uint32_t iPrevSubset)1726 { 1727 PPGMMAPSET pSet = &pV M->pgm.s.AutoSet;1740 VMMDECL(void) PGMDynMapPopAutoSubset(PVMCPU pVCpu, uint32_t iPrevSubset) 1741 { 1742 PPGMMAPSET pSet = &pVCpu->pgm.s.AutoSet; 1728 1743 uint32_t cEntries = pSet->cEntries; 1729 1744 AssertReturnVoid(cEntries != PGMMAPSET_CLOSED); 1730 1745 AssertReturnVoid(pSet->iSubset <= iPrevSubset || iPrevSubset == UINT32_MAX); 1731 1732 STAM_COUNTER_INC(&pV M->pgm.s.aStatR0DynMapSetSize[(cEntries * 10 / RT_ELEMENTS(pSet->aEntries)) % 11]);1746 Assert(iPrevSubset == UINT32_MAX); 1747 STAM_COUNTER_INC(&pVCpu->pgm.s.aStatR0DynMapSetSize[(cEntries * 10 / RT_ELEMENTS(pSet->aEntries)) % 11]); 1733 1748 if ( cEntries >= RT_ELEMENTS(pSet->aEntries) * 40 / 100 1734 1749 && cEntries != pSet->iSubset) … … 1801 1816 int pgmR0DynMapHCPageCommon(PVM pVM, PPGMMAPSET pSet, RTHCPHYS HCPhys, void **ppv) 1802 1817 { 1818 #ifdef VBOX_WITH_STATISTICS 1819 PVMCPU pVCpu = VMMGetCpu(pVM); 1820 #endif 1803 1821 AssertMsg(pSet->iCpu == RTMpCpuIdToSetIndex(RTMpCpuId()), ("%d %d(%d) efl=%#x\n", pSet->iCpu, RTMpCpuIdToSetIndex(RTMpCpuId()), RTMpCpuId(), ASMGetFlags())); 1804 1822 … … 1873 1891 { 1874 1892 pSet->aEntries[i].cRefs++; 1875 STAM_COUNTER_INC(&pV M->pgm.s.StatR0DynMapSetSearchHits);1893 STAM_COUNTER_INC(&pVCpu->pgm.s.StatR0DynMapSetSearchHits); 1876 1894 break; 1877 1895 } 1878 1896 if (i < 0) 1879 1897 { 1880 STAM_COUNTER_INC(&pV M->pgm.s.StatR0DynMapSetSearchMisses);1898 STAM_COUNTER_INC(&pVCpu->pgm.s.StatR0DynMapSetSearchMisses); 1881 1899 if (pSet->iSubset < pSet->cEntries) 1882 1900 { 1883 STAM_COUNTER_INC(&pV M->pgm.s.StatR0DynMapSetSearchFlushes);1884 STAM_COUNTER_INC(&pV M->pgm.s.aStatR0DynMapSetSize[(pSet->cEntries * 10 / RT_ELEMENTS(pSet->aEntries)) % 11]);1901 STAM_COUNTER_INC(&pVCpu->pgm.s.StatR0DynMapSetSearchFlushes); 1902 STAM_COUNTER_INC(&pVCpu->pgm.s.aStatR0DynMapSetSize[(pSet->cEntries * 10 / RT_ELEMENTS(pSet->aEntries)) % 11]); 1885 1903 AssertMsg(pSet->cEntries < PGMMAPSET_MAX_FILL, ("%u\n", pSet->cEntries)); 1886 1904 pgmDynMapFlushSubset(pSet); … … 1889 1907 if (RT_UNLIKELY(pSet->cEntries >= RT_ELEMENTS(pSet->aEntries))) 1890 1908 { 1891 STAM_COUNTER_INC(&pV M->pgm.s.StatR0DynMapSetOptimize);1909 STAM_COUNTER_INC(&pVCpu->pgm.s.StatR0DynMapSetOptimize); 1892 1910 pgmDynMapOptimizeAutoSet(pSet); 1893 1911 } … … 1925 1943 VMMDECL(int) PGMDynMapHCPage(PVM pVM, RTHCPHYS HCPhys, void **ppv) 1926 1944 { 1945 #ifdef VBOX_WITH_STATISTICS 1946 PVMCPU pVCpu = VMMGetCpu(pVM); 1947 #endif 1927 1948 /* 1928 1949 * Validate state. 1929 1950 */ 1930 STAM_PROFILE_START(&pV M->pgm.s.StatR0DynMapHCPage, a);1951 STAM_PROFILE_START(&pVCpu->pgm.s.StatR0DynMapHCPage, a); 1931 1952 AssertPtr(ppv); 1932 1953 AssertMsg(pVM->pgm.s.pvR0DynMapUsed == g_pPGMR0DynMap, 1933 1954 ("%p != %p\n", pVM->pgm.s.pvR0DynMapUsed, g_pPGMR0DynMap)); 1934 1955 AssertMsg(!(HCPhys & PAGE_OFFSET_MASK), ("HCPhys=%RHp\n", HCPhys)); 1935 PPGMMAPSET pSet = &pVM->pgm.s.AutoSet; 1956 PVMCPU pVCpu = VMMGetCpu(pVM); 1957 AssertPtr(pVCpu); 1958 PPGMMAPSET pSet = &pVCpu->pgm.s.AutoSet; 1936 1959 AssertMsg(pSet->cEntries <= RT_ELEMENTS(pSet->aEntries), 1937 1960 ("%#x (%u)\n", pSet->cEntries, pSet->cEntries)); … … 1942 1965 int rc = pgmR0DynMapHCPageCommon(pVM, pSet, HCPhys, ppv); 1943 1966 1944 STAM_PROFILE_STOP(&pV M->pgm.s.StatR0DynMapHCPage, a);1967 STAM_PROFILE_STOP(&pVCpu->pgm.s.StatR0DynMapHCPage, a); 1945 1968 return rc; 1946 1969 } … … 1983 2006 LogRel(("pgmR0DynMapTest: ****** START ******\n")); 1984 2007 PPGMR0DYNMAP pThis = g_pPGMR0DynMap; 1985 PPGMMAPSET pSet = &pVM-> pgm.s.AutoSet;2008 PPGMMAPSET pSet = &pVM->aCpus[0].pgm.s.AutoSet; 1986 2009 uint32_t i; 1987 2010 … … 2004 2027 LogRel(("Test #1\n")); 2005 2028 ASMIntDisable(); 2006 PGMDynMapStartAutoSet( pVM);2029 PGMDynMapStartAutoSet(&pVM->aCpus[0]); 2007 2030 2008 2031 uint64_t cr3 = ASMGetCR3() & ~(uint64_t)PAGE_OFFSET_MASK; … … 2025 2048 LogRel(("Test #2\n")); 2026 2049 ASMIntDisable(); 2027 PGMDynMapMigrateAutoSet( pVM);2050 PGMDynMapMigrateAutoSet(&pVM->aCpus[0]); 2028 2051 for (i = 0 ; i < UINT16_MAX*2 - 1 && RT_SUCCESS(rc) && pv2 == pv; i++) 2029 2052 { … … 2063 2086 LogRel(("Test #3\n")); 2064 2087 ASMIntDisable(); 2065 PGMDynMapMigrateAutoSet( pVM);2088 PGMDynMapMigrateAutoSet(&pVM->aCpus[0]); 2066 2089 pv2 = NULL; 2067 2090 for (i = 0 ; i < RT_ELEMENTS(pSet->aEntries) - 5 && RT_SUCCESS(rc) && pv2 != pv; i++) … … 2091 2114 LogRel(("Test #4\n")); 2092 2115 ASMIntDisable(); 2093 PGMDynMapMigrateAutoSet( pVM);2116 PGMDynMapMigrateAutoSet(&pVM->aCpus[0]); 2094 2117 for (i = 0 ; i < RT_ELEMENTS(pSet->aEntries) + 2; i++) 2095 2118 { … … 2106 2129 LogRel(("Test #5\n")); 2107 2130 ASMIntDisable(); 2108 PGMDynMapMigrateAutoSet( pVM);2109 PGMDynMapReleaseAutoSet( pVM);2110 PGMDynMapStartAutoSet( pVM);2131 PGMDynMapMigrateAutoSet(&pVM->aCpus[0]); 2132 PGMDynMapReleaseAutoSet(&pVM->aCpus[0]); 2133 PGMDynMapStartAutoSet(&pVM->aCpus[0]); 2111 2134 ASMIntEnable(); 2112 2135 … … 2136 2159 LogRel(("Test #5\n")); 2137 2160 ASMIntDisable(); 2138 PGMDynMapMigrateAutoSet( pVM);2161 PGMDynMapMigrateAutoSet(&pVM->aCpus[0]); 2139 2162 RTHCPHYS HCPhysPT = RTR0MemObjGetPagePhysAddr(pThis->pSegHead->ahMemObjPTs[0], 0); 2140 2163 rc = PGMDynMapHCPage(pVM, HCPhysPT, &pv); … … 2173 2196 LogRel(("Cleanup.\n")); 2174 2197 ASMIntDisable(); 2175 PGMDynMapMigrateAutoSet( pVM);2176 PGMDynMapFlushAutoSet( pVM);2177 PGMDynMapReleaseAutoSet( pVM);2198 PGMDynMapMigrateAutoSet(&pVM->aCpus[0]); 2199 PGMDynMapFlushAutoSet(&pVM->aCpus[0]); 2200 PGMDynMapReleaseAutoSet(&pVM->aCpus[0]); 2178 2201 ASMIntEnable(); 2179 2202 -
trunk/src/VBox/VMM/testcase/tstVMStructGC.cpp
r18974 r18984 411 411 GEN_CHECK_OFF(PGMCPU, offVCpu); 412 412 GEN_CHECK_OFF(PGMCPU, offPGM); 413 #ifdef VBOX_WITH_2X_4GB_ADDR_SPACE _IN_R0414 GEN_CHECK_OFF(PGM , AutoSet);413 #ifdef VBOX_WITH_2X_4GB_ADDR_SPACE 414 GEN_CHECK_OFF(PGMCPU, AutoSet); 415 415 #endif 416 416 GEN_CHECK_OFF(PGMCPU, GCPhysA20Mask);
Note:
See TracChangeset
for help on using the changeset viewer.