VirtualBox

Changeset 23415 in vbox


Ignore:
Timestamp:
Sep 29, 2009 3:40:39 PM (15 years ago)
Author:
vboxsync
Message:

PGM: Saved state hacking and some minor cleanups.

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/Makefile.kmk

    r23307 r23415  
    5454ifdef VBOX_WITH_PDM_ASYNC_COMPLETION
    5555 VMMR3_DEFS    += VBOX_WITH_PDM_ASYNC_COMPLETION
     56endif
     57ifdef VBOX_WITH_LIVE_MIGRATION
     58 VMMR3_DEFS    += VBOX_WITH_LIVE_MIGRATION
    5659endif
    5760VMMR3_DEFS.darwin = VMM_R0_SWITCH_STACK
  • trunk/src/VBox/VMM/PGMInternal.h

    r23398 r23415  
    687687        (pPage)->fSomethingElse = 0; \
    688688        (pPage)->idPageX        = (_idPage); \
    689         /*(pPage)->u3Type         = (_uType); - later */ \
    690         PGM_PAGE_SET_TYPE(pPage, _uType); \
     689        (pPage)->u3Type         = (_uType); \
    691690        (pPage)->u29B           = 0; \
    692691    } while (0)
     
    697696 */
    698697#define PGM_PAGE_INIT_ZERO(pPage, pVM, _uType)  \
    699     PGM_PAGE_INIT(pPage, (pVM)->pgm.s.HCPhysZeroPg, NIL_GMM_PAGEID, (_uType), PGM_PAGE_STATE_ZERO)
    700 /** Temporary hack. Replaced by PGM_PAGE_INIT_ZERO once the old code is kicked out. */
    701 # define PGM_PAGE_INIT_ZERO_REAL(pPage, pVM, _uType)  \
    702698    PGM_PAGE_INIT(pPage, (pVM)->pgm.s.HCPhysZeroPg, NIL_GMM_PAGEID, (_uType), PGM_PAGE_STATE_ZERO)
    703699
     
    11921188 *
    11931189 * There are a few reason why we need to keep track of these
    1194  * registrations. One of them is the deregistration & cleanup
    1195  * stuff, while another is that the PGMRAMRANGE associated with
    1196  * such a region may have to be removed from the ram range list.
    1197  *
    1198  * Overlapping with a RAM range has to be 100% or none at all. The
    1199  * pages in the existing RAM range must not be ROM nor MMIO. A guru
    1200  * meditation will be raised if a partial overlap or an overlap of
    1201  * ROM pages is encountered. On an overlap we will free all the
    1202  * existing RAM pages and put in the ram range pages instead.
     1190 * registrations.  One of them is the deregistration & cleanup stuff,
     1191 * while another is that the PGMRAMRANGE associated with such a region may
     1192 * have to be removed from the ram range list.
     1193 *
     1194 * Overlapping with a RAM range has to be 100% or none at all.  The pages
     1195 * in the existing RAM range must not be ROM nor MMIO.  A guru meditation
     1196 * will be raised if a partial overlap or an overlap of ROM pages is
     1197 * encountered.  On an overlap we will free all the existing RAM pages and
     1198 * put in the ram range pages instead.
    12031199 */
    12041200typedef struct PGMMMIO2RANGE
     
    26082604        /** The number of monitored pages. */
    26092605        uint32_t                    cMonitoredPages;
     2606        /** Indicates that a live save operation is active.  */
     2607        bool                        fActive;
     2608        /** Padding. */
     2609        bool                        afReserved[7];
    26102610    } LiveSave;
    26112611
  • trunk/src/VBox/VMM/PGMPhys.cpp

    r23398 r23415  
    13351335        uint32_t iPage = cPages;
    13361336        while (iPage-- > 0)
    1337             PGM_PAGE_INIT_ZERO_REAL(&pNew->aPages[iPage], pVM, PGMPAGETYPE_MMIO);
     1337            PGM_PAGE_INIT_ZERO(&pNew->aPages[iPage], pVM, PGMPAGETYPE_MMIO);
    13381338        Assert(PGM_PAGE_GET_TYPE(&pNew->aPages[0]) == PGMPAGETYPE_MMIO);
    13391339
     
    23542354                        PPGMROMPAGE pPage = &pRomNew->aPages[iPage];
    23552355                        pPage->enmProt = PGMROMPROT_READ_ROM_WRITE_IGNORE;
    2356                         PGM_PAGE_INIT_ZERO_REAL(&pPage->Shadow, pVM, PGMPAGETYPE_ROM_SHADOW);
     2356                        PGM_PAGE_INIT_ZERO(&pPage->Shadow, pVM, PGMPAGETYPE_ROM_SHADOW);
    23572357                    }
    23582358
  • trunk/src/VBox/VMM/PGMSavedState.cpp

    r23398 r23415  
    176176
    177177/**
    178  * Save zero indicator + bits for the specified page.
    179  *
    180  * @returns VBox status code, errors are logged/asserted before returning.
    181  * @param   pVM         The VM handle.
    182  * @param   pSSH        The saved state handle.
    183  * @param   pPage       The page to save.
    184  * @param   GCPhys      The address of the page.
    185  * @param   pRam        The ram range (for error logging).
    186  */
    187 static int pgmR3SavePage(PVM pVM, PSSMHANDLE pSSM, PPGMPAGE pPage, RTGCPHYS GCPhys, PPGMRAMRANGE pRam)
    188 {
    189     int rc;
    190     if (PGM_PAGE_IS_ZERO(pPage))
    191         rc = SSMR3PutU8(pSSM, 0);
    192     else
    193     {
    194         void const *pvPage;
    195         rc = pgmPhysGCPhys2CCPtrInternalReadOnly(pVM, pPage, GCPhys, &pvPage);
    196         AssertLogRelMsgRCReturn(rc, ("pPage=%R[pgmpage] GCPhys=%#x %s\n", pPage, GCPhys, pRam->pszDesc), rc);
    197 
    198         SSMR3PutU8(pSSM, 1);
    199         rc = SSMR3PutMem(pSSM, pvPage, PAGE_SIZE);
    200     }
    201     return rc;
    202 }
    203 
    204 
    205 /**
    206  * Save a shadowed ROM page.
    207  *
    208  * Format: Type, protection, and two pages with zero indicators.
    209  *
    210  * @returns VBox status code, errors are logged/asserted before returning.
    211  * @param   pVM         The VM handle.
    212  * @param   pSSH        The saved state handle.
    213  * @param   pPage       The page to save.
    214  * @param   GCPhys      The address of the page.
    215  * @param   pRam        The ram range (for error logging).
    216  */
    217 static int pgmR3SaveShadowedRomPage(PVM pVM, PSSMHANDLE pSSM, PPGMPAGE pPage, RTGCPHYS GCPhys, PPGMRAMRANGE pRam)
    218 {
    219     /* Need to save both pages and the current state. */
    220     PPGMROMPAGE pRomPage = pgmR3GetRomPage(pVM, GCPhys);
    221     AssertLogRelMsgReturn(pRomPage, ("GCPhys=%RGp %s\n", GCPhys, pRam->pszDesc), VERR_INTERNAL_ERROR);
    222 
    223     SSMR3PutU8(pSSM, PGMPAGETYPE_ROM_SHADOW);
    224     SSMR3PutU8(pSSM, pRomPage->enmProt);
    225 
    226     int rc = pgmR3SavePage(pVM, pSSM, pPage, GCPhys, pRam);
    227     if (RT_SUCCESS(rc))
    228     {
    229         PPGMPAGE pPagePassive = PGMROMPROT_IS_ROM(pRomPage->enmProt) ? &pRomPage->Shadow : &pRomPage->Virgin;
    230         rc = pgmR3SavePage(pVM, pSSM, pPagePassive, GCPhys, pRam);
    231     }
    232     return rc;
    233 }
    234 
    235 
    236 /**
    237178 * Prepare for a live save operation.
    238179 *
     
    267208    pVM->pgm.s.LiveSave.cDirtyPages = 0;
    268209    pVM->pgm.s.LiveSave.cMmioPages  = 0;
     210    pVM->pgm.s.LiveSave.fActive     = true;
    269211
    270212    /*
     
    512454                    /* Process the page. */
    513455                    if (paLSPages[iPage].fMmio)
     456                        continue;
     457                    switch (PGM_PAGE_GET_TYPE(&pCur->aPages[iPage]))
    514458                    {
    515                         switch (PGM_PAGE_GET_TYPE(&pCur->aPages[iPage]))
     459                        case PGMPAGETYPE_RAM:
    516460                        {
    517                             case PGMPAGETYPE_RAM:
     461                            switch (PGM_PAGE_GET_STATE(&pCur->aPages[iPage]))
    518462                            {
    519                                 switch (PGM_PAGE_GET_STATE(&pCur->aPages[iPage]))
    520                                 {
    521                                     case PGM_PAGE_STATE_ALLOCATED:
    522                                         /** @todo Optimize this: Don't always re-enable write
    523                                          * monitoring if the page is known to be very busy. */
    524                                         if (PGM_PAGE_IS_WRITTEN_TO(&pCur->aPages[iPage]))
    525                                         {
    526                                             Assert(paLSPages[iPage].fWriteMonitored);
    527                                             PGM_PAGE_CLEAR_WRITTEN_TO(&pCur->aPages[iPage]);
    528                                             Assert(pVM->pgm.s.cWrittenToPages > 0);
    529                                             pVM->pgm.s.cWrittenToPages--;
    530                                         }
    531                                         else
    532                                         {
    533                                             Assert(!paLSPages[iPage].fWriteMonitored);
    534                                             pVM->pgm.s.LiveSave.cMonitoredPages++;
    535                                         }
    536 
    537                                         if (!paLSPages[iPage].fDirty)
    538                                         {
    539                                             pVM->pgm.s.LiveSave.cDirtyPages++;
    540                                             pVM->pgm.s.LiveSave.cReadyPages--;
    541                                             if (++paLSPages[iPage].cDirtied > PGMLIVSAVEPAGE_MAX_DIRTIED)
    542                                                 paLSPages[iPage].cDirtied = PGMLIVSAVEPAGE_MAX_DIRTIED;
    543                                         }
    544 
    545                                         PGM_PAGE_SET_STATE(&pCur->aPages[iPage], PGM_PAGE_STATE_WRITE_MONITORED);
    546                                         pVM->pgm.s.cMonitoredPages++;
    547                                         paLSPages[iPage].fWriteMonitored        = 1;
    548                                         paLSPages[iPage].fWriteMonitoredJustNow = 1;
    549                                         paLSPages[iPage].fDirty                 = 1;
    550                                         paLSPages[iPage].fZero                  = 0;
    551                                         paLSPages[iPage].fShared                = 0;
    552                                         break;
    553 
    554                                     case PGM_PAGE_STATE_WRITE_MONITORED:
     463                                case PGM_PAGE_STATE_ALLOCATED:
     464                                    /** @todo Optimize this: Don't always re-enable write
     465                                     * monitoring if the page is known to be very busy. */
     466                                    if (PGM_PAGE_IS_WRITTEN_TO(&pCur->aPages[iPage]))
     467                                    {
    555468                                        Assert(paLSPages[iPage].fWriteMonitored);
    556                                         paLSPages[iPage].fWriteMonitoredJustNow = 0;
    557                                         break;
    558 
    559                                     case PGM_PAGE_STATE_ZERO:
    560                                         if (!paLSPages[iPage].fZero)
    561                                         {
    562                                             paLSPages[iPage].fZero = 1;
    563                                             paLSPages[iPage].fShared = 0;
    564                                             if (!paLSPages[iPage].fDirty)
    565                                             {
    566                                                 paLSPages[iPage].fDirty = 1;
    567                                                 pVM->pgm.s.LiveSave.cReadyPages--;
    568                                                 pVM->pgm.s.LiveSave.cDirtyPages++;
    569                                             }
    570                                         }
    571                                         break;
    572 
    573                                     case PGM_PAGE_STATE_SHARED:
    574                                         if (!paLSPages[iPage].fShared)
    575                                         {
    576                                             paLSPages[iPage].fZero = 0;
    577                                             paLSPages[iPage].fShared = 1;
    578                                             if (!paLSPages[iPage].fDirty)
    579                                             {
    580                                                 paLSPages[iPage].fDirty = 1;
    581                                                 pVM->pgm.s.LiveSave.cReadyPages--;
    582                                                 pVM->pgm.s.LiveSave.cDirtyPages++;
    583                                             }
    584                                         }
    585                                         break;
    586                                 }
    587                                 break;
    588                             }
    589 
    590                             /* All writes to the shadow page are intercepted. */
    591                             case PGMPAGETYPE_ROM_SHADOW: /* (The shadow page is active.) */
    592                             case PGMPAGETYPE_ROM:        /* (The virgin page is active.) */
    593                             {
    594                                 PPGMROMPAGE pRomPage = pgmR3GetRomPage(pVM, pCur->GCPhys + ((RTGCPHYS)iPage << PAGE_SHIFT));
    595                                 if (!pRomPage->LiveSave.fDone)
    596                                 {
    597                                     if (pRomPage->LiveSave.fWrittenTo)
     469                                        PGM_PAGE_CLEAR_WRITTEN_TO(&pCur->aPages[iPage]);
     470                                        Assert(pVM->pgm.s.cWrittenToPages > 0);
     471                                        pVM->pgm.s.cWrittenToPages--;
     472                                    }
     473                                    else
    598474                                    {
    599                                         pRomPage->LiveSave.fWrittenTo = false;
     475                                        Assert(!paLSPages[iPage].fWriteMonitored);
     476                                        pVM->pgm.s.LiveSave.cMonitoredPages++;
     477                                    }
     478
     479                                    if (!paLSPages[iPage].fDirty)
     480                                    {
     481                                        pVM->pgm.s.LiveSave.cDirtyPages++;
     482                                        pVM->pgm.s.LiveSave.cReadyPages--;
     483                                        if (++paLSPages[iPage].cDirtied > PGMLIVSAVEPAGE_MAX_DIRTIED)
     484                                            paLSPages[iPage].cDirtied = PGMLIVSAVEPAGE_MAX_DIRTIED;
     485                                    }
     486
     487                                    PGM_PAGE_SET_STATE(&pCur->aPages[iPage], PGM_PAGE_STATE_WRITE_MONITORED);
     488                                    pVM->pgm.s.cMonitoredPages++;
     489                                    paLSPages[iPage].fWriteMonitored        = 1;
     490                                    paLSPages[iPage].fWriteMonitoredJustNow = 1;
     491                                    paLSPages[iPage].fDirty                 = 1;
     492                                    paLSPages[iPage].fZero                  = 0;
     493                                    paLSPages[iPage].fShared                = 0;
     494                                    break;
     495
     496                                case PGM_PAGE_STATE_WRITE_MONITORED:
     497                                    Assert(paLSPages[iPage].fWriteMonitored);
     498                                    paLSPages[iPage].fWriteMonitoredJustNow = 0;
     499                                    break;
     500
     501                                case PGM_PAGE_STATE_ZERO:
     502                                    if (!paLSPages[iPage].fZero)
     503                                    {
     504                                        paLSPages[iPage].fZero = 1;
     505                                        paLSPages[iPage].fShared = 0;
    600506                                        if (!paLSPages[iPage].fDirty)
    601507                                        {
     
    604510                                            pVM->pgm.s.LiveSave.cDirtyPages++;
    605511                                        }
    606                                         paLSPages[iPage].fWriteMonitoredJustNow = 1;
    607512                                    }
    608                                     else
    609                                         paLSPages[iPage].fWriteMonitoredJustNow = 0;
    610                                     paLSPages[iPage].fWriteMonitored = 1;
     513                                    break;
     514
     515                                case PGM_PAGE_STATE_SHARED:
     516                                    if (!paLSPages[iPage].fShared)
     517                                    {
     518                                        paLSPages[iPage].fZero = 0;
     519                                        paLSPages[iPage].fShared = 1;
     520                                        if (!paLSPages[iPage].fDirty)
     521                                        {
     522                                            paLSPages[iPage].fDirty = 1;
     523                                            pVM->pgm.s.LiveSave.cReadyPages--;
     524                                            pVM->pgm.s.LiveSave.cDirtyPages++;
     525                                        }
     526                                    }
     527                                    break;
     528                            }
     529                            break;
     530                        }
     531
     532                        /* All writes to the shadow page are intercepted. */
     533                        case PGMPAGETYPE_ROM_SHADOW: /* (The shadow page is active.) */
     534                        case PGMPAGETYPE_ROM:        /* (The virgin page is active.) */
     535                        {
     536                            PPGMROMPAGE pRomPage = pgmR3GetRomPage(pVM, pCur->GCPhys + ((RTGCPHYS)iPage << PAGE_SHIFT));
     537                            if (!pRomPage->LiveSave.fDone)
     538                            {
     539                                if (pRomPage->LiveSave.fWrittenTo)
     540                                {
     541                                    pRomPage->LiveSave.fWrittenTo = false;
     542                                    if (!paLSPages[iPage].fDirty)
     543                                    {
     544                                        paLSPages[iPage].fDirty = 1;
     545                                        pVM->pgm.s.LiveSave.cReadyPages--;
     546                                        pVM->pgm.s.LiveSave.cDirtyPages++;
     547                                    }
     548                                    paLSPages[iPage].fWriteMonitoredJustNow = 1;
    611549                                }
    612550                                else
     551                                    paLSPages[iPage].fWriteMonitoredJustNow = 0;
     552                                paLSPages[iPage].fWriteMonitored = 1;
     553                            }
     554                            else
     555                            {
     556                                Assert(PGM_PAGE_GET_TYPE(&pCur->aPages[iPage]) == PGMPAGETYPE_ROM);
     557                                Assert(!paLSPages[iPage].fDirty);
     558                            }
     559                            break;
     560                        }
     561
     562                        default:
     563                            AssertMsgFailed(("%R[pgmpage]", &pCur->aPages[iPage]));
     564                        case PGMPAGETYPE_MMIO2:
     565                        case PGMPAGETYPE_MMIO2_ALIAS_MMIO:
     566                        case PGMPAGETYPE_MMIO:
     567                            if (PGM_PAGE_GET_TYPE(&pCur->aPages[iPage]) == PGMPAGETYPE_MMIO)
     568                            {
     569                                paLSPages[iPage].fZero  = 0;
     570                                paLSPages[iPage].fDirty = 1;
     571                                paLSPages[iPage].fMmio  = 1;
     572                            }
     573                            else
     574                            {
     575                                paLSPages[iPage].fZero  = 1;
     576                                paLSPages[iPage].fDirty = 1;
     577                                paLSPages[iPage].fMmio  = 1;
     578                            }
     579                            if (paLSPages[iPage].fWriteMonitored)
     580                            {
     581                                if (RT_UNLIKELY(PGM_PAGE_GET_STATE(&pCur->aPages[iPage]) == PGM_PAGE_STATE_WRITE_MONITORED))
    613582                                {
    614                                     Assert(PGM_PAGE_GET_TYPE(&pCur->aPages[iPage]) == PGMPAGETYPE_ROM);
    615                                     Assert(!paLSPages[iPage].fDirty);
     583                                    AssertMsgFailed(("%R[pgmpage]", &pCur->aPages[iPage])); /* shouldn't happen. */
     584                                    PGM_PAGE_SET_STATE(&pCur->aPages[iPage], PGM_PAGE_STATE_ALLOCATED);
     585                                    Assert(pVM->pgm.s.cMonitoredPages > 0);
     586                                    pVM->pgm.s.cMonitoredPages--;
    616587                                }
    617                                 break;
     588                                if (PGM_PAGE_IS_WRITTEN_TO(&pCur->aPages[iPage]))
     589                                {
     590                                    PGM_PAGE_CLEAR_WRITTEN_TO(&pCur->aPages[iPage]);
     591                                    Assert(pVM->pgm.s.cWrittenToPages > 0);
     592                                    pVM->pgm.s.cWrittenToPages--;
     593                                }
     594                                pVM->pgm.s.LiveSave.cMonitoredPages--;
    618595                            }
    619 
    620                             default:
    621                                 AssertMsgFailed(("%R[pgmpage]", &pCur->aPages[iPage]));
    622                             case PGMPAGETYPE_MMIO2:
    623                             case PGMPAGETYPE_MMIO2_ALIAS_MMIO:
    624                             case PGMPAGETYPE_MMIO:
    625                                 if (PGM_PAGE_GET_TYPE(&pCur->aPages[iPage]) == PGMPAGETYPE_MMIO)
    626                                 {
    627                                     paLSPages[iPage].fZero  = 0;
    628                                     paLSPages[iPage].fDirty = 1;
    629                                     paLSPages[iPage].fMmio  = 1;
    630                                 }
    631                                 else
    632                                 {
    633                                     paLSPages[iPage].fZero  = 1;
    634                                     paLSPages[iPage].fDirty = 1;
    635                                     paLSPages[iPage].fMmio  = 1;
    636                                 }
    637                                 if (paLSPages[iPage].fWriteMonitored)
    638                                 {
    639                                     if (RT_UNLIKELY(PGM_PAGE_GET_STATE(&pCur->aPages[iPage]) == PGM_PAGE_STATE_WRITE_MONITORED))
    640                                     {
    641                                         AssertMsgFailed(("%R[pgmpage]", &pCur->aPages[iPage])); /* shouldn't happen. */
    642                                         PGM_PAGE_SET_STATE(&pCur->aPages[iPage], PGM_PAGE_STATE_ALLOCATED);
    643                                         Assert(pVM->pgm.s.cMonitoredPages > 0);
    644                                         pVM->pgm.s.cMonitoredPages--;
    645                                     }
    646                                     if (PGM_PAGE_IS_WRITTEN_TO(&pCur->aPages[iPage]))
    647                                     {
    648                                         PGM_PAGE_CLEAR_WRITTEN_TO(&pCur->aPages[iPage]);
    649                                         Assert(pVM->pgm.s.cWrittenToPages > 0);
    650                                         pVM->pgm.s.cWrittenToPages--;
    651                                     }
    652                                     pVM->pgm.s.LiveSave.cMonitoredPages--;
    653                                 }
    654                                 pVM->pgm.s.LiveSave.cMmioPages++;
    655                                 break;
    656                         }
    657                     }
     596                            pVM->pgm.s.LiveSave.cMmioPages++;
     597                            break;
     598                    } /* switch on page type */
    658599                } /* for each page in range */
    659600
     
    868809}
    869810
     811#ifdef VBOX_WITH_LIVE_MIGRATION
     812
     813/**
     814 * Worker for pgmR3SaveExec that saves the memory.
     815 *
     816 * @returns VBox status code.
     817 *
     818 * @param   pVM         The VM handle.
     819 * @param   pSSM        The SSM handle.
     820 * @param   fLiveSave   Whether we're in a live save or not.
     821 *
     822 */
     823static int pgmR3SaveExecMemory(PVM pVM, PSSMHANDLE pSSM, bool fLiveSave)
     824{
     825    /*
     826     * Save all ROM pages.
     827     */
     828
     829    /*
     830     * Save all MMIO2 pages (including unmapped ones).
     831     */
     832
     833    /*
     834     * Save all normal RAM pages.
     835     */
     836    return VINF_SUCCESS;
     837}
     838
     839#else /* !VBOX_WITH_LIVE_MIGRATION */
     840
     841/**
     842 * Save zero indicator + bits for the specified page.
     843 *
     844 * @returns VBox status code, errors are logged/asserted before returning.
     845 * @param   pVM         The VM handle.
     846 * @param   pSSH        The saved state handle.
     847 * @param   pPage       The page to save.
     848 * @param   GCPhys      The address of the page.
     849 * @param   pRam        The ram range (for error logging).
     850 */
     851static int pgmR3SavePage(PVM pVM, PSSMHANDLE pSSM, PPGMPAGE pPage, RTGCPHYS GCPhys, PPGMRAMRANGE pRam)
     852{
     853    int rc;
     854    if (PGM_PAGE_IS_ZERO(pPage))
     855        rc = SSMR3PutU8(pSSM, 0);
     856    else
     857    {
     858        void const *pvPage;
     859        rc = pgmPhysGCPhys2CCPtrInternalReadOnly(pVM, pPage, GCPhys, &pvPage);
     860        AssertLogRelMsgRCReturn(rc, ("pPage=%R[pgmpage] GCPhys=%#x %s\n", pPage, GCPhys, pRam->pszDesc), rc);
     861
     862        SSMR3PutU8(pSSM, 1);
     863        rc = SSMR3PutMem(pSSM, pvPage, PAGE_SIZE);
     864    }
     865    return rc;
     866}
     867
     868
     869/**
     870 * Save a shadowed ROM page.
     871 *
     872 * Format: Type, protection, and two pages with zero indicators.
     873 *
     874 * @returns VBox status code, errors are logged/asserted before returning.
     875 * @param   pVM         The VM handle.
     876 * @param   pSSH        The saved state handle.
     877 * @param   pPage       The page to save.
     878 * @param   GCPhys      The address of the page.
     879 * @param   pRam        The ram range (for error logging).
     880 */
     881static int pgmR3SaveShadowedRomPage(PVM pVM, PSSMHANDLE pSSM, PPGMPAGE pPage, RTGCPHYS GCPhys, PPGMRAMRANGE pRam)
     882{
     883    /* Need to save both pages and the current state. */
     884    PPGMROMPAGE pRomPage = pgmR3GetRomPage(pVM, GCPhys);
     885    AssertLogRelMsgReturn(pRomPage, ("GCPhys=%RGp %s\n", GCPhys, pRam->pszDesc), VERR_INTERNAL_ERROR);
     886
     887    SSMR3PutU8(pSSM, PGMPAGETYPE_ROM_SHADOW);
     888    SSMR3PutU8(pSSM, pRomPage->enmProt);
     889
     890    int rc = pgmR3SavePage(pVM, pSSM, pPage, GCPhys, pRam);
     891    if (RT_SUCCESS(rc))
     892    {
     893        PPGMPAGE pPagePassive = PGMROMPROT_IS_ROM(pRomPage->enmProt) ? &pRomPage->Shadow : &pRomPage->Virgin;
     894        rc = pgmR3SavePage(pVM, pSSM, pPagePassive, GCPhys, pRam);
     895    }
     896    return rc;
     897}
     898
     899#endif /* !VBOX_WITH_LIVE_MIGRATION */
    870900
    871901/**
     
    912942    rc = SSMR3PutU32(pSSM, ~0); /* terminator. */
    913943
     944#ifdef VBOX_WITH_LIVE_MIGRATION
     945    /*
     946     * Save the (remainder of the) memory.
     947     */
     948    if (RT_SUCCESS(rc))
     949    {
     950        if (pVM->pgm.s.LiveSave.fActive)
     951            pgmR3LiveExecPart1(pVM);
     952        rc = pgmR3SaveExecMemory(pVM, pSSM, pVM->pgm.s.LiveSave.fActive);
     953    }
     954
     955#else /* !VBOX_WITH_LIVE_MIGRATION */
    914956    /*
    915957     * Ram ranges and the memory they describe.
     
    938980            uint8_t  uType      = PGM_PAGE_GET_TYPE(pPage);
    939981
    940             if (uType == PGMPAGETYPE_ROM_SHADOW)
     982            if (uType == PGMPAGETYPE_ROM_SHADOW) /** @todo This isn't right, but it doesn't currently matter. */
    941983                rc = pgmR3SaveShadowedRomPage(pVM, pSSM, pPage, GCPhysPage, pRam);
    942984            else if (uType == PGMPAGETYPE_MMIO2_ALIAS_MMIO)
     
    9581000    }
    9591001
     1002    rc = SSMR3PutU32(pSSM, ~0); /* terminator. */
     1003#endif /* !VBOX_WITH_LIVE_MIGRATION */
     1004
    9601005    pgmUnlock(pVM);
    961     return SSMR3PutU32(pSSM, ~0); /* terminator. */
     1006    return rc;
    9621007}
    9631008
     
    10191064    } while (pCur);
    10201065
     1066    pVM->pgm.s.LiveSave.fActive = false;
     1067
    10211068    /** @todo this is blindly assuming that we're the only user of write
    10221069     *        monitoring. Fix this when more users are added. */
     
    10321079
    10331080/**
    1034  * Worker for pgmR3Load and pgmR3LoadLocked.
     1081 * Prepare state load operation.
    10351082 *
    10361083 * @returns VBox status code.
    1037  *
    1038  * @param   pVM                 The VM handle.
    1039  * @param   pSSM                The SSM handle.
    1040  * @param   uVersion            The saved state version.
    1041  */
    1042 static int pgmR3LoadLockedMemory(PVM pVM, PSSMHANDLE pSSM, uint32_t uPass)
    1043 {
    1044     /*
    1045      * Process page records until we hit the terminator.
    1046      */
    1047     PPGMRAMRANGE    pRamHint   = NULL;
    1048     RTGCPHYS        GCPhysLast = NIL_RTGCPHYS;
    1049     for (;;)
    1050     {
    1051         /* Get the record type and flags. */
    1052         uint8_t u8;
    1053         int rc = SSMR3GetU8(pSSM, &u8);
    1054         if (RT_FAILURE(rc))
    1055             return rc;
    1056         if (u8 == PGM_STATE_REC_END)
    1057             return VINF_SUCCESS;
    1058         AssertLogRelMsgReturn((u8 & ~PGM_STATE_REC_FLAG_ADDR) <= PGM_STATE_REC_LAST, ("%#x\n", u8), VERR_SSM_DATA_UNIT_FORMAT_CHANGED);
    1059 
    1060         /* Get the address. */
    1061         RTGCPHYS GCPhys;
    1062         if (!(u8 & PGM_STATE_REC_FLAG_ADDR))
    1063         {
    1064             AssertLogRelReturn(GCPhysLast != NIL_RTGCPHYS, VERR_SSM_DATA_UNIT_FORMAT_CHANGED);
    1065             GCPhys = GCPhysLast + PAGE_SIZE;
    1066         }
    1067         else
    1068         {
    1069             rc = SSMR3GetGCPhys(pSSM, &GCPhys);
    1070             if (RT_FAILURE(rc))
    1071                 return rc;
    1072             AssertLogRelMsgReturn(GCPhys & PAGE_OFFSET_MASK, ("%RGp\n", GCPhys), VERR_SSM_DATA_UNIT_FORMAT_CHANGED);
    1073         }
    1074 
    1075         /* Get the ram range and page. */
    1076         PPGMPAGE pPage;
    1077         rc = pgmPhysGetPageWithHintEx(&pVM->pgm.s, GCPhys, &pPage, &pRamHint);
    1078         AssertLogRelMsgRCReturn(rc, ("rc=%Rrc %RGp\n", rc, GCPhys), rc);
    1079 
    1080         /*
    1081          * Take action according to the record type.
    1082          */
    1083         switch (u8 & ~PGM_STATE_REC_FLAG_ADDR)
    1084         {
    1085             case PGM_STATE_REC_ZERO:
    1086             {
    1087                 if (PGM_PAGE_IS_ZERO(pPage))
    1088                     break;
    1089                 /** @todo implement zero page replacing. */
    1090                 AssertLogRelMsgReturn(PGM_PAGE_GET_STATE(pPage) == PGM_PAGE_STATE_ALLOCATED, ("GCPhys=%RGp %R[pgmpage]\n", GCPhys, pPage), VERR_INTERNAL_ERROR_5);
    1091                 void *pvDstPage;
    1092                 rc = pgmPhysGCPhys2CCPtrInternal(pVM, pPage, GCPhys, &pvDstPage);
    1093                 AssertLogRelMsgRCReturn(rc, ("GCPhys=%RGp %R[pgmpage] rc=%Rrc\n", GCPhys, pPage, rc), rc);
    1094                 ASMMemZeroPage(pvDstPage);
    1095                 break;
    1096             }
    1097 
    1098             case PGM_STATE_REC_RAW:
    1099             {
    1100                 void *pvDstPage;
    1101                 rc = pgmPhysGCPhys2CCPtrInternal(pVM, pPage, GCPhys, &pvDstPage);
    1102                 AssertLogRelMsgRCReturn(rc, ("GCPhys=%RGp %R[pgmpage] rc=%Rrc\n", GCPhys, pPage, rc), rc);
    1103                 rc = SSMR3GetMem(pSSM, pvDstPage, PAGE_SIZE);
    1104                 if (RT_FAILURE(rc))
    1105                     return rc;
    1106                 break;
    1107             }
    1108 
    1109             case PGM_STATE_REC_ROM_VIRGIN:
    1110             case PGM_STATE_REC_ROM_SHADOW:
    1111             case PGM_STATE_REC_ROM_SHADOW_ZERO:
    1112             case PGM_STATE_REC_ROM_PROT:
    1113             {
    1114                 PPGMROMPAGE pRomPage = pgmR3GetRomPage(pVM, GCPhys);
    1115                 AssertLogRelMsgReturn(pRomPage, ("GCPhys=%RGp\n", GCPhys), VERR_INTERNAL_ERROR);
    1116 
    1117                 uint8_t u8Prot;
    1118                 rc = SSMR3GetU8(pSSM, &u8Prot);
    1119                 if (RT_FAILURE(rc))
    1120                     return rc;
    1121                 PGMROMPROT enmProt = (PGMROMPROT)u8Prot;
    1122                 AssertLogRelMsgReturn(enmProt > PGMROMPROT_INVALID && enmProt < PGMROMPROT_END, ("GCPhys=%RGp enmProt=%d\n", GCPhys, enmProt), VERR_INTERNAL_ERROR);
    1123 
    1124                 /* Make the protection change. */
    1125                 if (enmProt != pRomPage->enmProt)
    1126                 {
    1127                     rc = PGMR3PhysRomProtect(pVM, GCPhys, PAGE_SIZE, enmProt);
    1128                     AssertLogRelMsgRCReturn(rc, ("GCPhys=%RGp rc=%Rrc\n", GCPhys, rc), rc);
    1129                     AssertLogRelReturn(pRomPage->enmProt == enmProt, VERR_INTERNAL_ERROR);
    1130                 }
    1131 
    1132                 /* Get the right page descriptor. */
    1133                 PPGMPAGE pRealPage;
    1134                 switch (u8 & ~PGM_STATE_REC_FLAG_ADDR)
    1135                 {
    1136                     case PGM_STATE_REC_ROM_VIRGIN:
    1137                         if (!PGMROMPROT_IS_ROM(enmProt))
    1138                             pRealPage = &pRomPage->Virgin;
    1139                         else
    1140                             pRealPage = pPage;
    1141                         break;
    1142 
    1143                     case PGM_STATE_REC_ROM_SHADOW:
    1144                     case PGM_STATE_REC_ROM_SHADOW_ZERO:
    1145                         if (PGMROMPROT_IS_ROM(enmProt))
    1146                             pRealPage = &pRomPage->Shadow;
    1147                         else
    1148                             pRealPage = pPage;
    1149                         break;
    1150 
    1151                     case PGM_STATE_REC_ROM_PROT:
    1152                         pRealPage = NULL;
    1153                         break;
    1154 
    1155                     default:
    1156                         AssertMsgFailedReturn(("%#x\n", u8), VERR_INTERNAL_ERROR);
    1157                 }
    1158 
    1159                 /* Map it if necessary. */
    1160                 void *pvDstPage = NULL;
    1161                 switch (u8 & ~PGM_STATE_REC_FLAG_ADDR)
    1162                 {
    1163                     case PGM_STATE_REC_ROM_SHADOW_ZERO:
    1164                         if (PGM_PAGE_IS_ZERO(pRealPage))
    1165                             break;
    1166                         /** @todo implement zero page replacing. */
    1167                         /* fall thru */
    1168                     case PGM_STATE_REC_ROM_VIRGIN:
    1169                     case PGM_STATE_REC_ROM_SHADOW:
    1170                     {
    1171                         if (RT_UNLIKELY(PGM_PAGE_GET_STATE(pRealPage) != PGM_PAGE_STATE_ALLOCATED))
    1172                         {
    1173                             rc = pgmPhysPageMakeWritable(pVM, pRealPage, GCPhys);
    1174                             AssertLogRelMsgRCReturn(rc, ("GCPhys=%RGp rc=%Rrc\n", GCPhys, rc), rc);
    1175                         }
    1176                         PPGMPAGEMAP pMapIgnored;
    1177                         rc = pgmPhysPageMap(pVM, pRealPage, GCPhys, &pMapIgnored, &pvDstPage);
    1178                         AssertLogRelMsgRCReturn(rc, ("GCPhys=%RGp rc=%Rrc\n", GCPhys, rc), rc);
    1179                         break;
    1180                     }
    1181 
    1182                     case PGM_STATE_REC_ROM_PROT:
    1183                         break;
    1184                 }
    1185 
    1186                 /* Load the bits. */
    1187                 switch (u8 & ~PGM_STATE_REC_FLAG_ADDR)
    1188                 {
    1189                     case PGM_STATE_REC_ROM_SHADOW_ZERO:
    1190                         if (pvDstPage)
    1191                             ASMMemZeroPage(pvDstPage);
    1192                         break;
    1193 
    1194                     case PGM_STATE_REC_ROM_VIRGIN:
    1195                     case PGM_STATE_REC_ROM_SHADOW:
    1196                     {
    1197                         rc = SSMR3GetMem(pSSM, pvDstPage, PAGE_SIZE);
    1198                         if (RT_FAILURE(rc))
    1199                             return rc;
    1200                         break;
    1201                     }
    1202 
    1203                     case PGM_STATE_REC_ROM_PROT:
    1204                         break;
    1205                 }
    1206                 break;
    1207             }
    1208 
    1209             default:
    1210                 AssertMsgFailedReturn(("%#x\n", u8), VERR_INTERNAL_ERROR);
    1211         }
    1212     }
     1084 * @param   pVM             VM Handle.
     1085 * @param   pSSM            SSM operation handle.
     1086 */
     1087static DECLCALLBACK(int) pgmR3LoadPrep(PVM pVM, PSSMHANDLE pSSM)
     1088{
     1089    /*
     1090     * Call the reset function to make sure all the memory is cleared.
     1091     */
     1092    PGMR3Reset(pVM);
     1093    NOREF(pSSM);
     1094    return VINF_SUCCESS;
    12131095}
    12141096
     
    12201102 * @param   pSSM            The saved state handle.
    12211103 */
    1222 static int pgmR3LoadPageToDevNull(PSSMHANDLE pSSM)
     1104static int pgmR3LoadPageToDevNullOld(PSSMHANDLE pSSM)
    12231105{
    12241106    uint8_t abPage[PAGE_SIZE];
     
    12391121 * @param   pRam            The ram range (logging).
    12401122 */
    1241 static int pgmR3LoadPageZero(PVM pVM, uint8_t uType, PPGMPAGE pPage, RTGCPHYS GCPhys, PPGMRAMRANGE pRam)
     1123static int pgmR3LoadPageZeroOld(PVM pVM, uint8_t uType, PPGMPAGE pPage, RTGCPHYS GCPhys, PPGMRAMRANGE pRam)
    12421124{
    12431125    if (    PGM_PAGE_GET_TYPE(pPage) != uType
     
    12681150 * @param   pRam            The ram range (logging).
    12691151 */
    1270 static int pgmR3LoadPageBits(PVM pVM, PSSMHANDLE pSSM, uint8_t uType, PPGMPAGE pPage, RTGCPHYS GCPhys, PPGMRAMRANGE pRam)
     1152static int pgmR3LoadPageBitsOld(PVM pVM, PSSMHANDLE pSSM, uint8_t uType, PPGMPAGE pPage, RTGCPHYS GCPhys, PPGMRAMRANGE pRam)
    12711153{
    12721154    int rc;
     
    13031185 * @param   pRam            The RAM range (for error messages).
    13041186 */
    1305 static int pgmR3LoadPage(PVM pVM, PSSMHANDLE pSSM, uint8_t uType, PPGMPAGE pPage, RTGCPHYS GCPhys, PPGMRAMRANGE pRam)
     1187static int pgmR3LoadPageOld(PVM pVM, PSSMHANDLE pSSM, uint8_t uType, PPGMPAGE pPage, RTGCPHYS GCPhys, PPGMRAMRANGE pRam)
    13061188{
    13071189    uint8_t         uState;
     
    13091191    AssertLogRelMsgRCReturn(rc, ("pPage=%R[pgmpage] GCPhys=%#x %s rc=%Rrc\n", pPage, GCPhys, pRam->pszDesc, rc), rc);
    13101192    if (uState == 0 /* zero */)
    1311         rc = pgmR3LoadPageZero(pVM, uType, pPage, GCPhys, pRam);
     1193        rc = pgmR3LoadPageZeroOld(pVM, uType, pPage, GCPhys, pRam);
    13121194    else if (uState == 1)
    1313         rc = pgmR3LoadPageBits(pVM, pSSM, uType, pPage, GCPhys, pRam);
     1195        rc = pgmR3LoadPageBitsOld(pVM, pSSM, uType, pPage, GCPhys, pRam);
    13141196    else
    13151197        rc = VERR_INTERNAL_ERROR;
     
    13311213 * @param   pRam            The RAM range (for error messages).
    13321214 */
    1333 static int pgmR3LoadShadowedRomPage(PVM pVM, PSSMHANDLE pSSM, PPGMPAGE pPage, RTGCPHYS GCPhys, PPGMRAMRANGE pRam)
     1215static int pgmR3LoadShadowedRomPageOld(PVM pVM, PSSMHANDLE pSSM, PPGMPAGE pPage, RTGCPHYS GCPhys, PPGMRAMRANGE pRam)
    13341216{
    13351217    /*
     
    13611243    uint8_t  u8PassiveType= PGMROMPROT_IS_ROM(enmProt) ? PGMPAGETYPE_ROM_SHADOW : PGMPAGETYPE_ROM;
    13621244
    1363     rc = pgmR3LoadPage(pVM, pSSM, u8ActiveType, pPage, GCPhys, pRam);
     1245    /** @todo this isn't entirely correct as long as pgmPhysGCPhys2CCPtrInternal is
     1246     *        used down the line (will the 2nd page will be written to the first
     1247     *        one because of a false TLB hit since the TLB is using GCPhys and
     1248     *        doesn't check the HCPhys of the desired page). */
     1249    rc = pgmR3LoadPageOld(pVM, pSSM, u8ActiveType, pPage, GCPhys, pRam);
    13641250    if (RT_SUCCESS(rc))
    13651251    {
    13661252        *pPageActive = *pPage;
    1367         rc = pgmR3LoadPage(pVM, pSSM, u8PassiveType, pPagePassive, GCPhys, pRam);
     1253        rc = pgmR3LoadPageOld(pVM, pSSM, u8PassiveType, pPagePassive, GCPhys, pRam);
    13681254    }
    13691255    return rc;
     
    13791265 * @param   uVersion    The saved state version.
    13801266 */
    1381 static int pgmR3LoadLockedMemoryOld(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion)
     1267static int pgmR3LoadMemoryOld(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion)
    13821268{
    13831269    PPGM pPGM = &pVM->pgm.s;
     
    14841370                AssertLogRelMsgRCReturn(rc, ("pPage=%R[pgmpage] iPage=%#x GCPhysPage=%#x %s\n", pPage, iPage, GCPhysPage, pRam->pszDesc), rc);
    14851371                if (uType == PGMPAGETYPE_ROM_SHADOW)
    1486                     rc = pgmR3LoadShadowedRomPage(pVM, pSSM, pPage, GCPhysPage, pRam);
     1372                    rc = pgmR3LoadShadowedRomPageOld(pVM, pSSM, pPage, GCPhysPage, pRam);
    14871373                else
    1488                     rc = pgmR3LoadPage(pVM, pSSM, uType, pPage, GCPhysPage, pRam);
     1374                    rc = pgmR3LoadPageOld(pVM, pSSM, uType, pPage, GCPhysPage, pRam);
    14891375                AssertLogRelMsgRCReturn(rc, ("rc=%Rrc iPage=%#x GCPhysPage=%#x %s\n", rc, iPage, GCPhysPage, pRam->pszDesc), rc);
    14901376            }
     
    15361422                        {
    15371423                            if (PGM_PAGE_GET_TYPE(pPage) == PGMPAGETYPE_MMIO)
    1538                                 rc = pgmR3LoadPageToDevNull(pSSM);
     1424                                rc = pgmR3LoadPageToDevNullOld(pSSM);
    15391425                            else
    1540                                 rc = pgmR3LoadPageBits(pVM, pSSM, PGMPAGETYPE_INVALID, pPage, GCPhysPage, pRam);
     1426                                rc = pgmR3LoadPageBitsOld(pVM, pSSM, PGMPAGETYPE_INVALID, pPage, GCPhysPage, pRam);
    15411427                        }
    15421428                        else
    1543                             rc = pgmR3LoadPageZero(pVM, PGMPAGETYPE_INVALID, pPage, GCPhysPage, pRam);
     1429                            rc = pgmR3LoadPageZeroOld(pVM, PGMPAGETYPE_INVALID, pPage, GCPhysPage, pRam);
    15441430                        AssertLogRelMsgRCReturn(rc, ("rc=%Rrc iPage=%#x GCPhysPage=%#x %s\n", rc, iPage, GCPhysPage, pRam->pszDesc), rc);
    15451431                    }
     
    15851471                while (GCPhys < pRam->GCPhys)
    15861472                {
    1587                     rc = pgmR3LoadPageToDevNull(pSSM);
     1473                    rc = pgmR3LoadPageToDevNullOld(pSSM);
    15881474                    GCPhys += PAGE_SIZE;
    15891475                }
     
    15991485                                          ("GCPhys=%RGp pPage=%R[pgmpage]\n", GCPhys, GCPhys),
    16001486                                          VERR_SSM_DATA_UNIT_FORMAT_CHANGED);
    1601                     rc = pgmR3LoadPageBits(pVM, pSSM, PGMPAGETYPE_ROM, pPage, GCPhysPage, pRam);
     1487                    rc = pgmR3LoadPageBitsOld(pVM, pSSM, PGMPAGETYPE_ROM, pPage, GCPhysPage, pRam);
    16021488                    AssertLogRelMsgRCReturn(rc, ("rc=%Rrc iPage=%#x GCPhys=%#x %s\n", rc, iPage, pRam->GCPhys, pRam->pszDesc), rc);
    16031489                }
     
    16071493
    16081494    return VINF_SUCCESS;
     1495}
     1496
     1497
     1498/**
     1499 * Worker for pgmR3Load and pgmR3LoadLocked.
     1500 *
     1501 * @returns VBox status code.
     1502 *
     1503 * @param   pVM                 The VM handle.
     1504 * @param   pSSM                The SSM handle.
     1505 * @param   uVersion            The saved state version.
     1506 */
     1507static int pgmR3LoadMemory(PVM pVM, PSSMHANDLE pSSM, uint32_t uPass)
     1508{
     1509    /*
     1510     * Process page records until we hit the terminator.
     1511     */
     1512    PPGMRAMRANGE    pRamHint   = NULL;
     1513    RTGCPHYS        GCPhysLast = NIL_RTGCPHYS;
     1514    for (;;)
     1515    {
     1516        /* Get the record type and flags. */
     1517        uint8_t u8;
     1518        int rc = SSMR3GetU8(pSSM, &u8);
     1519        if (RT_FAILURE(rc))
     1520            return rc;
     1521        if (u8 == PGM_STATE_REC_END)
     1522            return VINF_SUCCESS;
     1523        AssertLogRelMsgReturn((u8 & ~PGM_STATE_REC_FLAG_ADDR) <= PGM_STATE_REC_LAST, ("%#x\n", u8), VERR_SSM_DATA_UNIT_FORMAT_CHANGED);
     1524
     1525        /* Get the address. */
     1526        RTGCPHYS GCPhys;
     1527        if (!(u8 & PGM_STATE_REC_FLAG_ADDR))
     1528        {
     1529            AssertLogRelReturn(GCPhysLast != NIL_RTGCPHYS, VERR_SSM_DATA_UNIT_FORMAT_CHANGED);
     1530            GCPhys = GCPhysLast + PAGE_SIZE;
     1531        }
     1532        else
     1533        {
     1534            rc = SSMR3GetGCPhys(pSSM, &GCPhys);
     1535            if (RT_FAILURE(rc))
     1536                return rc;
     1537            AssertLogRelMsgReturn(GCPhys & PAGE_OFFSET_MASK, ("%RGp\n", GCPhys), VERR_SSM_DATA_UNIT_FORMAT_CHANGED);
     1538        }
     1539
     1540        /* Get the ram range and page. */
     1541        PPGMPAGE pPage;
     1542        rc = pgmPhysGetPageWithHintEx(&pVM->pgm.s, GCPhys, &pPage, &pRamHint);
     1543        AssertLogRelMsgRCReturn(rc, ("rc=%Rrc %RGp\n", rc, GCPhys), rc);
     1544
     1545        /*
     1546         * Take action according to the record type.
     1547         */
     1548        switch (u8 & ~PGM_STATE_REC_FLAG_ADDR)
     1549        {
     1550            case PGM_STATE_REC_ZERO:
     1551            {
     1552                if (PGM_PAGE_IS_ZERO(pPage))
     1553                    break;
     1554                /** @todo implement zero page replacing. */
     1555                AssertLogRelMsgReturn(PGM_PAGE_GET_STATE(pPage) == PGM_PAGE_STATE_ALLOCATED, ("GCPhys=%RGp %R[pgmpage]\n", GCPhys, pPage), VERR_INTERNAL_ERROR_5);
     1556                void *pvDstPage;
     1557                rc = pgmPhysGCPhys2CCPtrInternal(pVM, pPage, GCPhys, &pvDstPage);
     1558                AssertLogRelMsgRCReturn(rc, ("GCPhys=%RGp %R[pgmpage] rc=%Rrc\n", GCPhys, pPage, rc), rc);
     1559                ASMMemZeroPage(pvDstPage);
     1560                break;
     1561            }
     1562
     1563            case PGM_STATE_REC_RAW:
     1564            {
     1565                void *pvDstPage;
     1566                rc = pgmPhysGCPhys2CCPtrInternal(pVM, pPage, GCPhys, &pvDstPage);
     1567                AssertLogRelMsgRCReturn(rc, ("GCPhys=%RGp %R[pgmpage] rc=%Rrc\n", GCPhys, pPage, rc), rc);
     1568                rc = SSMR3GetMem(pSSM, pvDstPage, PAGE_SIZE);
     1569                if (RT_FAILURE(rc))
     1570                    return rc;
     1571                break;
     1572            }
     1573
     1574            case PGM_STATE_REC_ROM_VIRGIN:
     1575            case PGM_STATE_REC_ROM_SHADOW:
     1576            case PGM_STATE_REC_ROM_SHADOW_ZERO:
     1577            case PGM_STATE_REC_ROM_PROT:
     1578            {
     1579                PPGMROMPAGE pRomPage = pgmR3GetRomPage(pVM, GCPhys);
     1580                AssertLogRelMsgReturn(pRomPage, ("GCPhys=%RGp\n", GCPhys), VERR_INTERNAL_ERROR);
     1581
     1582                uint8_t u8Prot;
     1583                rc = SSMR3GetU8(pSSM, &u8Prot);
     1584                if (RT_FAILURE(rc))
     1585                    return rc;
     1586                PGMROMPROT enmProt = (PGMROMPROT)u8Prot;
     1587                AssertLogRelMsgReturn(enmProt > PGMROMPROT_INVALID && enmProt < PGMROMPROT_END, ("GCPhys=%RGp enmProt=%d\n", GCPhys, enmProt), VERR_INTERNAL_ERROR);
     1588
     1589                /* Make the protection change. */
     1590                if (enmProt != pRomPage->enmProt)
     1591                {
     1592                    rc = PGMR3PhysRomProtect(pVM, GCPhys, PAGE_SIZE, enmProt);
     1593                    AssertLogRelMsgRCReturn(rc, ("GCPhys=%RGp rc=%Rrc\n", GCPhys, rc), rc);
     1594                    AssertLogRelReturn(pRomPage->enmProt == enmProt, VERR_INTERNAL_ERROR);
     1595                }
     1596                if ((u8 & ~PGM_STATE_REC_FLAG_ADDR) == PGM_STATE_REC_ROM_PROT)
     1597                    break; /* done */
     1598
     1599                /* Get the right page descriptor. */
     1600                PPGMPAGE pRealPage;
     1601                switch (u8 & ~PGM_STATE_REC_FLAG_ADDR)
     1602                {
     1603                    case PGM_STATE_REC_ROM_VIRGIN:
     1604                        if (!PGMROMPROT_IS_ROM(enmProt))
     1605                            pRealPage = &pRomPage->Virgin;
     1606                        else
     1607                            pRealPage = pPage;
     1608                        break;
     1609
     1610                    case PGM_STATE_REC_ROM_SHADOW:
     1611                    case PGM_STATE_REC_ROM_SHADOW_ZERO:
     1612                        if (PGMROMPROT_IS_ROM(enmProt))
     1613                            pRealPage = &pRomPage->Shadow;
     1614                        else
     1615                            pRealPage = pPage;
     1616                        break;
     1617                }
     1618
     1619                /* Map it if necessary. */
     1620                void *pvDstPage = NULL;
     1621                switch (u8 & ~PGM_STATE_REC_FLAG_ADDR)
     1622                {
     1623                    case PGM_STATE_REC_ROM_SHADOW_ZERO:
     1624                        if (PGM_PAGE_IS_ZERO(pRealPage))
     1625                            break;
     1626                        /** @todo implement zero page replacing. */
     1627                        /* fall thru */
     1628                    case PGM_STATE_REC_ROM_VIRGIN:
     1629                    case PGM_STATE_REC_ROM_SHADOW:
     1630                    {
     1631                        if (RT_UNLIKELY(PGM_PAGE_GET_STATE(pRealPage) != PGM_PAGE_STATE_ALLOCATED))
     1632                        {
     1633                            rc = pgmPhysPageMakeWritable(pVM, pRealPage, GCPhys);
     1634                            AssertLogRelMsgRCReturn(rc, ("GCPhys=%RGp rc=%Rrc\n", GCPhys, rc), rc);
     1635                        }
     1636                        PPGMPAGEMAP pMapIgnored;
     1637                        rc = pgmPhysPageMap(pVM, pRealPage, GCPhys, &pMapIgnored, &pvDstPage);
     1638                        AssertLogRelMsgRCReturn(rc, ("GCPhys=%RGp rc=%Rrc\n", GCPhys, rc), rc);
     1639                        break;
     1640                    }
     1641                }
     1642
     1643                /* Load the bits. */
     1644                switch (u8 & ~PGM_STATE_REC_FLAG_ADDR)
     1645                {
     1646                    case PGM_STATE_REC_ROM_SHADOW_ZERO:
     1647                        if (pvDstPage)
     1648                            ASMMemZeroPage(pvDstPage);
     1649                        break;
     1650
     1651                    case PGM_STATE_REC_ROM_VIRGIN:
     1652                    case PGM_STATE_REC_ROM_SHADOW:
     1653                        rc = SSMR3GetMem(pSSM, pvDstPage, PAGE_SIZE);
     1654                        if (RT_FAILURE(rc))
     1655                            return rc;
     1656                        break;
     1657                }
     1658                break;
     1659            }
     1660
     1661            default:
     1662                AssertMsgFailedReturn(("%#x\n", u8), VERR_INTERNAL_ERROR);
     1663        }
     1664    }
    16091665}
    16101666
     
    17431799     */
    17441800    if (uVersion > PGM_SAVED_STATE_VERSION_3_0_0)
    1745         return pgmR3LoadLockedMemory(pVM, pSSM, SSM_PASS_FINAL);
    1746     return pgmR3LoadLockedMemoryOld(pVM, pSSM, uVersion);
    1747 }
    1748 
    1749 
    1750 /**
    1751  * Prepare state load operation.
    1752  *
    1753  * @returns VBox status code.
    1754  * @param   pVM             VM Handle.
    1755  * @param   pSSM            SSM operation handle.
    1756  */
    1757 static DECLCALLBACK(int) pgmR3LoadPrep(PVM pVM, PSSMHANDLE pSSM)
    1758 {
    1759     /*
    1760      * Call the reset function to make sure all the memory is cleared.
    1761      */
    1762     PGMR3Reset(pVM);
    1763     NOREF(pSSM);
    1764     return VINF_SUCCESS;
     1801        return pgmR3LoadMemory(pVM, pSSM, SSM_PASS_FINAL);
     1802    return pgmR3LoadMemoryOld(pVM, pSSM, uVersion);
    17651803}
    17661804
     
    18031841         */
    18041842        pgmLock(pVM);
    1805         rc = pgmR3LoadLockedMemory(pVM, pSSM, uPass);
     1843        rc = pgmR3LoadMemory(pVM, pSSM, uPass);
    18061844        pgmUnlock(pVM);
    18071845    }
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