PGMSavedState.cpp revision cc5ce86a395fb9d506d0520751ed61892a29317d
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * PGM - Page Manager and Monitor, The Saved State Part.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * Copyright (C) 2006-2009 Sun Microsystems, Inc.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * available from http://www.virtualbox.org. This file is free software;
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * you can redistribute it and/or modify it under the terms of the GNU
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * General Public License (GPL) as published by the Free Software
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * additional information or have any questions.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync/*******************************************************************************
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync* Header Files *
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync*******************************************************************************/
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync/*******************************************************************************
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync* Defined Constants And Macros *
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync*******************************************************************************/
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync/** Saved state data unit version.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * @todo remove the guest mappings from the saved state at next version change! */
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync/** Saved state before the balloon change. */
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync/** Saved state data unit version used during 3.1 development, misses the RAM
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * config. */
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync/** Saved state data unit version for 3.0 (pre teleportation). */
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync/** Saved state data unit version for 2.2.2 and later. */
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync/** Saved state data unit version for 2.2.0. */
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync/** Saved state data unit version. */
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync/** @name Sparse state record types
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync/** Zero page. No data. */
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync/** Raw page. */
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync/** Raw MMIO2 page. */
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync/** Zero MMIO2 page. */
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync/** Virgin ROM page. Followed by protection (8-bit) and the raw bits. */
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync/** Raw shadowed ROM page. The protection (8-bit) preceeds the raw bits. */
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync/** Zero shadowed ROM page. The protection (8-bit) is the only payload. */
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync/** ROM protection (8-bit). */
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync/** The last record type. */
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync/** End marker. */
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync/** Flag indicating that the data is preceeded by the page address.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * For RAW pages this is a RTGCPHYS. For MMIO2 and ROM pages this is a 8-bit
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * range ID and a 32-bit page index.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync/** The CRC-32 for a zero page. */
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync#define PGM_STATE_CRC32_ZERO_PAGE UINT32_C(0xc71c0011)
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync/** The CRC-32 for a zero half page. */
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync#define PGM_STATE_CRC32_ZERO_HALF_PAGE UINT32_C(0xf1e8ba9e)
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync/*******************************************************************************
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync* Structures and Typedefs *
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync*******************************************************************************/
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync/** For loading old saved states. (pre-smp) */
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsynctypedef struct
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync /** If set no conflict checks are required. (boolean) */
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync /** Size of fixed mapping */
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync /** Base address (GC) of fixed mapping */
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync /** A20 gate mask.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * Our current approach to A20 emulation is to let REM do it and don't bother
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * anywhere else. The interesting guests will be operating with it enabled anyway.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * But should the need arise, we'll subject physical addresses to this mask. */
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync /** A20 gate state - boolean! */
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync /** The guest paging mode. */
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync/*******************************************************************************
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync* Global Variables *
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync*******************************************************************************/
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync/** PGM fields to save/load. */
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * Find the ROM tracking structure for the given page.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * @returns Pointer to the ROM page structure. NULL if the caller didn't check
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * that it's a ROM page.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * @param pVM The VM handle.
6a0359b8230a1b91fe49967c124a75191c3dfbf9vboxsync * @param GCPhys The address of the ROM page.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsyncstatic PPGMROMPAGE pgmR3GetRomPage(PVM pVM, RTGCPHYS GCPhys) /** @todo change this to take a hint. */
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync for (PPGMROMRANGE pRomRange = pVM->pgm.s.CTX_SUFF(pRomRanges);
6a0359b8230a1b91fe49967c124a75191c3dfbf9vboxsync * Prepares the ROM pages for a live save.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * @returns VBox status code.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * @param pVM The VM handle.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * Initialize the live save tracking in the ROM page descriptors.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync for (PPGMROMRANGE pRom = pVM->pgm.s.pRomRangesR3; pRom; pRom = pRom->pNextR3)
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync pRom->aPages[iPage].LiveSave.u8Prot = (uint8_t)PGMROMPROT_INVALID;
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync pRom->aPages[iPage].LiveSave.fDirtiedRecently = true;
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync if (PGMROMPROT_IS_ROM(pRom->aPages[iPage].enmProt))
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync pRom->aPages[iPage].LiveSave.fWrittenTo = !PGM_PAGE_IS_ZERO(&pRom->aPages[iPage].Shadow);
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync RTGCPHYS GCPhys = pRom->GCPhys + ((RTGCPHYS)iPage << PAGE_SHIFT);
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync int rc = pgmPhysGetPageWithHintEx(&pVM->pgm.s, GCPhys, &pPage, &pRamHint);
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync AssertLogRelMsgRC(rc, ("%Rrc GCPhys=%RGp\n", rc, GCPhys));
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync pRom->aPages[iPage].LiveSave.fWrittenTo = !PGM_PAGE_IS_ZERO(pPage);
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync pRom->aPages[iPage].LiveSave.fWrittenTo = !PGM_PAGE_IS_ZERO(&pRom->aPages[iPage].Shadow);
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * Assigns IDs to the ROM ranges and saves them.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * @returns VBox status code.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * @param pVM The VM handle.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * @param pSSM Saved state handle.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsyncstatic int pgmR3SaveRomRanges(PVM pVM, PSSMHANDLE pSSM)
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync for (PPGMROMRANGE pRom = pVM->pgm.s.pRomRangesR3; pRom; pRom = pRom->pNextR3, id++)
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * Loads the ROM range ID assignments.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * @returns VBox status code.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * @param pVM The VM handle.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * @param pSSM The saved state handle.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsyncstatic int pgmR3LoadRomRanges(PVM pVM, PSSMHANDLE pSSM)
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync for (PPGMROMRANGE pRom = pVM->pgm.s.pRomRangesR3; pRom; pRom = pRom->pNextR3)
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * Read the data.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync for (PPGMROMRANGE pRom = pVM->pgm.s.pRomRangesR3; pRom; pRom = pRom->pNextR3)
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync AssertLogRelMsg(pRom->idSavedState != UINT8_MAX, ("%s\n", pRom->pszDesc));
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync AssertLogRelReturn(id != 0, VERR_SSM_DATA_UNIT_FORMAT_CHANGED);
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync rc = SSMR3GetStrZ(pSSM, szDevName, sizeof(szDevName));
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync AssertLogRelMsgReturn(!(GCPhys & PAGE_OFFSET_MASK), ("GCPhys=%RGp %s\n", GCPhys, szDesc), VERR_SSM_DATA_UNIT_FORMAT_CHANGED);
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync AssertLogRelMsgReturn(!(cb & PAGE_OFFSET_MASK), ("cb=%RGp %s\n", cb, szDesc), VERR_SSM_DATA_UNIT_FORMAT_CHANGED);
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * Locate a matching ROM range.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync for (pRom = pVM->pgm.s.pRomRangesR3; pRom; pRom = pRom->pNextR3)
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("ROM at %RGp by the name '%s' was not found"), GCPhys, szDesc);
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync } /* forever */
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * Scan ROM pages.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * @param pVM The VM handle.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * The shadow ROMs.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync for (PPGMROMRANGE pRom = pVM->pgm.s.pRomRangesR3; pRom; pRom = pRom->pNextR3)
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * Takes care of the virgin ROM pages in the first pass.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * This is an attempt at simplifying the handling of ROM pages a little bit.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * This ASSUMES that no new ROM ranges will be added and that they won't be
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * relinked in any way.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * @param pVM The VM handle.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * @param pSSM The SSM handle.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * @param fLiveSave Whether we're in a live save or not.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsyncstatic int pgmR3SaveRomVirginPages(PVM pVM, PSSMHANDLE pSSM, bool fLiveSave)
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync for (PPGMROMRANGE pRom = pVM->pgm.s.pRomRangesR3; pRom; pRom = pRom->pNextR3)
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync RTGCPHYS GCPhys = pRom->GCPhys + ((RTGCPHYS)iPage << PAGE_SHIFT);
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync /* Get the virgin page descriptor. */
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync /* Get the page bits. (Cannot use pgmPhysGCPhys2CCPtrInternalReadOnly here!) */
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync void const *pvPage;
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync rc = pgmPhysPageMapReadOnly(pVM, pPage, GCPhys, &pvPage);
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync AssertLogRelMsgRCReturn(rc, ("rc=%Rrc GCPhys=%RGp\n", rc, GCPhys), rc);
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync /* Save it. */
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync SSMR3PutU8(pSSM, PGM_STATE_REC_ROM_VIRGIN | PGM_STATE_REC_FLAG_ADDR);
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync /* Update state. */
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync pRom->aPages[iPage].LiveSave.u8Prot = (uint8_t)enmProt;
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * Saves dirty pages in the shadowed ROM ranges.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * Used by pgmR3LiveExecPart2 and pgmR3SaveExecMemory.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * @returns VBox status code.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * @param pVM The VM handle.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * @param pSSM The SSM handle.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * @param fLiveSave Whether it's a live save or not.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * @param fFinalPass Whether this is the final pass or not.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsyncstatic int pgmR3SaveShadowedRomPages(PVM pVM, PSSMHANDLE pSSM, bool fLiveSave, bool fFinalPass)
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * The Shadowed ROMs.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * ASSUMES that the ROM ranges are fixed.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * ASSUMES that all the ROM ranges are mapped.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync for (PPGMROMRANGE pRom = pVM->pgm.s.pRomRangesR3; pRom; pRom = pRom->pNextR3)
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync RTGCPHYS GCPhys = pRom->GCPhys + ((RTGCPHYS)iPage << PAGE_SHIFT);
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync PPGMPAGE pPage = PGMROMPROT_IS_ROM(enmProt) ? &pRomPage->Shadow : pgmPhysGetPage(&pVM->pgm.s, GCPhys);
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync void const *pvPage;
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync rc = pgmPhysPageMapReadOnly(pVM, pPage, GCPhys, &pvPage);
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync AssertLogRelMsgRCReturn(rc, ("rc=%Rrc GCPhys=%RGp\n", rc, GCPhys), rc);
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync SSMR3PutU8(pSSM, (fZero ? PGM_STATE_REC_ROM_SHW_ZERO : PGM_STATE_REC_ROM_SHW_RAW));
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync SSMR3PutU8(pSSM, (fZero ? PGM_STATE_REC_ROM_SHW_ZERO : PGM_STATE_REC_ROM_SHW_RAW) | PGM_STATE_REC_FLAG_ADDR);
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * In the final pass, make sure the protection is in sync.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync SSMR3PutU8(pSSM, PGM_STATE_REC_ROM_PROT | PGM_STATE_REC_FLAG_ADDR);
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * Cleans up ROM pages after a live save.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * @param pVM The VM handle.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * Prepares the MMIO2 pages for a live save.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * @returns VBox status code.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * @param pVM The VM handle.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * Initialize the live save tracking in the MMIO2 ranges.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * ASSUME nothing changes here.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync for (PPGMMMIO2RANGE pMmio2 = pVM->pgm.s.pMmio2RangesR3; pMmio2; pMmio2 = pMmio2->pNextR3)
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync uint32_t const cPages = pMmio2->RamRange.cb >> PAGE_SHIFT;
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync PPGMLIVESAVEMMIO2PAGE paLSPages = (PPGMLIVESAVEMMIO2PAGE)MMR3HeapAllocZ(pVM, MM_TAG_PGM, sizeof(PGMLIVESAVEMMIO2PAGE) * cPages);
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync /* Initialize it as a dirty zero page. */
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync paLSPages[iPage].u32CrcH1 = PGM_STATE_CRC32_ZERO_HALF_PAGE;
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync paLSPages[iPage].u32CrcH2 = PGM_STATE_CRC32_ZERO_HALF_PAGE;
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * Assigns IDs to the MMIO2 ranges and saves them.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * @returns VBox status code.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * @param pVM The VM handle.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * @param pSSM Saved state handle.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsyncstatic int pgmR3SaveMmio2Ranges(PVM pVM, PSSMHANDLE pSSM)
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync for (PPGMMMIO2RANGE pMmio2 = pVM->pgm.s.pMmio2RangesR3; pMmio2; pMmio2 = pMmio2->pNextR3, id++)
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync SSMR3PutStrZ(pSSM, pMmio2->pDevInsR3->pReg->szName);
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync int rc = SSMR3PutGCPhys(pSSM, pMmio2->RamRange.cb);
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * Loads the MMIO2 range ID assignments.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * @returns VBox status code.
return rc;
AssertLogRelMsgReturn(!(cb & PAGE_OFFSET_MASK), ("cb=%RGp %s\n", cb, szDesc), VERR_SSM_DATA_UNIT_FORMAT_CHANGED);
if (!pMmio2)
return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Failed to locate a MMIO2 range called '%s' owned by %s/%u, region %d"),
return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("MMIO2 region \"%s\" size mismatch: saved=%RGp config=%RGp"),
if (fZero)
if (fZero)
if (!fLiveSave)
if (!fZero)
return rc;
if (pvMmio2ToFree)
PPGMLIVESAVERAMPAGE paLSPages = (PPGMLIVESAVERAMPAGE)MMR3HeapAllocZ(pVM, MM_TAG_PGM, cPages * sizeof(PGMLIVESAVERAMPAGE));
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;
int rc = CFGMR3QueryU32Def(CFGMR3GetRoot(pVM), "RamHoleSize", &cbRamHole, MM_RAM_HOLE_SIZE_DEFAULT);
int rc = CFGMR3QueryU32Def(CFGMR3GetRoot(pVM), "RamHoleSize", &cbRamHoleCfg, MM_RAM_HOLE_SIZE_DEFAULT);
return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Ram config mismatch: saved=%RX64/%RX32 config=%RX64/%RX32 (RAM/Hole)"),
return VINF_SUCCESS;
static void pgmR3StateCalcCrc32ForRamPage(PVM pVM, PPGMRAMRANGE pCur, PPGMLIVESAVERAMPAGE paLSPages, uint32_t iPage)
void const *pvPage;
static void pgmR3StateVerifyCrc32ForPage(void const *pvPage, PPGMRAMRANGE pCur, PPGMLIVESAVERAMPAGE paLSPages, uint32_t iPage)
static void pgmR3StateVerifyCrc32ForRamPage(PVM pVM, PPGMRAMRANGE pCur, PPGMLIVESAVERAMPAGE paLSPages, uint32_t iPage)
void const *pvPage;
GCPhysCur = 0;
if ( !fFinalPass
#ifndef PGMLIVESAVERAMPAGE_WITH_CRC32
case PGM_PAGE_STATE_ALLOCATED:
case PGM_PAGE_STATE_ZERO:
case PGM_PAGE_STATE_SHARED:
if (GCPhysCur != 0)
} while (pCur);
GCPhysCur = 0;
&& paLSPages)
if ( paLSPages
int rc;
if (!fZero)
void const *pvPage;
if (paLSPages)
if (paLSPages)
return rc;
if (paLSPages)
if (fZero)
if (GCPhysCur != 0)
} while (pCur);
return VINF_SUCCESS;
if (pvToFree)
while (iPage--)
} while (pCur);
int rc;
if (uPass == 0)
return rc;
return rc;
return rc;
if (uPass == 0)
return rc;
cTotal = 0;
for (i = 0; i < cHistoryEntries; i++)
Log(("pgmR3LiveVote: VINF_SUCCESS - pass=%d cDirtyPagesShort=%u|%ums cDirtyPagesLong=%u|%ums cMsMaxDowntime=%u\n",
return VINF_SUCCESS;
Log(("pgmR3LiveVote: VINF_SUCCESS - pass=%d cDirtyPagesShort=%u cDirtyPagesLong=%u\n", uPass, cDirtyPagesShort, cDirtyPagesLong));
return VINF_SUCCESS;
return VINF_SSM_VOTE_FOR_ANOTHER_PASS;
return rc;
int rc;
return rc;
return VINF_SUCCESS;
return VINF_SUCCESS;
static int pgmR3LoadPageZeroOld(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 pgmR3LoadPageBitsOld(PVM pVM, PSSMHANDLE pSSM, uint8_t uType, PPGMPAGE pPage, RTGCPHYS GCPhys, PPGMRAMRANGE pRam)
void *pvPage;
return rc;
static int pgmR3LoadPageOld(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 pgmR3LoadShadowedRomPageOld(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;
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);
case PGM_STATE_REC_RAM_ZERO:
case PGM_STATE_REC_RAM_RAW:
return rc;
AssertLogRelMsgReturn(!(GCPhys & PAGE_OFFSET_MASK), ("%RGp\n", GCPhys), VERR_SSM_DATA_UNIT_FORMAT_CHANGED);
case PGM_STATE_REC_RAM_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_RAM_RAW:
void *pvDstPage;
return rc;
case PGM_STATE_REC_MMIO2_RAW:
case PGM_STATE_REC_MMIO2_ZERO:
iPage++;
return rc;
if ( !pMmio2
AssertLogRelMsgReturn(iPage < (pMmio2->RamRange.cb >> PAGE_SHIFT), ("iPage=%#x cb=%RGp %s\n", iPage, pMmio2->RamRange.cb, pMmio2->RamRange.pszDesc), VERR_INTERNAL_ERROR);
return rc;
case PGM_STATE_REC_ROM_VIRGIN:
case PGM_STATE_REC_ROM_PROT:
iPage++;
return rc;
if ( !pRom
AssertLogRelMsgReturn(iPage < (pRom->cb >> PAGE_SHIFT), ("iPage=%#x cb=%RGp %s\n", iPage, pRom->cb, pRom->pszDesc), VERR_INTERNAL_ERROR);
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:
if (!pRealPage)
case PGM_STATE_REC_ROM_VIRGIN:
if (pvDstPage)
case PGM_STATE_REC_ROM_VIRGIN:
return rc;
int rc;
return rc;
return rc;
uint32_t i = 0;
return rc;
if (u32Sep == ~0U)
return rc;
return rc;
return rc;
return rc;
return rc;
return rc;
int rc;
AssertMsgFailed(("pgmR3Load: Invalid version uVersion=%d (current %d)!\n", uVersion, PGM_SAVED_STATE_VERSION));
if (uPass != 0)
/* Restore pVM->pgm.s.GCPhysCR3. */
rc = PGMSyncCR3(pVCpu, CPUMGetGuestCR0(pVCpu), CPUMGetGuestCR3(pVCpu), CPUMGetGuestCR4(pVCpu), true);
return rc;