VirtualBox

Changeset 23539 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Oct 4, 2009 8:42:05 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
53182
Message:

PGMSavedState: Added some sanity checks for write monitored pages using CRC-32.

Location:
trunk/src/VBox/VMM
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/PGMInternal.h

    r23535 r23539  
    10421042
    10431043/** Max number of locks on a page. */
    1044 #define PGM_PAGE_MAX_LOCKS                  254
     1044#define PGM_PAGE_MAX_LOCKS                  UINT8_C(254)
    10451045
    10461046/** Get the read lock count.
     
    10771077
    10781078
     1079#if 0
     1080/** Enables sanity checking of write monitoring using CRC-32.  */
     1081#define PGMLIVESAVERAMPAGE_WITH_CRC32
     1082#endif
    10791083
    10801084/**
    10811085 * Per page live save tracking data.
    10821086 */
    1083 typedef struct PGMLIVESAVEPAGE
    1084 {
    1085     /** The pass number where this page was last saved.  */
    1086     uint32_t    uPassSaved;
     1087typedef struct PGMLIVESAVERAMPAGE
     1088{
    10871089    /** Number of times it has been dirtied. */
    10881090    uint32_t    cDirtied : 24;
     
    11041106    /** Bits reserved for future use.  */
    11051107    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
     1114AssertCompileSize(PGMLIVESAVERAMPAGE, 8);
     1115#else
     1116AssertCompileSize(PGMLIVESAVERAMPAGE, 4);
     1117#endif
    11081118/** Pointer to the per page live save tracking data. */
    1109 typedef PGMLIVESAVEPAGE *PPGMLIVESAVEPAGE;
    1110 
    1111 /** The max value of PGMLIVESAVEPAGE::cDirtied. */
     1119typedef PGMLIVESAVERAMPAGE *PPGMLIVESAVERAMPAGE;
     1120
     1121/** The max value of PGMLIVESAVERAMPAGE::cDirtied. */
    11121122#define PGMLIVSAVEPAGE_MAX_DIRTIED 0x00fffff0
    11131123
     
    11401150    R3PTRTYPE(void *)                   pvR3;
    11411151    /** Live save per page tracking data. */
    1142     R3PTRTYPE(PPGMLIVESAVEPAGE)         paLSPages;
     1152    R3PTRTYPE(PPGMLIVESAVERAMPAGE)         paLSPages;
    11431153    /** The range description. */
    11441154    R3PTRTYPE(const char *)             pszDesc;
     
    12591269 * Live save per page data for an MMIO2 page.
    12601270 *
    1261  * Not using PGMLIVESAVEPAGE here because we cannot use normal write monitoring
     1271 * Not using PGMLIVESAVERAMPAGE here because we cannot use normal write monitoring
    12621272 * of MMIO2 pages.  The current approach is using some optimisitic SHA-1 +
    12631273 * CRC-32 for detecting changes as well as special handling of zero pages.  This
  • trunk/src/VBox/VMM/PGMSavedState.cpp

    r23536 r23539  
    9292/** @} */
    9393
     94/** The CRC-32 for a zero page. */
     95#define PGM_STATE_CRC32_ZERO_PAGE       UINT32_C(0xc71c0011)
    9496/** The CRC-32 for a zero half page. */
    9597#define PGM_STATE_CRC32_ZERO_HALF_PAGE  UINT32_C(0xf1e8ba9e)
     
    10051007                uint32_t const  cPages = pCur->cb >> PAGE_SHIFT;
    10061008                pgmUnlock(pVM);
    1007                 PPGMLIVESAVEPAGE paLSPages = (PPGMLIVESAVEPAGE)MMR3HeapAllocZ(pVM, MM_TAG_PGM, cPages * sizeof(PGMLIVESAVEPAGE));
     1009                PPGMLIVESAVERAMPAGE paLSPages = (PPGMLIVESAVERAMPAGE)MMR3HeapAllocZ(pVM, MM_TAG_PGM, cPages * sizeof(PGMLIVESAVERAMPAGE));
    10081010                if (!paLSPages)
    10091011                    return VERR_NO_MEMORY;
     
    10261028                    /** @todo yield critsect! (after moving this away from EMT0) */
    10271029                    PCPGMPAGE pPage = &pCur->aPages[iPage];
    1028                     paLSPages[iPage].uPassSaved             = UINT32_MAX;
    10291030                    paLSPages[iPage].cDirtied               = 0;
    10301031                    paLSPages[iPage].fDirty                 = 1; /* everything is dirty at this time */
     
    10391040                                paLSPages[iPage].fZero   = 1;
    10401041                                paLSPages[iPage].fShared = 0;
     1042#ifdef PGMLIVESAVERAMPAGE_WITH_CRC32
     1043                                paLSPages[iPage].u32Crc  = PGM_STATE_CRC32_ZERO_PAGE;
     1044#endif
    10411045                            }
    10421046                            else if (PGM_PAGE_IS_SHARED(pPage))
     
    10441048                                paLSPages[iPage].fZero   = 0;
    10451049                                paLSPages[iPage].fShared = 1;
     1050#ifdef PGMLIVESAVERAMPAGE_WITH_CRC32
     1051                                paLSPages[iPage].u32Crc  = UINT32_MAX;
     1052#endif
    10461053                            }
    10471054                            else
     
    10491056                                paLSPages[iPage].fZero   = 0;
    10501057                                paLSPages[iPage].fShared = 0;
     1058#ifdef PGMLIVESAVERAMPAGE_WITH_CRC32
     1059                                paLSPages[iPage].u32Crc  = UINT32_MAX;
     1060#endif
    10511061                            }
    10521062                            paLSPages[iPage].fIgnore     = 0;
     
    10611071                            paLSPages[iPage].fDirty  = 0;
    10621072                            paLSPages[iPage].fIgnore = 1;
     1073#ifdef PGMLIVESAVERAMPAGE_WITH_CRC32
     1074                            paLSPages[iPage].u32Crc  = UINT32_MAX;
     1075#endif
    10631076                            pVM->pgm.s.LiveSave.cIgnoredPages++;
    10641077                            break;
     
    10731086                            paLSPages[iPage].fDirty  = 0;
    10741087                            paLSPages[iPage].fIgnore = 1;
     1088#ifdef PGMLIVESAVERAMPAGE_WITH_CRC32
     1089                            paLSPages[iPage].u32Crc  = UINT32_MAX;
     1090#endif
    10751091                            pVM->pgm.s.LiveSave.cIgnoredPages++;
    10761092                            break;
     
    10811097                            paLSPages[iPage].fDirty  = 0;
    10821098                            paLSPages[iPage].fIgnore = 1;
     1099#ifdef PGMLIVESAVERAMPAGE_WITH_CRC32
     1100                            paLSPages[iPage].u32Crc  = UINT32_MAX;
     1101#endif
    10831102                            pVM->pgm.s.LiveSave.cIgnoredPages++;
    10841103                            break;
     
    10931112}
    10941113
     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 */
     1126static 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 */
     1147static 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 */
     1169static 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 */
    10951182
    10961183/**
     
    11161203                && !PGM_RAM_RANGE_IS_AD_HOC(pCur))
    11171204            {
    1118                 PPGMLIVESAVEPAGE paLSPages = pCur->paLSPages;
     1205                PPGMLIVESAVERAMPAGE paLSPages = pCur->paLSPages;
    11191206                uint32_t         cPages    = pCur->cb >> PAGE_SHIFT;
    11201207                uint32_t         iPage     = GCPhysCur <= pCur->GCPhys ? 0 : (GCPhysCur - pCur->GCPhys) >> PAGE_SHIFT;
     
    11241211                    /* Do yield first. */
    11251212                    if (   !fFinalPass
     1213#ifndef PGMLIVESAVERAMPAGE_WITH_CRC32
    11261214                        && (iPage & 0x7ff) == 0x100
     1215#endif
    11271216                        && PDMR3CritSectYield(&pVM->pgm.s.CritSect)
    11281217                        && pVM->pgm.s.idRamRangesGen != idRamRangesGen)
     
    11761265                                paLSPages[iPage].fZero                  = 0;
    11771266                                paLSPages[iPage].fShared                = 0;
     1267#ifdef PGMLIVESAVERAMPAGE_WITH_CRC32
     1268                                paLSPages[iPage].u32Crc                 = UINT32_MAX; /* invalid */
     1269#endif
    11781270                                break;
    11791271
     
    11811273                                Assert(paLSPages[iPage].fWriteMonitored);
    11821274                                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
    11831282                                    paLSPages[iPage].fWriteMonitoredJustNow = 0;
     1283                                }
    11841284                                else
    11851285                                {
    11861286                                    paLSPages[iPage].fWriteMonitoredJustNow = 1;
     1287#ifdef PGMLIVESAVERAMPAGE_WITH_CRC32
     1288                                    paLSPages[iPage].u32Crc                 = UINT32_MAX; /* invalid */
     1289#endif
    11871290                                    if (!paLSPages[iPage].fDirty)
    11881291                                    {
     
    12001303                                    paLSPages[iPage].fZero = 1;
    12011304                                    paLSPages[iPage].fShared = 0;
     1305#ifdef PGMLIVESAVERAMPAGE_WITH_CRC32
     1306                                    paLSPages[iPage].u32Crc = PGM_STATE_CRC32_ZERO_PAGE;
     1307#endif
    12021308                                    if (!paLSPages[iPage].fDirty)
    12031309                                    {
     
    12151321                                    paLSPages[iPage].fZero = 0;
    12161322                                    paLSPages[iPage].fShared = 1;
     1323#ifdef PGMLIVESAVERAMPAGE_WITH_CRC32
     1324                                    pgmR3StateCalcCrc32ForRamPage(pVM, pCur, paLSPages, iPage);
     1325#endif
    12171326                                    if (!paLSPages[iPage].fDirty)
    12181327                                    {
     
    12971406                && !PGM_RAM_RANGE_IS_AD_HOC(pCur))
    12981407            {
    1299                 PPGMLIVESAVEPAGE paLSPages = pCur->paLSPages;
     1408                PPGMLIVESAVERAMPAGE paLSPages = pCur->paLSPages;
    13001409                uint32_t         cPages    = pCur->cb >> PAGE_SHIFT;
    13011410                uint32_t         iPage     = GCPhysCur <= pCur->GCPhys ? 0 : (GCPhysCur - pCur->GCPhys) >> PAGE_SHIFT;
     
    13421451                            && !paLSPages[iPage].fDirty
    13431452                            && !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
    13441458                            continue;
     1459                        }
    13451460                        if (PGM_PAGE_GET_TYPE(&pCur->aPages[iPage]) != PGMPAGETYPE_RAM)
    13461461                            continue;
     
    13601475                         * SSM call may block).
    13611476                         */
    1362                         char        abPage[PAGE_SIZE];
     1477                        uint8_t     abPage[PAGE_SIZE];
    13631478                        void const *pvPage;
    13641479                        rc = pgmPhysGCPhys2CCPtrInternalReadOnly(pVM, &pCur->aPages[iPage], GCPhys, &pvPage);
    13651480                        if (RT_SUCCESS(rc))
     1481                        {
    13661482                            memcpy(abPage, pvPage, PAGE_SIZE);
     1483#ifdef PGMLIVESAVERAMPAGE_WITH_CRC32
     1484                            if (paLSPages)
     1485                                pgmR3StateVerifyCrc32ForPage(abPage, pCur, paLSPages, iPage);
     1486#endif
     1487                        }
    13671488                        pgmUnlock(pVM);
    13681489                        AssertLogRelMsgRCReturn(rc, ("rc=%Rrc GCPhys=%RGp\n", rc, GCPhys), rc);
     
    13821503                         * Dirty zero page.
    13831504                         */
     1505#ifdef PGMLIVESAVERAMPAGE_WITH_CRC32
     1506                        if (paLSPages)
     1507                            pgmR3StateVerifyCrc32ForRamPage(pVM, pCur, paLSPages, iPage);
     1508#endif
    13841509                        pgmUnlock(pVM);
    13851510
     
    14001525                    {
    14011526                        paLSPages[iPage].fDirty = 0;
    1402                         paLSPages[iPage].uPassSaved = uPass;
    14031527                        pVM->pgm.s.LiveSave.Ram.cReadyPages++;
    14041528                        pVM->pgm.s.LiveSave.Ram.cDirtyPages--;
     
    15441668}
    15451669
    1546 //#include <iprt/stream.h>
     1670#include <iprt/stream.h>
    15471671
    15481672/**
     
    15561680static DECLCALLBACK(int)  pgmR3LiveVote(PVM pVM, PSSMHANDLE pSSM)
    15571681{
    1558 #if 0
     1682#if 1
    15591683    RTPrintf("# Rom[R/D/Z/M]=%03x/%03x/%03x/%03x  Mmio2=%04x/%04x/%04x/%04x  Ram=%06x/%06x/%06x/%06x Ignored=%03x\n",
    15601684             pVM->pgm.s.LiveSave.Rom.cReadyPages,
     
    15751699    if ((++s_iHack % 42) == 0)
    15761700        return VINF_SUCCESS;
     1701    RTThreadSleep(1000);
     1702
    15771703#else
    15781704    if (      pVM->pgm.s.LiveSave.Rom.cDirtyPages
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette