Changeset 23539 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Oct 4, 2009 8:42:05 PM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 53182
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/PGMInternal.h
r23535 r23539 1042 1042 1043 1043 /** Max number of locks on a page. */ 1044 #define PGM_PAGE_MAX_LOCKS 2541044 #define PGM_PAGE_MAX_LOCKS UINT8_C(254) 1045 1045 1046 1046 /** Get the read lock count. … … 1077 1077 1078 1078 1079 #if 0 1080 /** Enables sanity checking of write monitoring using CRC-32. */ 1081 #define PGMLIVESAVERAMPAGE_WITH_CRC32 1082 #endif 1079 1083 1080 1084 /** 1081 1085 * Per page live save tracking data. 1082 1086 */ 1083 typedef struct PGMLIVESAVEPAGE 1084 { 1085 /** The pass number where this page was last saved. */ 1086 uint32_t uPassSaved; 1087 typedef struct PGMLIVESAVERAMPAGE 1088 { 1087 1089 /** Number of times it has been dirtied. */ 1088 1090 uint32_t cDirtied : 24; … … 1104 1106 /** Bits reserved for future use. */ 1105 1107 uint32_t u2Reserved : 2; 1106 } PGMLIVESAVEPAGE; 1107 AssertCompileSize(PGMLIVESAVEPAGE, 8); 1108 #ifdef PGMLIVESAVERAMPAGE_WITH_CRC32 1109 /** CRC-32 for the page. This is for internal consistency checks. */ 1110 uint32_t u32Crc; 1111 #endif 1112 } PGMLIVESAVERAMPAGE; 1113 #ifdef PGMLIVESAVERAMPAGE_WITH_CRC32 1114 AssertCompileSize(PGMLIVESAVERAMPAGE, 8); 1115 #else 1116 AssertCompileSize(PGMLIVESAVERAMPAGE, 4); 1117 #endif 1108 1118 /** Pointer to the per page live save tracking data. */ 1109 typedef PGMLIVESAVE PAGE *PPGMLIVESAVEPAGE;1110 1111 /** The max value of PGMLIVESAVE PAGE::cDirtied. */1119 typedef PGMLIVESAVERAMPAGE *PPGMLIVESAVERAMPAGE; 1120 1121 /** The max value of PGMLIVESAVERAMPAGE::cDirtied. */ 1112 1122 #define PGMLIVSAVEPAGE_MAX_DIRTIED 0x00fffff0 1113 1123 … … 1140 1150 R3PTRTYPE(void *) pvR3; 1141 1151 /** Live save per page tracking data. */ 1142 R3PTRTYPE(PPGMLIVESAVE PAGE) paLSPages;1152 R3PTRTYPE(PPGMLIVESAVERAMPAGE) paLSPages; 1143 1153 /** The range description. */ 1144 1154 R3PTRTYPE(const char *) pszDesc; … … 1259 1269 * Live save per page data for an MMIO2 page. 1260 1270 * 1261 * Not using PGMLIVESAVE PAGE here because we cannot use normal write monitoring1271 * Not using PGMLIVESAVERAMPAGE here because we cannot use normal write monitoring 1262 1272 * of MMIO2 pages. The current approach is using some optimisitic SHA-1 + 1263 1273 * CRC-32 for detecting changes as well as special handling of zero pages. This -
trunk/src/VBox/VMM/PGMSavedState.cpp
r23536 r23539 92 92 /** @} */ 93 93 94 /** The CRC-32 for a zero page. */ 95 #define PGM_STATE_CRC32_ZERO_PAGE UINT32_C(0xc71c0011) 94 96 /** The CRC-32 for a zero half page. */ 95 97 #define PGM_STATE_CRC32_ZERO_HALF_PAGE UINT32_C(0xf1e8ba9e) … … 1005 1007 uint32_t const cPages = pCur->cb >> PAGE_SHIFT; 1006 1008 pgmUnlock(pVM); 1007 PPGMLIVESAVE PAGE paLSPages = (PPGMLIVESAVEPAGE)MMR3HeapAllocZ(pVM, MM_TAG_PGM, cPages * sizeof(PGMLIVESAVEPAGE));1009 PPGMLIVESAVERAMPAGE paLSPages = (PPGMLIVESAVERAMPAGE)MMR3HeapAllocZ(pVM, MM_TAG_PGM, cPages * sizeof(PGMLIVESAVERAMPAGE)); 1008 1010 if (!paLSPages) 1009 1011 return VERR_NO_MEMORY; … … 1026 1028 /** @todo yield critsect! (after moving this away from EMT0) */ 1027 1029 PCPGMPAGE pPage = &pCur->aPages[iPage]; 1028 paLSPages[iPage].uPassSaved = UINT32_MAX;1029 1030 paLSPages[iPage].cDirtied = 0; 1030 1031 paLSPages[iPage].fDirty = 1; /* everything is dirty at this time */ … … 1039 1040 paLSPages[iPage].fZero = 1; 1040 1041 paLSPages[iPage].fShared = 0; 1042 #ifdef PGMLIVESAVERAMPAGE_WITH_CRC32 1043 paLSPages[iPage].u32Crc = PGM_STATE_CRC32_ZERO_PAGE; 1044 #endif 1041 1045 } 1042 1046 else if (PGM_PAGE_IS_SHARED(pPage)) … … 1044 1048 paLSPages[iPage].fZero = 0; 1045 1049 paLSPages[iPage].fShared = 1; 1050 #ifdef PGMLIVESAVERAMPAGE_WITH_CRC32 1051 paLSPages[iPage].u32Crc = UINT32_MAX; 1052 #endif 1046 1053 } 1047 1054 else … … 1049 1056 paLSPages[iPage].fZero = 0; 1050 1057 paLSPages[iPage].fShared = 0; 1058 #ifdef PGMLIVESAVERAMPAGE_WITH_CRC32 1059 paLSPages[iPage].u32Crc = UINT32_MAX; 1060 #endif 1051 1061 } 1052 1062 paLSPages[iPage].fIgnore = 0; … … 1061 1071 paLSPages[iPage].fDirty = 0; 1062 1072 paLSPages[iPage].fIgnore = 1; 1073 #ifdef PGMLIVESAVERAMPAGE_WITH_CRC32 1074 paLSPages[iPage].u32Crc = UINT32_MAX; 1075 #endif 1063 1076 pVM->pgm.s.LiveSave.cIgnoredPages++; 1064 1077 break; … … 1073 1086 paLSPages[iPage].fDirty = 0; 1074 1087 paLSPages[iPage].fIgnore = 1; 1088 #ifdef PGMLIVESAVERAMPAGE_WITH_CRC32 1089 paLSPages[iPage].u32Crc = UINT32_MAX; 1090 #endif 1075 1091 pVM->pgm.s.LiveSave.cIgnoredPages++; 1076 1092 break; … … 1081 1097 paLSPages[iPage].fDirty = 0; 1082 1098 paLSPages[iPage].fIgnore = 1; 1099 #ifdef PGMLIVESAVERAMPAGE_WITH_CRC32 1100 paLSPages[iPage].u32Crc = UINT32_MAX; 1101 #endif 1083 1102 pVM->pgm.s.LiveSave.cIgnoredPages++; 1084 1103 break; … … 1093 1112 } 1094 1113 1114 #ifdef PGMLIVESAVERAMPAGE_WITH_CRC32 1115 1116 /** 1117 * Calculates the CRC-32 for a RAM page and updates the live save page tracking 1118 * info with it. 1119 * 1120 * @param pVM The VM handle. 1121 * @param pCur The current RAM range. 1122 * @param paLSPages The current array of live save page tracking 1123 * structures. 1124 * @param iPage The page index. 1125 */ 1126 static void pgmR3StateCalcCrc32ForRamPage(PVM pVM, PPGMRAMRANGE pCur, PPGMLIVESAVERAMPAGE paLSPages, uint32_t iPage) 1127 { 1128 RTGCPHYS GCPhys = pCur->GCPhys + ((RTGCPHYS)iPage << PAGE_SHIFT); 1129 void const *pvPage; 1130 int rc = pgmPhysGCPhys2CCPtrInternalReadOnly(pVM, &pCur->aPages[iPage], GCPhys, &pvPage); 1131 if (RT_SUCCESS(rc)) 1132 paLSPages[iPage].u32Crc = RTCrc32(pvPage, PAGE_SIZE); 1133 else 1134 paLSPages[iPage].u32Crc = UINT32_MAX; /* Invalid */ 1135 } 1136 1137 1138 /** 1139 * Verifies the CRC-32 for a page given it's raw bits. 1140 * 1141 * @param pvPage The page bits. 1142 * @param pCur The current RAM range. 1143 * @param paLSPages The current array of live save page tracking 1144 * structures. 1145 * @param iPage The page index. 1146 */ 1147 static void pgmR3StateVerifyCrc32ForPage(void const *pvPage, PPGMRAMRANGE pCur, PPGMLIVESAVERAMPAGE paLSPages, uint32_t iPage) 1148 { 1149 if (paLSPages[iPage].u32Crc != UINT32_MAX) 1150 { 1151 uint32_t u32Crc = RTCrc32(pvPage, PAGE_SIZE); 1152 Assert(!PGM_PAGE_IS_ZERO(&pCur->aPages[iPage]) || u32Crc == PGM_STATE_CRC32_ZERO_PAGE); 1153 AssertMsg(paLSPages[iPage].u32Crc == u32Crc, 1154 ("%08x != %08x for %RGp %R[pgmpage]\n", paLSPages[iPage].u32Crc, u32Crc, 1155 pCur->GCPhys + ((RTGCPHYS)iPage << PAGE_SHIFT), &pCur->aPages[iPage])); 1156 } 1157 } 1158 1159 1160 /** 1161 * Verfies the CRC-32 for a RAM page. 1162 * 1163 * @param pVM The VM handle. 1164 * @param pCur The current RAM range. 1165 * @param paLSPages The current array of live save page tracking 1166 * structures. 1167 * @param iPage The page index. 1168 */ 1169 static void pgmR3StateVerifyCrc32ForRamPage(PVM pVM, PPGMRAMRANGE pCur, PPGMLIVESAVERAMPAGE paLSPages, uint32_t iPage) 1170 { 1171 if (paLSPages[iPage].u32Crc != UINT32_MAX) 1172 { 1173 RTGCPHYS GCPhys = pCur->GCPhys + ((RTGCPHYS)iPage << PAGE_SHIFT); 1174 void const *pvPage; 1175 int rc = pgmPhysGCPhys2CCPtrInternalReadOnly(pVM, &pCur->aPages[iPage], GCPhys, &pvPage); 1176 if (RT_SUCCESS(rc)) 1177 pgmR3StateVerifyCrc32ForPage(pvPage, pCur, paLSPages, iPage); 1178 } 1179 } 1180 1181 #endif /* PGMLIVESAVERAMPAGE_WITH_CRC32 */ 1095 1182 1096 1183 /** … … 1116 1203 && !PGM_RAM_RANGE_IS_AD_HOC(pCur)) 1117 1204 { 1118 PPGMLIVESAVE PAGE paLSPages = pCur->paLSPages;1205 PPGMLIVESAVERAMPAGE paLSPages = pCur->paLSPages; 1119 1206 uint32_t cPages = pCur->cb >> PAGE_SHIFT; 1120 1207 uint32_t iPage = GCPhysCur <= pCur->GCPhys ? 0 : (GCPhysCur - pCur->GCPhys) >> PAGE_SHIFT; … … 1124 1211 /* Do yield first. */ 1125 1212 if ( !fFinalPass 1213 #ifndef PGMLIVESAVERAMPAGE_WITH_CRC32 1126 1214 && (iPage & 0x7ff) == 0x100 1215 #endif 1127 1216 && PDMR3CritSectYield(&pVM->pgm.s.CritSect) 1128 1217 && pVM->pgm.s.idRamRangesGen != idRamRangesGen) … … 1176 1265 paLSPages[iPage].fZero = 0; 1177 1266 paLSPages[iPage].fShared = 0; 1267 #ifdef PGMLIVESAVERAMPAGE_WITH_CRC32 1268 paLSPages[iPage].u32Crc = UINT32_MAX; /* invalid */ 1269 #endif 1178 1270 break; 1179 1271 … … 1181 1273 Assert(paLSPages[iPage].fWriteMonitored); 1182 1274 if (PGM_PAGE_GET_WRITE_LOCKS(&pCur->aPages[iPage]) == 0) 1275 { 1276 #ifdef PGMLIVESAVERAMPAGE_WITH_CRC32 1277 if (paLSPages[iPage].fWriteMonitoredJustNow) 1278 pgmR3StateCalcCrc32ForRamPage(pVM, pCur, paLSPages, iPage); 1279 else 1280 pgmR3StateVerifyCrc32ForRamPage(pVM, pCur, paLSPages, iPage); 1281 #endif 1183 1282 paLSPages[iPage].fWriteMonitoredJustNow = 0; 1283 } 1184 1284 else 1185 1285 { 1186 1286 paLSPages[iPage].fWriteMonitoredJustNow = 1; 1287 #ifdef PGMLIVESAVERAMPAGE_WITH_CRC32 1288 paLSPages[iPage].u32Crc = UINT32_MAX; /* invalid */ 1289 #endif 1187 1290 if (!paLSPages[iPage].fDirty) 1188 1291 { … … 1200 1303 paLSPages[iPage].fZero = 1; 1201 1304 paLSPages[iPage].fShared = 0; 1305 #ifdef PGMLIVESAVERAMPAGE_WITH_CRC32 1306 paLSPages[iPage].u32Crc = PGM_STATE_CRC32_ZERO_PAGE; 1307 #endif 1202 1308 if (!paLSPages[iPage].fDirty) 1203 1309 { … … 1215 1321 paLSPages[iPage].fZero = 0; 1216 1322 paLSPages[iPage].fShared = 1; 1323 #ifdef PGMLIVESAVERAMPAGE_WITH_CRC32 1324 pgmR3StateCalcCrc32ForRamPage(pVM, pCur, paLSPages, iPage); 1325 #endif 1217 1326 if (!paLSPages[iPage].fDirty) 1218 1327 { … … 1297 1406 && !PGM_RAM_RANGE_IS_AD_HOC(pCur)) 1298 1407 { 1299 PPGMLIVESAVE PAGE paLSPages = pCur->paLSPages;1408 PPGMLIVESAVERAMPAGE paLSPages = pCur->paLSPages; 1300 1409 uint32_t cPages = pCur->cb >> PAGE_SHIFT; 1301 1410 uint32_t iPage = GCPhysCur <= pCur->GCPhys ? 0 : (GCPhysCur - pCur->GCPhys) >> PAGE_SHIFT; … … 1342 1451 && !paLSPages[iPage].fDirty 1343 1452 && !paLSPages[iPage].fIgnore) 1453 { 1454 #ifdef PGMLIVESAVERAMPAGE_WITH_CRC32 1455 if (PGM_PAGE_GET_TYPE(&pCur->aPages[iPage]) != PGMPAGETYPE_RAM) 1456 pgmR3StateVerifyCrc32ForRamPage(pVM, pCur, paLSPages, iPage); 1457 #endif 1344 1458 continue; 1459 } 1345 1460 if (PGM_PAGE_GET_TYPE(&pCur->aPages[iPage]) != PGMPAGETYPE_RAM) 1346 1461 continue; … … 1360 1475 * SSM call may block). 1361 1476 */ 1362 charabPage[PAGE_SIZE];1477 uint8_t abPage[PAGE_SIZE]; 1363 1478 void const *pvPage; 1364 1479 rc = pgmPhysGCPhys2CCPtrInternalReadOnly(pVM, &pCur->aPages[iPage], GCPhys, &pvPage); 1365 1480 if (RT_SUCCESS(rc)) 1481 { 1366 1482 memcpy(abPage, pvPage, PAGE_SIZE); 1483 #ifdef PGMLIVESAVERAMPAGE_WITH_CRC32 1484 if (paLSPages) 1485 pgmR3StateVerifyCrc32ForPage(abPage, pCur, paLSPages, iPage); 1486 #endif 1487 } 1367 1488 pgmUnlock(pVM); 1368 1489 AssertLogRelMsgRCReturn(rc, ("rc=%Rrc GCPhys=%RGp\n", rc, GCPhys), rc); … … 1382 1503 * Dirty zero page. 1383 1504 */ 1505 #ifdef PGMLIVESAVERAMPAGE_WITH_CRC32 1506 if (paLSPages) 1507 pgmR3StateVerifyCrc32ForRamPage(pVM, pCur, paLSPages, iPage); 1508 #endif 1384 1509 pgmUnlock(pVM); 1385 1510 … … 1400 1525 { 1401 1526 paLSPages[iPage].fDirty = 0; 1402 paLSPages[iPage].uPassSaved = uPass;1403 1527 pVM->pgm.s.LiveSave.Ram.cReadyPages++; 1404 1528 pVM->pgm.s.LiveSave.Ram.cDirtyPages--; … … 1544 1668 } 1545 1669 1546 //#include <iprt/stream.h>1670 #include <iprt/stream.h> 1547 1671 1548 1672 /** … … 1556 1680 static DECLCALLBACK(int) pgmR3LiveVote(PVM pVM, PSSMHANDLE pSSM) 1557 1681 { 1558 #if 01682 #if 1 1559 1683 RTPrintf("# Rom[R/D/Z/M]=%03x/%03x/%03x/%03x Mmio2=%04x/%04x/%04x/%04x Ram=%06x/%06x/%06x/%06x Ignored=%03x\n", 1560 1684 pVM->pgm.s.LiveSave.Rom.cReadyPages, … … 1575 1699 if ((++s_iHack % 42) == 0) 1576 1700 return VINF_SUCCESS; 1701 RTThreadSleep(1000); 1702 1577 1703 #else 1578 1704 if ( pVM->pgm.s.LiveSave.Rom.cDirtyPages
Note:
See TracChangeset
for help on using the changeset viewer.