PGMSavedState.cpp revision bc13a205575fcbcf95893fc09c9c33a30c7fd53f
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * PGM - Page Manager and Monitor, The Saved State Part.
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * Copyright (C) 2006-2009 Sun Microsystems, Inc.
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * available from http://www.virtualbox.org. This file is free software;
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * you can redistribute it and/or modify it under the terms of the GNU
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * General Public License (GPL) as published by the Free Software
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * additional information or have any questions.
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync/*******************************************************************************
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync* Header Files *
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync*******************************************************************************/
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync/*******************************************************************************
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync* Defined Constants And Macros *
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync*******************************************************************************/
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync/** Saved state data unit version. */
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync/** Saved state data unit version for 3.0. (pre live migration) */
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync/** Saved state data unit version for 2.2.2 and later. */
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync/** Saved state data unit version for 2.2.0. */
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync/** Saved state data unit version. */
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync/** @name Sparse state record types
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync/** Zero page. No data. */
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync/** Raw page. */
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync/** Virgin ROM page. Followed by protection (8-bit) and the raw bits. */
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync/** Raw shadowed ROM page. The protection (8-bit) preceeds the raw bits. */
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync/** Zero shadowed ROM page. The protection (8-bit) is the only payload. */
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync/** ROM protection (8-bit). */
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync/** The last record type. */
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync/** End marker. */
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync/** Flag indicating that the data is preceeded by an RTGCPHYS containing the
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * page address. If not set, the page follows the immediately after the
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * previous one. */
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync/*******************************************************************************
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync* Structures and Typedefs *
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync*******************************************************************************/
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync/** For loading old saved states. (pre-smp) */
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsynctypedef struct
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync /** If set no conflict checks are required. (boolean) */
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync /** Size of fixed mapping */
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync /** Base address (GC) of fixed mapping */
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync /** A20 gate mask.
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * Our current approach to A20 emulation is to let REM do it and don't bother
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * anywhere else. The interesting Guests will be operating with it enabled anyway.
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * But whould need arrise, we'll subject physical addresses to this mask. */
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync /** A20 gate state - boolean! */
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync /** The guest paging mode. */
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync/*******************************************************************************
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync* Global Variables *
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync*******************************************************************************/
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync/** PGM fields to save/load. */
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * Find the ROM tracking structure for the given page.
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * @returns Pointer to the ROM page structure. NULL if the caller didn't check
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * that it's a ROM page.
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * @param pVM The VM handle.
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * @param GCPhys The address of the ROM page.
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsyncstatic PPGMROMPAGE pgmR3GetRomPage(PVM pVM, RTGCPHYS GCPhys) /** @todo change this to take a hint. */
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync for (PPGMROMRANGE pRomRange = pVM->pgm.s.CTX_SUFF(pRomRanges);
static int pgmR3SavePage(PVM pVM, PSSMHANDLE pSSM, PPGMPAGE pPage, RTGCPHYS GCPhys, PPGMRAMRANGE pRam)
int rc;
void const *pvPage;
AssertLogRelMsgRCReturn(rc, ("pPage=%R[pgmpage] GCPhys=%#x %s\n", pPage, GCPhys, pRam->pszDesc), rc);
return rc;
static int pgmR3SaveShadowedRomPage(PVM pVM, PSSMHANDLE pSSM, PPGMPAGE pPage, RTGCPHYS GCPhys, PPGMRAMRANGE pRam)
PPGMPAGE pPagePassive = PGMROMPROT_IS_ROM(pRomPage->enmProt) ? &pRomPage->Shadow : &pRomPage->Virgin;
return rc;
PPGMLIVESAVEPAGE paLSPages = (PPGMLIVESAVEPAGE)MMR3HeapAllocZ(pVM, MM_TAG_PGM, cPages * sizeof(PGMLIVESAVEPAGE));
if (!paLSPages)
return VERR_NO_MEMORY;
while (iPage-- > 0)
case PGMPAGETYPE_RAM:
case PGMPAGETYPE_ROM_SHADOW:
case PGMPAGETYPE_ROM:
case PGMPAGETYPE_MMIO2:
case PGMPAGETYPE_MMIO:
} while (pCur);
return VINF_SUCCESS;
void *pvPage;
return rc;
return VINF_SUCCESS;
GCPhysCur = 0;
case PGMPAGETYPE_RAM:
case PGM_PAGE_STATE_ALLOCATED:
case PGM_PAGE_STATE_ZERO:
case PGM_PAGE_STATE_SHARED:
case PGMPAGETYPE_MMIO2:
case PGMPAGETYPE_MMIO:
if (GCPhysCur != 0)
} while (pCur);
GCPhysCur = 0;
int rc;
void const *pvPage;
if (!fZero)
void *pvPage;
SSMR3PutU8(pSSM, (fZero ? PGM_STATE_REC_ROM_SHADOW_ZERO : PGM_STATE_REC_ROM_SHADOW) | PGM_STATE_REC_FLAG_ADDR);
if (!fZero)
return rc;
if (GCPhysCur != 0)
} while (pCur);
return VINF_SUCCESS;
if (uPass == 0)
return rc;
return VINF_SUCCESS;
int rc;
if (pvToFree)
while (iPage--)
} while (pCur);
return VINF_SUCCESS;
return rc;
return VINF_SUCCESS;
AssertLogRelMsgReturn((u8 & ~PGM_STATE_REC_FLAG_ADDR) <= PGM_STATE_REC_LAST, ("%#x\n", u8), VERR_SSM_DATA_UNIT_FORMAT_CHANGED);
return rc;
AssertLogRelMsgReturn(GCPhys & PAGE_OFFSET_MASK, ("%RGp\n", GCPhys), VERR_SSM_DATA_UNIT_FORMAT_CHANGED);
case PGM_STATE_REC_ZERO:
AssertLogRelMsgReturn(PGM_PAGE_GET_STATE(pPage) == PGM_PAGE_STATE_ALLOCATED, ("GCPhys=%RGp %R[pgmpage]\n", GCPhys, pPage), VERR_INTERNAL_ERROR_5);
void *pvDstPage;
case PGM_STATE_REC_RAW:
void *pvDstPage;
return rc;
case PGM_STATE_REC_ROM_VIRGIN:
case PGM_STATE_REC_ROM_SHADOW:
case PGM_STATE_REC_ROM_PROT:
return rc;
AssertLogRelMsgReturn(enmProt > PGMROMPROT_INVALID && enmProt < PGMROMPROT_END, ("GCPhys=%RGp enmProt=%d\n", GCPhys, enmProt), VERR_INTERNAL_ERROR);
case PGM_STATE_REC_ROM_VIRGIN:
case PGM_STATE_REC_ROM_SHADOW:
case PGM_STATE_REC_ROM_PROT:
case PGM_STATE_REC_ROM_VIRGIN:
case PGM_STATE_REC_ROM_SHADOW:
case PGM_STATE_REC_ROM_PROT:
if (pvDstPage)
case PGM_STATE_REC_ROM_VIRGIN:
case PGM_STATE_REC_ROM_SHADOW:
return rc;
case PGM_STATE_REC_ROM_PROT:
static int pgmR3LoadPageZero(PVM pVM, uint8_t uType, PPGMPAGE pPage, RTGCPHYS GCPhys, PPGMRAMRANGE pRam)
return VERR_SSM_UNEXPECTED_DATA;
return VERR_SSM_UNEXPECTED_DATA;
return VINF_SUCCESS;
static int pgmR3LoadPageBits(PVM pVM, PSSMHANDLE pSSM, uint8_t uType, PPGMPAGE pPage, RTGCPHYS GCPhys, PPGMRAMRANGE pRam)
int rc;
void *pvPage;
return rc;
static int pgmR3LoadPage(PVM pVM, PSSMHANDLE pSSM, uint8_t uType, PPGMPAGE pPage, RTGCPHYS GCPhys, PPGMRAMRANGE pRam)
AssertLogRelMsgRCReturn(rc, ("pPage=%R[pgmpage] GCPhys=%#x %s rc=%Rrc\n", pPage, GCPhys, pRam->pszDesc, rc), rc);
rc);
return VINF_SUCCESS;
static int pgmR3LoadShadowedRomPage(PVM pVM, PSSMHANDLE pSSM, PPGMPAGE pPage, RTGCPHYS GCPhys, PPGMRAMRANGE pRam)
AssertLogRelMsgRCReturn(rc, ("pPage=%R[pgmpage] GCPhys=%#x %s\n", pPage, GCPhys, pRam->pszDesc), rc);
return rc;
uint32_t i = 0;
return rc;
if (u32Sep == ~0U)
if (u32Sep != i)
return rc;
return rc;
|| ( cchDesc
|| !fHaveBits)
AssertLogRelMsgRCReturn(rc, ("pPage=%R[pgmpage] iPage=%#x GCPhysPage=%#x %s\n", pPage, iPage, GCPhysPage, pRam->pszDesc), rc);
AssertLogRelMsgRCReturn(rc, ("rc=%Rrc iPage=%#x GCPhysPage=%#x %s\n", rc, iPage, GCPhysPage, pRam->pszDesc), rc);
AssertLogRelMsgRCReturn(rc, ("rc=%Rrc iPage=%#x GCPhys=%#x %s\n", rc, iPage, pRam->GCPhys, pRam->pszDesc), rc);
if ( !fHaveBits
AssertLogRelMsgRCReturn(rc, ("rc=%Rrc iPage=%#x GCPhys=%#x %s\n", rc, iPage, pRam->GCPhys, pRam->pszDesc), rc);
if (fPresent)
AssertLogRelMsgRCReturn(rc, ("rc=%Rrc iPage=%#x GCPhysPage=%#x %s\n", rc, iPage, GCPhysPage, pRam->pszDesc), rc);
AssertLogRelMsgRCReturn(rc, ("rc=%Rrc iPage=%#x GCPhys=%#x %s\n", rc, iPage, pRam->GCPhys, pRam->pszDesc), rc);
return VINF_SUCCESS;
int rc;
return rc;
return rc;
uint32_t i = 0;
return rc;
if (u32Sep == ~0U)
if (u32Sep != i)
return rc;
return rc;
return VINF_SUCCESS;
int rc;
AssertMsgFailed(("pgmR3Load: Invalid version uVersion=%d (current %d)!\n", uVersion, PGM_SAVED_STATE_VERSION));
/* Restore pVM->pgm.s.GCPhysCR3. */
return rc;