- Timestamp:
- Aug 24, 2010 5:17:48 PM (14 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/FTM.cpp
r31895 r31938 546 546 547 547 case FTMSYNCSTATE_DELTA_MEMORY: 548 /* Nothing to do as we sync the memory in an async thread; no need to block EMT. */ 548 549 break; 549 550 } … … 557 558 AssertRC(rc); 558 559 } 560 } 561 562 /** 563 * PGMR3PhysEnumDirtyFTPages callback for syncing dirty physical pages 564 * 565 * @param pVM VM Handle. 566 * @param GCPhys GC physical address 567 * @param pRange HC virtual address of the page(s) 568 * @param cbRange Size of the dirty range in bytes. 569 * @param pvUser User argument 570 */ 571 static DECLCALLBACK(int) ftmR3SyncDirtyPage(PVM pVM, RTGCPHYS GCPhys, uint8_t *pRange, unsigned cbRange, void *pvUser) 572 { 573 return VINF_SUCCESS; 559 574 } 560 575 … … 626 641 for (;;) 627 642 { 643 rc = RTSemEventWait(pVM->ftm.s.master.hShutdownEvent, pVM->ftm.s.uInterval); 644 if (rc != VERR_TIMEOUT) 645 break; /* told to quit */ 646 628 647 if (!pVM->ftm.s.fCheckpointingActive) 629 648 { … … 632 651 633 652 /* sync the changed memory with the standby node. */ 653 rc = VMR3ReqCallWait(pVM, VMCPUID_ANY, (PFNRT)ftmR3PerformSync, 2, pVM, FTMSYNCSTATE_DELTA_MEMORY); 654 AssertRC(rc); 655 656 rc = PGMR3PhysEnumDirtyFTPages(pVM, ftmR3SyncDirtyPage, NULL /* pvUser */); 657 AssertRC(rc); 634 658 635 659 PDMCritSectLeave(&pVM->ftm.s.CritSect); 636 660 } 637 rc = RTSemEventWait(pVM->ftm.s.master.hShutdownEvent, pVM->ftm.s.uInterval);638 if (rc != VERR_TIMEOUT)639 break; /* told to quit */640 661 } 641 662 return rc; … … 846 867 pVM->ftm.s.syncstate.fEndOfStream = false; 847 868 848 /** @todo sync state + changed memory. */ 869 /* Sync state + changed memory. */ 870 rc = VMR3ReqCallWait(pVM, VMCPUID_ANY, (PFNRT)ftmR3PerformSync, 2, pVM, FTMSYNCSTATE_DELTA_VM); 871 AssertRC(rc); 849 872 850 873 PDMCritSectLeave(&pVM->ftm.s.CritSect); -
trunk/src/VBox/VMM/PGMInternal.h
r31895 r31938 724 724 * - [8-9]: u2HandlerVirtStateY - the virtual handler state 725 725 * (PGM_PAGE_HNDL_VIRT_STATE_*). 726 * - [10]: u1FTDirty - indicator of dirty page for fault tolerance tracking 726 727 * - [13-14]: u2PDEType - paging structure needed to map the page (PGM_PAGE_PDE_TYPE_*) 727 728 * - [15]: fWrittenToY - flag indicating that a write monitored page was 728 729 * written to when set. 729 * - [1 0-13]: 4unused bits.730 * - [11-13]: 3 unused bits. 730 731 * @remarks Warning! All accesses to the bits are hardcoded. 731 732 * … … 969 970 */ 970 971 #define PGM_PAGE_IS_WRITTEN_TO(pPage) ( !!((pPage)->u16MiscY.au8[1] & UINT8_C(0x80)) ) 972 973 /** 974 * Marks the page as dirty for FTM 975 * @param pPage Pointer to the physical guest page tracking structure. 976 */ 977 #define PGM_PAGE_SET_FT_DIRTY(pPage) do { (pPage)->u16MiscY.au8[1] |= UINT8_C(0x04); } while (0) 978 979 /** 980 * Clears the FTM dirty indicator 981 * @param pPage Pointer to the physical guest page tracking structure. 982 */ 983 #define PGM_PAGE_CLEAR_FT_DIRTY(pPage) do { (pPage)->u16MiscY.au8[1] &= UINT8_C(0xfb); } while (0) 984 985 /** 986 * Checks if the page was marked as dirty for FTM 987 * @returns true/false. 988 * @param pPage Pointer to the physical guest page tracking structure. 989 */ 990 #define PGM_PAGE_IS_FT_DIRTY(pPage) ( !!((pPage)->u16MiscY.au8[1] & UINT8_C(0x04)) ) 991 971 992 972 993 /** @name PT usage values (PGMPAGE::u2PDEType). -
trunk/src/VBox/VMM/PGMPhys.cpp
r31895 r31938 980 980 /** @todo pointless to write protect the physical page pointed to by RSP. */ 981 981 982 /*983 * Clear all the GCPhys links and rebuild the phys ext free list.984 */985 982 for (PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRanges); 986 983 pRam; … … 1004 1001 * monitoring if the page is known to be very busy. */ 1005 1002 if (PGM_PAGE_IS_WRITTEN_TO(pPage)) 1003 { 1006 1004 PGM_PAGE_CLEAR_WRITTEN_TO(pPage); 1005 /* Remember this dirty page for the next (memory) sync. */ 1006 PGM_PAGE_SET_FT_DIRTY(pPage); 1007 } 1007 1008 1008 1009 PGM_PAGE_SET_STATE(pPage, PGM_PAGE_STATE_WRITE_MONITORED); … … 1042 1043 int rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ONCE, pgmR3PhysWriteProtectRAMRendezvous, NULL); 1043 1044 AssertRC(rc); 1045 return rc; 1046 } 1047 1048 /** 1049 * Enumerate all dirty FT pages 1050 * 1051 * @returns VBox status code. 1052 * @param pVM The VM handle. 1053 * @param pfnEnum Enumerate callback handler 1054 * @param pvUser Enumerate callback handler parameter 1055 */ 1056 VMMR3DECL(int) PGMR3PhysEnumDirtyFTPages(PVM pVM, PFNPGMENUMDIRTYFTPAGES pfnEnum, void *pvUser) 1057 { 1058 int rc = VINF_SUCCESS; 1059 1060 pgmLock(pVM); 1061 for (PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRanges); 1062 pRam; 1063 pRam = pRam->CTX_SUFF(pNext)) 1064 { 1065 if (!PGM_RAM_RANGE_IS_AD_HOC(pRam)) 1066 { 1067 unsigned iPage = pRam->cb >> PAGE_SHIFT; 1068 while (iPage-- > 0) 1069 { 1070 PPGMPAGE pPage = &pRam->aPages[iPage]; 1071 if (RT_LIKELY(PGM_PAGE_GET_TYPE(pPage) == PGMPAGETYPE_RAM)) 1072 { 1073 /* 1074 * A RAM page. 1075 */ 1076 switch (PGM_PAGE_GET_STATE(pPage)) 1077 { 1078 case PGM_PAGE_STATE_ALLOCATED: 1079 if ( !PGM_PAGE_IS_WRITTEN_TO(pPage) 1080 && PGM_PAGE_IS_FT_DIRTY(pPage)) 1081 { 1082 /** @todo this is risky; the range might be changed, but little choice as the sync costs a lot of time */ 1083 pgmUnlock(pVM); 1084 pfnEnum(pVM, pRam->GCPhys + iPage * PAGE_SIZE, 0, 0, pvUser); 1085 pgmLock(pVM); 1086 PGM_PAGE_CLEAR_FT_DIRTY(pPage); 1087 } 1088 break; 1089 } 1090 } 1091 } 1092 } 1093 } 1094 pgmUnlock(pVM); 1044 1095 return rc; 1045 1096 }
Note:
See TracChangeset
for help on using the changeset viewer.