VirtualBox

Changeset 57008 in vbox for trunk


Ignore:
Timestamp:
Jul 19, 2015 5:11:15 PM (9 years ago)
Author:
vboxsync
Message:

CSAM: Fixed saved state (broken since r10346). Won't easily break again.

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR3/CSAM.cpp

    r56287 r57008  
    4949#include <VBox/err.h>
    5050#include <VBox/log.h>
     51#include <VBox/version.h>
    5152
    5253#include <VBox/dis.h>
     
    7677bool                csamIsCodeScanned(PVM pVM, RTRCPTR pInstr, PCSAMPAGE *pPage);
    7778int                 csamR3CheckPageRecord(PVM pVM, RTRCPTR pInstr);
    78 static PCSAMPAGE    csamCreatePageRecord(PVM pVM, RTRCPTR GCPtr, CSAMTAG enmTag, bool fCode32, bool fMonitorInvalidation = false);
     79static PCSAMPAGE    csamR3CreatePageRecord(PVM pVM, RTRCPTR GCPtr, CSAMTAG enmTag, bool fCode32, bool fMonitorInvalidation = false);
    7980static int          csamRemovePageRecord(PVM pVM, RTRCPTR GCPtr);
    8081static int          csamReinit(PVM pVM);
     
    106107
    107108/**
    108  * SSM descriptor table for the CSAM structure.
     109 * SSM descriptor table for the CSAM structure (save + restore).
    109110 */
    110111static const SSMFIELD g_aCsamFields[] =
     112{
     113    SSMFIELD_ENTRY(             CSAM, aDangerousInstr),        /* didn't used to restored */
     114    SSMFIELD_ENTRY(             CSAM, cDangerousInstr),        /* didn't used to restored */
     115    SSMFIELD_ENTRY(             CSAM, iDangerousInstr),        /* didn't used to restored */
     116    SSMFIELD_ENTRY(             CSAM, savedstate.cPageRecords),
     117    SSMFIELD_ENTRY(             CSAM, savedstate.cPatchPageRecords),
     118    SSMFIELD_ENTRY(             CSAM, cDirtyPages),
     119    SSMFIELD_ENTRY_RCPTR_ARRAY( CSAM, pvDirtyBasePage),
     120    SSMFIELD_ENTRY_RCPTR_ARRAY( CSAM, pvDirtyFaultPage),
     121    SSMFIELD_ENTRY(             CSAM, cPossibleCodePages),
     122    SSMFIELD_ENTRY_RCPTR_ARRAY( CSAM, pvPossibleCodePage),
     123    SSMFIELD_ENTRY_RCPTR_ARRAY( CSAM, pvCallInstruction),       /* didn't used to be restored */
     124    SSMFIELD_ENTRY(             CSAM, iCallInstruction),        /* didn't used to be restored */
     125    SSMFIELD_ENTRY(             CSAM, fScanningStarted),
     126    SSMFIELD_ENTRY(             CSAM, fGatesChecked),
     127    SSMFIELD_ENTRY_TERM()
     128};
     129
     130/**
     131 * SSM descriptor table for the version 5.0.0 CSAM structure.
     132 */
     133static const SSMFIELD g_aCsamFields500[] =
     134{
     135    SSMFIELD_ENTRY_IGNORE(      CSAM, offVM),
     136    SSMFIELD_ENTRY_PAD_HC64(    CSAM, Alignment0, sizeof(uint32_t)),
     137    SSMFIELD_ENTRY_IGN_HCPTR(   CSAM, pPageTree),
     138    SSMFIELD_ENTRY(             CSAM, aDangerousInstr),
     139    SSMFIELD_ENTRY(             CSAM, cDangerousInstr),
     140    SSMFIELD_ENTRY(             CSAM, iDangerousInstr),
     141    SSMFIELD_ENTRY_RCPTR(       CSAM, pPDBitmapGC),   /// @todo ignore this?
     142    SSMFIELD_ENTRY_RCPTR(       CSAM, pPDHCBitmapGC), /// @todo ignore this?
     143    SSMFIELD_ENTRY_IGN_HCPTR(   CSAM, pPDBitmapHC),
     144    SSMFIELD_ENTRY_IGN_HCPTR(   CSAM, pPDGCBitmapHC),
     145    SSMFIELD_ENTRY_IGN_HCPTR(   CSAM, savedstate.pSSM),
     146    SSMFIELD_ENTRY(             CSAM, savedstate.cPageRecords),
     147    SSMFIELD_ENTRY(             CSAM, savedstate.cPatchPageRecords),
     148    SSMFIELD_ENTRY(             CSAM, cDirtyPages),
     149    SSMFIELD_ENTRY_RCPTR_ARRAY( CSAM, pvDirtyBasePage),
     150    SSMFIELD_ENTRY_RCPTR_ARRAY( CSAM, pvDirtyFaultPage),
     151    SSMFIELD_ENTRY(             CSAM, cPossibleCodePages),
     152    SSMFIELD_ENTRY_RCPTR_ARRAY( CSAM, pvPossibleCodePage),
     153    SSMFIELD_ENTRY_RCPTR_ARRAY( CSAM, pvCallInstruction),
     154    SSMFIELD_ENTRY(             CSAM, iCallInstruction),
     155    SSMFIELD_ENTRY_IGNORE(      CSAM, hCodePageWriteType),          /* added in 5.0 */
     156    SSMFIELD_ENTRY_IGNORE(      CSAM, hCodePageWriteAndInvPgType),  /* added in 5.0 */
     157    SSMFIELD_ENTRY(             CSAM, fScanningStarted),
     158    SSMFIELD_ENTRY(             CSAM, fGatesChecked),
     159    SSMFIELD_ENTRY_PAD_HC(      CSAM, Alignment1, 6, 2),
     160    SSMFIELD_ENTRY_IGNORE(      CSAM, StatNrTraps),
     161    SSMFIELD_ENTRY_IGNORE(      CSAM, StatNrPages),
     162    SSMFIELD_ENTRY_IGNORE(      CSAM, StatNrPagesInv),
     163    SSMFIELD_ENTRY_IGNORE(      CSAM, StatNrRemovedPages),
     164    SSMFIELD_ENTRY_IGNORE(      CSAM, StatNrPatchPages),
     165    SSMFIELD_ENTRY_IGNORE(      CSAM, StatNrPageNPHC),
     166    SSMFIELD_ENTRY_IGNORE(      CSAM, StatNrPageNPGC),
     167    SSMFIELD_ENTRY_IGNORE(      CSAM, StatNrFlushes),
     168    SSMFIELD_ENTRY_IGNORE(      CSAM, StatNrFlushesSkipped),
     169    SSMFIELD_ENTRY_IGNORE(      CSAM, StatNrKnownPagesHC),
     170    SSMFIELD_ENTRY_IGNORE(      CSAM, StatNrKnownPagesGC),
     171    SSMFIELD_ENTRY_IGNORE(      CSAM, StatNrInstr),
     172    SSMFIELD_ENTRY_IGNORE(      CSAM, StatNrBytesRead),
     173    SSMFIELD_ENTRY_IGNORE(      CSAM, StatNrOpcodeRead),
     174    SSMFIELD_ENTRY_IGNORE(      CSAM, StatTime),
     175    SSMFIELD_ENTRY_IGNORE(      CSAM, StatTimeCheckAddr),
     176    SSMFIELD_ENTRY_IGNORE(      CSAM, StatTimeAddrConv),
     177    SSMFIELD_ENTRY_IGNORE(      CSAM, StatTimeFlushPage),
     178    SSMFIELD_ENTRY_IGNORE(      CSAM, StatTimeDisasm),
     179    SSMFIELD_ENTRY_IGNORE(      CSAM, StatFlushDirtyPages),
     180    SSMFIELD_ENTRY_IGNORE(      CSAM, StatCheckGates),
     181    SSMFIELD_ENTRY_IGNORE(      CSAM, StatCodePageModified),
     182    SSMFIELD_ENTRY_IGNORE(      CSAM, StatDangerousWrite),
     183    SSMFIELD_ENTRY_IGNORE(      CSAM, StatInstrCacheHit),
     184    SSMFIELD_ENTRY_IGNORE(      CSAM, StatInstrCacheMiss),
     185    SSMFIELD_ENTRY_IGNORE(      CSAM, StatPagePATM),
     186    SSMFIELD_ENTRY_IGNORE(      CSAM, StatPageCSAM),
     187    SSMFIELD_ENTRY_IGNORE(      CSAM, StatPageREM),
     188    SSMFIELD_ENTRY_IGNORE(      CSAM, StatNrUserPages),
     189    SSMFIELD_ENTRY_IGNORE(      CSAM, StatPageMonitor),
     190    SSMFIELD_ENTRY_IGNORE(      CSAM, StatPageRemoveREMFlush),
     191    SSMFIELD_ENTRY_IGNORE(      CSAM, StatBitmapAlloc),
     192    SSMFIELD_ENTRY_IGNORE(      CSAM, StatScanNextFunction),
     193    SSMFIELD_ENTRY_IGNORE(      CSAM, StatScanNextFunctionFailed),
     194    SSMFIELD_ENTRY_TERM()
     195};
     196
     197/**
     198 * SSM descriptor table for the pre 5.0.0 CSAM structure.
     199 */
     200static const SSMFIELD g_aCsamFieldsBefore500[] =
    111201{
    112202    /** @todo there are more fields that can be ignored here. */
     
    171261};
    172262
     263
    173264/** Fake type to simplify g_aCsamPDBitmapArray construction. */
    174265typedef struct
     
    186277};
    187278
    188 /**
    189  * SSM descriptor table for the CSAMPAGEREC structure.
     279
     280/**
     281 * SSM descriptor table for the CSAMPAGE structure.
     282 */
     283static const SSMFIELD g_aCsamPageFields[] =
     284{
     285    SSMFIELD_ENTRY_RCPTR(       CSAMPAGE, pPageGC),
     286    SSMFIELD_ENTRY_GCPHYS(      CSAMPAGE, GCPhys),
     287    SSMFIELD_ENTRY(             CSAMPAGE, fFlags),
     288    SSMFIELD_ENTRY(             CSAMPAGE, uSize),
     289    SSMFIELD_ENTRY_HCPTR_NI(    CSAMPAGE, pBitmap),
     290    SSMFIELD_ENTRY(             CSAMPAGE, fCode32),
     291    SSMFIELD_ENTRY(             CSAMPAGE, fMonitorActive),
     292    SSMFIELD_ENTRY(             CSAMPAGE, fMonitorInvalidation),
     293    SSMFIELD_ENTRY(             CSAMPAGE, enmTag),
     294    SSMFIELD_ENTRY(             CSAMPAGE, u64Hash),
     295    SSMFIELD_ENTRY_TERM()
     296};
     297
     298/**
     299 * SSM descriptor table for the CSAMPAGEREC structure, putmem fashion.
    190300 */
    191301static const SSMFIELD g_aCsamPageRecFields[] =
     
    495605 * @param   pcPatches       Pointer to patch counter
    496606 */
    497 static DECLCALLBACK(int) CountRecord(PAVLPVNODECORE pNode, void *pcPatches)
     607static DECLCALLBACK(int) csamR3SaveCountRecord(PAVLPVNODECORE pNode, void *pcPatches)
    498608{
    499609    NOREF(pNode);
    500     *(uint32_t *)pcPatches = *(uint32_t *)pcPatches + 1;
     610    *(uint32_t *)pcPatches += 1;
    501611    return VINF_SUCCESS;
    502612}
    503613
    504614/**
    505  * Callback function for RTAvlPVDoWithAll
    506  *
    507  * Saves the state of the page record
     615 * Callback function for RTAvlPVDoWithAll for saving a page record.
    508616 *
    509617 * @returns VBox status code.
    510618 * @param   pNode           Current node
    511  * @param   pVM1            Pointer to the VM
    512  */
    513 static DECLCALLBACK(int) SavePageState(PAVLPVNODECORE pNode, void *pVM1)
    514 {
    515     PVM           pVM    = (PVM)pVM1;
     619 * @param   pvVM            Pointer to the VM
     620 */
     621static DECLCALLBACK(int) csamR3SavePageState(PAVLPVNODECORE pNode, void *pvVM)
     622{
    516623    PCSAMPAGEREC  pPage  = (PCSAMPAGEREC)pNode;
    517     CSAMPAGEREC   page   = *pPage;
     624    PVM           pVM    = (PVM)pvVM;
    518625    PSSMHANDLE    pSSM   = pVM->csam.s.savedstate.pSSM;
    519     int           rc;
    520 
    521     /* Save the page record itself */
    522     rc = SSMR3PutMem(pSSM, &page, sizeof(page));
    523     AssertRCReturn(rc, rc);
    524 
    525     if (page.page.pBitmap)
    526     {
    527         rc = SSMR3PutMem(pSSM, page.page.pBitmap, CSAM_PAGE_BITMAP_SIZE);
    528         AssertRCReturn(rc, rc);
    529     }
     626
     627    int rc = SSMR3PutStructEx(pSSM, &pPage->page, sizeof(pPage->page), 0 /*fFlags*/, &g_aCsamPageFields[0], NULL);
     628    AssertLogRelRCReturn(rc, rc);
     629
     630    if (pPage->page.pBitmap)
     631        SSMR3PutMem(pSSM, pPage->page.pBitmap, CSAM_PAGE_BITMAP_SIZE);
    530632
    531633    return VINF_SUCCESS;
     
    541643static DECLCALLBACK(int) csamR3Save(PVM pVM, PSSMHANDLE pSSM)
    542644{
    543     CSAM csamInfo = pVM->csam.s;
    544645    int  rc;
    545646
     
    547648     * Count the number of page records in the tree (feeling lazy)
    548649     */
    549     csamInfo.savedstate.cPageRecords = 0;
    550     RTAvlPVDoWithAll(&pVM->csam.s.pPageTree, true, CountRecord, &csamInfo.savedstate.cPageRecords);
     650    pVM->csam.s.savedstate.cPageRecords = 0;
     651    RTAvlPVDoWithAll(&pVM->csam.s.pPageTree, true, csamR3SaveCountRecord, &pVM->csam.s.savedstate.cPageRecords);
    551652
    552653    /*
    553      * Save CSAM structure
     654     * Save CSAM structure.
    554655     */
    555656    pVM->csam.s.savedstate.pSSM = pSSM;
    556     rc = SSMR3PutMem(pSSM, &csamInfo, sizeof(csamInfo));
    557     AssertRCReturn(rc, rc);
    558 
    559     /* Save pgdir bitmap */
    560     rc = SSMR3PutMem(pSSM, csamInfo.pPDBitmapHC, CSAM_PGDIRBMP_CHUNKS*sizeof(RTHCPTR));
    561     AssertRCReturn(rc, rc);
    562 
    563     for (unsigned i = 0; i < CSAM_PGDIRBMP_CHUNKS; i++)
    564     {
    565         if(csamInfo.pPDBitmapHC[i])
    566         {
    567             /* Save the page bitmap. */
    568             rc = SSMR3PutMem(pSSM, csamInfo.pPDBitmapHC[i], CSAM_PAGE_BITMAP_SIZE);
    569             AssertRCReturn(rc, rc);
    570         }
    571     }
     657    rc = SSMR3PutStructEx(pSSM, &pVM->csam.s, sizeof(pVM->csam.s), 0 /*fFlags*/, g_aCsamFields, NULL);
     658    AssertLogRelRCReturn(rc, rc);
     659
     660    /*
     661     * Save pgdir bitmap.
     662     */
     663    SSMR3PutU32(pSSM, CSAM_PGDIRBMP_CHUNKS);
     664    SSMR3PutU32(pSSM, CSAM_PAGE_BITMAP_SIZE);
     665    for (uint32_t i = 0; i < CSAM_PGDIRBMP_CHUNKS; i++)
     666        if (pVM->csam.s.pPDBitmapHC[i])
     667        {
     668            SSMR3PutU32(pSSM, i);
     669            SSMR3PutMem(pSSM, pVM->csam.s.pPDBitmapHC[i], CSAM_PAGE_BITMAP_SIZE);
     670        }
     671    SSMR3PutU32(pSSM, UINT32_MAX); /* terminator */
    572672
    573673    /*
    574674     * Save page records
    575675     */
    576     rc = RTAvlPVDoWithAll(&pVM->csam.s.pPageTree, true, SavePageState, pVM);
     676    pVM->csam.s.savedstate.pSSM = pSSM;
     677    rc = RTAvlPVDoWithAll(&pVM->csam.s.pPageTree, true, csamR3SavePageState, pVM);
    577678    AssertRCReturn(rc, rc);
    578679
    579     /** @note we don't restore aDangerousInstr; it will be recreated automatically. */
     680    pVM->csam.s.savedstate.pSSM = NULL;
    580681    return VINF_SUCCESS;
    581682}
     
    593694static DECLCALLBACK(int) csamR3Load(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
    594695{
    595     int  rc;
    596     CSAM csamInfo;
    597 
     696    int rc;
     697
     698    /*
     699     * Check preconditions.
     700     */
    598701    Assert(uPass == SSM_PASS_FINAL); NOREF(uPass);
    599     if (uVersion != CSAM_SAVED_STATE_VERSION)
    600     {
    601         AssertMsgFailed(("csamR3Load: Invalid version uVersion=%d!\n", uVersion));
    602         return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
    603     }
    604 
    605     pVM->csam.s.savedstate.pSSM = pSSM;
    606 
    607     /*
    608      * Restore CSAM structure
    609      */
    610     RT_ZERO(csamInfo);
    611     rc = SSMR3GetStructEx(pSSM, &csamInfo, sizeof(csamInfo), SSMSTRUCT_FLAGS_MEM_BAND_AID_RELAXED, &g_aCsamFields[0], NULL);
    612     AssertRCReturn(rc, rc);
    613 
    614     pVM->csam.s.fGatesChecked    = csamInfo.fGatesChecked;
    615     pVM->csam.s.fScanningStarted = csamInfo.fScanningStarted;
    616 
    617      /* Restore dirty code page info. */
    618     pVM->csam.s.cDirtyPages = csamInfo.cDirtyPages;
    619     memcpy(pVM->csam.s.pvDirtyBasePage,  csamInfo.pvDirtyBasePage, sizeof(pVM->csam.s.pvDirtyBasePage));
    620     memcpy(pVM->csam.s.pvDirtyFaultPage, csamInfo.pvDirtyFaultPage, sizeof(pVM->csam.s.pvDirtyFaultPage));
    621 
    622      /* Restore possible code page  */
    623     pVM->csam.s.cPossibleCodePages = csamInfo.cPossibleCodePages;
    624     memcpy(pVM->csam.s.pvPossibleCodePage,  csamInfo.pvPossibleCodePage, sizeof(pVM->csam.s.pvPossibleCodePage));
    625 
    626     /* Restore pgdir bitmap (we'll change the pointers next). */
    627     rc = SSMR3GetStructEx(pSSM, pVM->csam.s.pPDBitmapHC, sizeof(uint8_t *) * CSAM_PGDIRBMP_CHUNKS,
    628                           SSMSTRUCT_FLAGS_MEM_BAND_AID_RELAXED, &g_aCsamPDBitmapArray[0], NULL);
    629     AssertRCReturn(rc, rc);
    630 
    631     /*
    632      * Restore page bitmaps
    633      */
    634     for (unsigned i=0;i<CSAM_PGDIRBMP_CHUNKS;i++)
    635     {
    636         if(pVM->csam.s.pPDBitmapHC[i])
    637         {
    638             rc = MMHyperAlloc(pVM, CSAM_PAGE_BITMAP_SIZE, 0, MM_TAG_CSAM, (void **)&pVM->csam.s.pPDBitmapHC[i]);
    639             if (RT_FAILURE(rc))
     702    Assert(pVM->csam.s.savedstate.pSSM == NULL);
     703    AssertLogRelMsgReturn(uVersion >= CSAM_SAVED_STATE_VERSION_PUT_MEM && uVersion <= CSAM_SAVED_STATE_VERSION,
     704                          ("uVersion=%d (%#x)\n", uVersion),
     705                          VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION);
     706
     707    if (uVersion >= CSAM_SAVED_STATE_VERSION_PUT_STRUCT)
     708    {
     709        /*
     710         * Restore the SSMR3PutStructEx fashioned state.
     711         */
     712        rc = SSMR3GetStructEx(pSSM, &pVM->csam.s, sizeof(pVM->csam.s), 0 /*fFlags*/, &g_aCsamFields[0], NULL);
     713
     714        /*
     715         * Restore page bitmaps
     716         */
     717        uint32_t cPgDirBmpChunks = 0;
     718        rc = SSMR3GetU32(pSSM, &cPgDirBmpChunks);
     719        uint32_t cbPgDirBmpChunk = 0;
     720        rc = SSMR3GetU32(pSSM, &cbPgDirBmpChunk);
     721        AssertRCReturn(rc, rc);
     722        AssertLogRelMsgReturn(cPgDirBmpChunks <= CSAM_PGDIRBMP_CHUNKS,
     723                              ("cPgDirBmpChunks=%#x (vs %#x)\n", cPgDirBmpChunks, CSAM_PGDIRBMP_CHUNKS),
     724                              VERR_SSM_UNEXPECTED_DATA);
     725        AssertLogRelMsgReturn(cbPgDirBmpChunk <= CSAM_PAGE_BITMAP_SIZE,
     726                              ("cbPgDirBmpChunk=%#x (vs %#x)\n", cbPgDirBmpChunk, CSAM_PAGE_BITMAP_SIZE),
     727                              VERR_SSM_UNEXPECTED_DATA);
     728        for (uint32_t i = 0; i < CSAM_PGDIRBMP_CHUNKS; i++)
     729        {
     730            Assert(!pVM->csam.s.pPDBitmapHC[i]);
     731            Assert(!pVM->csam.s.pPDGCBitmapHC[i]);
     732        }
     733        for (uint32_t iNext = 0;;)
     734        {
     735            uint32_t iThis;
     736            rc = SSMR3GetU32(pSSM, &iThis);
     737            AssertLogRelRCReturn(rc, rc);
     738            AssertLogRelMsgReturn(iThis >= iNext, ("iThis=%#x iNext=%#x\n", iThis, iNext), VERR_SSM_UNEXPECTED_DATA);
     739            if (iThis == UINT32_MAX)
     740                break;
     741
     742            rc = MMHyperAlloc(pVM, CSAM_PAGE_BITMAP_SIZE, 0, MM_TAG_CSAM, (void **)&pVM->csam.s.pPDBitmapHC[iThis]);
     743            AssertLogRelRCReturn(rc, rc);
     744            pVM->csam.s.pPDGCBitmapHC[iThis] = MMHyperR3ToRC(pVM, pVM->csam.s.pPDBitmapHC[iThis]);
     745
     746            rc = SSMR3GetMem(pSSM, pVM->csam.s.pPDBitmapHC[iThis], CSAM_PAGE_BITMAP_SIZE);
     747            AssertLogRelRCReturn(rc, rc);
     748            iNext = iThis + 1;
     749        }
     750
     751        /*
     752         * Restore page records
     753         */
     754        uint32_t const cPageRecords = pVM->csam.s.savedstate.cPageRecords + pVM->csam.s.savedstate.cPatchPageRecords;
     755        for (uint32_t iPageRec = 0; iPageRec < cPageRecords; iPageRec++)
     756        {
     757            CSAMPAGE PageRec;
     758            RT_ZERO(PageRec);
     759            rc = SSMR3GetStructEx(pSSM, &PageRec, sizeof(PageRec), 0 /*fFlags*/, &g_aCsamPageFields[0], NULL);
     760            AssertLogRelRCReturn(rc, rc);
     761
     762            /* Recreate the page record. */
     763            PCSAMPAGE pPage = csamR3CreatePageRecord(pVM, PageRec.pPageGC, PageRec.enmTag, PageRec.fCode32,
     764                                                     PageRec.fMonitorInvalidation);
     765            AssertReturn(pPage, VERR_NO_MEMORY);
     766            pPage->GCPhys  = PageRec.GCPhys;
     767            pPage->fFlags  = PageRec.fFlags;
     768            pPage->u64Hash = PageRec.u64Hash;
     769            if (PageRec.pBitmap)
    640770            {
    641                 Log(("MMHyperAlloc failed with %Rrc\n", rc));
    642                 return rc;
    643             }
    644             /* Convert to GC pointer. */
    645             pVM->csam.s.pPDGCBitmapHC[i] = MMHyperR3ToRC(pVM, pVM->csam.s.pPDBitmapHC[i]);
    646             Assert(pVM->csam.s.pPDGCBitmapHC[i]);
    647 
    648             /* Restore the bitmap. */
    649             rc = SSMR3GetMem(pSSM, pVM->csam.s.pPDBitmapHC[i], CSAM_PAGE_BITMAP_SIZE);
     771                rc = SSMR3GetMem(pSSM, pPage->pBitmap, CSAM_PAGE_BITMAP_SIZE);
     772                AssertLogRelRCReturn(rc, rc);
     773            }
     774            else
     775            {
     776                MMR3HeapFree(pPage->pBitmap);
     777                pPage->pBitmap = NULL;
     778            }
     779        }
     780    }
     781    else
     782    {
     783        /*
     784         * Restore the old SSMR3PutMem fashioned state.
     785         */
     786
     787        /* CSAM structure first. */
     788        CSAM csamInfo;
     789        RT_ZERO(csamInfo);
     790        if (   SSMR3HandleVersion(pSSM)  >= VBOX_FULL_VERSION_MAKE(4, 3, 51)
     791            && SSMR3HandleRevision(pSSM) >= 100346)
     792            rc = SSMR3GetStructEx(pSSM, &csamInfo, sizeof(csamInfo), SSMSTRUCT_FLAGS_MEM_BAND_AID,
     793                                  &g_aCsamFields500[0], NULL);
     794        else
     795            rc = SSMR3GetStructEx(pSSM, &csamInfo, sizeof(csamInfo), SSMSTRUCT_FLAGS_MEM_BAND_AID_RELAXED,
     796                                  &g_aCsamFieldsBefore500[0], NULL);
     797        AssertRCReturn(rc, rc);
     798
     799        pVM->csam.s.fGatesChecked    = csamInfo.fGatesChecked;
     800        pVM->csam.s.fScanningStarted = csamInfo.fScanningStarted;
     801
     802         /* Restore dirty code page info. */
     803        pVM->csam.s.cDirtyPages = csamInfo.cDirtyPages;
     804        memcpy(pVM->csam.s.pvDirtyBasePage,  csamInfo.pvDirtyBasePage, sizeof(pVM->csam.s.pvDirtyBasePage));
     805        memcpy(pVM->csam.s.pvDirtyFaultPage, csamInfo.pvDirtyFaultPage, sizeof(pVM->csam.s.pvDirtyFaultPage));
     806
     807         /* Restore possible code page  */
     808        pVM->csam.s.cPossibleCodePages = csamInfo.cPossibleCodePages;
     809        memcpy(pVM->csam.s.pvPossibleCodePage,  csamInfo.pvPossibleCodePage, sizeof(pVM->csam.s.pvPossibleCodePage));
     810
     811        /*
     812         * Restore pgdir bitmap (we'll change the pointers next).
     813         */
     814        rc = SSMR3GetStructEx(pSSM, pVM->csam.s.pPDBitmapHC, sizeof(uint8_t *) * CSAM_PGDIRBMP_CHUNKS,
     815                              SSMSTRUCT_FLAGS_MEM_BAND_AID_RELAXED, &g_aCsamPDBitmapArray[0], NULL);
     816        AssertRCReturn(rc, rc);
     817
     818        /*
     819         * Restore page bitmaps
     820         */
     821        for (unsigned i = 0; i < CSAM_PGDIRBMP_CHUNKS; i++)
     822            if (pVM->csam.s.pPDBitmapHC[i])
     823            {
     824                rc = MMHyperAlloc(pVM, CSAM_PAGE_BITMAP_SIZE, 0, MM_TAG_CSAM, (void **)&pVM->csam.s.pPDBitmapHC[i]);
     825                AssertLogRelRCReturn(rc, rc);
     826                pVM->csam.s.pPDGCBitmapHC[i] = MMHyperR3ToRC(pVM, pVM->csam.s.pPDBitmapHC[i]);
     827
     828                /* Restore the bitmap. */
     829                rc = SSMR3GetMem(pSSM, pVM->csam.s.pPDBitmapHC[i], CSAM_PAGE_BITMAP_SIZE);
     830                AssertRCReturn(rc, rc);
     831            }
     832            else
     833            {
     834                Assert(!pVM->csam.s.pPDGCBitmapHC[i]);
     835                pVM->csam.s.pPDGCBitmapHC[i] = 0;
     836            }
     837
     838        /*
     839         * Restore page records
     840         */
     841        for (uint32_t i=0;i<csamInfo.savedstate.cPageRecords + csamInfo.savedstate.cPatchPageRecords;i++)
     842        {
     843            CSAMPAGEREC  page;
     844            PCSAMPAGE    pPage;
     845
     846            RT_ZERO(page);
     847            rc = SSMR3GetStructEx(pSSM, &page, sizeof(page), SSMSTRUCT_FLAGS_MEM_BAND_AID_RELAXED, &g_aCsamPageRecFields[0], NULL);
    650848            AssertRCReturn(rc, rc);
    651         }
    652         else
    653         {
    654             Assert(!pVM->csam.s.pPDGCBitmapHC[i]);
    655             pVM->csam.s.pPDGCBitmapHC[i] = 0;
    656         }
    657     }
    658 
    659     /*
    660      * Restore page records
    661      */
    662     for (uint32_t i=0;i<csamInfo.savedstate.cPageRecords + csamInfo.savedstate.cPatchPageRecords;i++)
    663     {
    664         CSAMPAGEREC  page;
    665         PCSAMPAGE    pPage;
    666 
    667         RT_ZERO(page);
    668         rc = SSMR3GetStructEx(pSSM, &page, sizeof(page), SSMSTRUCT_FLAGS_MEM_BAND_AID_RELAXED, &g_aCsamPageRecFields[0], NULL);
    669         AssertRCReturn(rc, rc);
    670 
    671         /*
    672          * Recreate the page record
    673          */
    674         pPage = csamCreatePageRecord(pVM, page.page.pPageGC, page.page.enmTag, page.page.fCode32, page.page.fMonitorInvalidation);
    675         AssertReturn(pPage, VERR_NO_MEMORY);
    676 
    677         pPage->GCPhys  = page.page.GCPhys;
    678         pPage->fFlags  = page.page.fFlags;
    679         pPage->u64Hash = page.page.u64Hash;
    680 
    681         if (page.page.pBitmap)
    682         {
    683             rc = SSMR3GetMem(pSSM, pPage->pBitmap, CSAM_PAGE_BITMAP_SIZE);
    684             AssertRCReturn(rc, rc);
    685         }
    686         else
    687         {
    688             MMR3HeapFree(pPage->pBitmap);
    689             pPage->pBitmap = 0;
    690         }
    691     }
    692 
    693     /* Note: we don't restore aDangerousInstr; it will be recreated automatically. */
    694     memset(&pVM->csam.s.aDangerousInstr, 0, sizeof(pVM->csam.s.aDangerousInstr));
    695     pVM->csam.s.cDangerousInstr = 0;
    696     pVM->csam.s.iDangerousInstr  = 0;
     849
     850            /*
     851             * Recreate the page record
     852             */
     853            pPage = csamR3CreatePageRecord(pVM, page.page.pPageGC, page.page.enmTag, page.page.fCode32, page.page.fMonitorInvalidation);
     854            AssertReturn(pPage, VERR_NO_MEMORY);
     855
     856            pPage->GCPhys  = page.page.GCPhys;
     857            pPage->fFlags  = page.page.fFlags;
     858            pPage->u64Hash = page.page.u64Hash;
     859
     860            if (page.page.pBitmap)
     861            {
     862                rc = SSMR3GetMem(pSSM, pPage->pBitmap, CSAM_PAGE_BITMAP_SIZE);
     863                AssertRCReturn(rc, rc);
     864            }
     865            else
     866            {
     867                MMR3HeapFree(pPage->pBitmap);
     868                pPage->pBitmap = NULL;
     869            }
     870        }
     871
     872        /* Note: we don't restore aDangerousInstr; it will be recreated automatically. */
     873        memset(&pVM->csam.s.aDangerousInstr, 0, sizeof(pVM->csam.s.aDangerousInstr));
     874        pVM->csam.s.cDangerousInstr = 0;
     875        pVM->csam.s.iDangerousInstr = 0;
     876    }
    697877    return VINF_SUCCESS;
    698878}
     
    11171297            {
    11181298                /* New address; let's take a look at it. */
    1119                 pPage = csamCreatePageRecord(pVM, pCurInstrGC, CSAM_TAG_CSAM, fCode32);
     1299                pPage = csamR3CreatePageRecord(pVM, pCurInstrGC, CSAM_TAG_CSAM, fCode32);
    11201300                if (pPage == NULL)
    11211301                {
     
    13301510            {
    13311511                /* New address; let's take a look at it. */
    1332                 pPage = csamCreatePageRecord(pVM, pCurInstrGC, CSAM_TAG_CSAM, fCode32);
     1512                pPage = csamR3CreatePageRecord(pVM, pCurInstrGC, CSAM_TAG_CSAM, fCode32);
    13331513                if (pPage == NULL)
    13341514                {
     
    14621642                {
    14631643                    /* New branch target; let's take a look at it. */
    1464                     pJmpPage = csamCreatePageRecord(pVM, addr, CSAM_TAG_CSAM, fCode32);
     1644                    pJmpPage = csamR3CreatePageRecord(pVM, addr, CSAM_TAG_CSAM, fCode32);
    14651645                    if (pJmpPage == NULL)
    14661646                    {
     
    15281708                        {
    15291709                            /* New branch target; let's take a look at it. */
    1530                             pJmpPage = csamCreatePageRecord(pVM, addr, CSAM_TAG_CSAM, fCode32);
     1710                            pJmpPage = csamR3CreatePageRecord(pVM, addr, CSAM_TAG_CSAM, fCode32);
    15311711                            if (pJmpPage == NULL)
    15321712                            {
     
    18332013 * @param   fMonitorInvalidation    Monitor page invalidation flag
    18342014 */
    1835 static PCSAMPAGE csamCreatePageRecord(PVM pVM, RTRCPTR GCPtr, CSAMTAG enmTag, bool fCode32, bool fMonitorInvalidation)
     2015static PCSAMPAGE csamR3CreatePageRecord(PVM pVM, RTRCPTR GCPtr, CSAMTAG enmTag, bool fCode32, bool fMonitorInvalidation)
    18362016{
    18372017    PCSAMPAGEREC pPage;
     
    18462026    if (pPage == NULL)
    18472027    {
    1848         AssertMsgFailed(("csamCreatePageRecord: Out of memory!!!!\n"));
     2028        AssertMsgFailed(("csamR3CreatePageRecord: Out of memory!!!!\n"));
    18492029        return NULL;
    18502030    }
     
    19022082    }
    19032083
    1904     Log(("csamCreatePageRecord %RRv GCPhys=%RGp\n", GCPtr, pPage->page.GCPhys));
     2084    Log(("csamR3CreatePageRecord %RRv GCPhys=%RGp\n", GCPtr, pPage->page.GCPhys));
    19052085
    19062086# ifdef VBOX_WITH_STATISTICS
     
    19752155        }
    19762156
    1977         csamCreatePageRecord(pVM, pPageAddrGC, enmTag, true /* 32 bits code */, fMonitorInvalidation);
     2157        csamR3CreatePageRecord(pVM, pPageAddrGC, enmTag, true /* 32 bits code */, fMonitorInvalidation);
    19782158
    19792159        pPageRec = (PCSAMPAGEREC)RTAvlPVGet(&pVM->csam.s.pPageTree, (AVLPVKEY)(uintptr_t)pPageAddrGC);
  • trunk/src/VBox/VMM/include/CSAMInternal.h

    r56287 r57008  
    3939/** @} */
    4040
    41 #define CSAM_SAVED_STATE_VERSION                14
     41#define CSAM_SAVED_STATE_VERSION                CSAM_SAVED_STATE_VERSION_PUT_STRUCT
     42#define CSAM_SAVED_STATE_VERSION_PUT_STRUCT     15
     43#define CSAM_SAVED_STATE_VERSION_PUT_MEM        14
    4244
    4345#define CSAM_PGDIRBMP_CHUNKS                    1024
Note: See TracChangeset for help on using the changeset viewer.

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