46
46
/*******************************************************************************
47
47
* Defined Constants And Macros *
48
48
*******************************************************************************/
49
/** Saved state data unit version. */
49
/** Saved state data unit version.
50
* @todo remove the guest mappings from the saved state at next version change! */
50
51
#define PGM_SAVED_STATE_VERSION 11
51
52
/** Saved state data unit version used during 3.1 development, misses the RAM
1940
1941
* Save basic data (required / unaffected by relocation).
1943
bool const fMappingsFixed = pVM->pgm.s.fMappingsFixed;
1944
pVM->pgm.s.fMappingsFixed |= pVM->pgm.s.fMappingsFixedRestored;
1942
1945
SSMR3PutStruct(pSSM, pPGM, &s_aPGMFields[0]);
1946
pVM->pgm.s.fMappingsFixed = fMappingsFixed;
1944
1948
for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
1946
PVMCPU pVCpu = &pVM->aCpus[idCpu];
1947
SSMR3PutStruct(pSSM, &pVCpu->pgm.s, &s_aPGMCpuFields[0]);
1949
SSMR3PutStruct(pSSM, &pVM->aCpus[idCpu].pgm.s, &s_aPGMCpuFields[0]);
1951
1952
* The guest mappings.
2786
2787
SSMR3GetU32(pSSM, &pPGM->cbMappingFixed);
2788
2789
uint32_t cbRamSizeIgnored;
2789
rc = SSMR3GetU32(pSSM, &cbRamSizeIgnored);
2790
rc = SSMR3GetU32(pSSM, &cbRamSizeIgnored);
2790
2791
if (RT_FAILURE(rc))
2792
2793
SSMR3GetGCPhys(pSSM, &pVM->aCpus[0].pgm.s.GCPhysA20Mask);
2814
* The guest mappings.
2815
* The guest mappings - skipped now, see re-fixation in the caller.
2816
2817
uint32_t i = 0;
2819
/* Check the seqence number / separator. */
2820
rc = SSMR3GetU32(pSSM, &u32Sep);
2820
rc = SSMR3GetU32(pSSM, &u32Sep); /* seqence number */
2821
2821
if (RT_FAILURE(rc))
2823
2823
if (u32Sep == ~0U)
2827
AssertMsgFailed(("u32Sep=%#x (last)\n", u32Sep));
2828
return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
2825
AssertMsgReturn(u32Sep == i, ("u32Sep=%#x i=%#x\n", u32Sep, i), VERR_SSM_DATA_UNIT_FORMAT_CHANGED);
2831
/* get the mapping details. */
2832
2827
char szDesc[256];
2834
2828
rc = SSMR3GetStrZ(pSSM, szDesc, sizeof(szDesc));
2835
2829
if (RT_FAILURE(rc))
2838
SSMR3GetGCPtr(pSSM, &GCPtr);
2840
rc = SSMR3GetGCUIntPtr(pSSM, &cPTs);
2831
RTGCPTR GCPtrIgnore;
2832
SSMR3GetGCPtr(pSSM, &GCPtrIgnore); /* GCPtr */
2833
rc = SSMR3GetGCPtr(pSSM, &GCPtrIgnore); /* cPTs */
2841
2834
if (RT_FAILURE(rc))
2844
/* find matching range. */
2845
PPGMMAPPING pMapping;
2846
for (pMapping = pPGM->pMappingsR3; pMapping; pMapping = pMapping->pNextR3)
2848
if ( pMapping->cPTs == cPTs
2849
&& !strcmp(pMapping->pszDesc, szDesc))
2851
#ifdef DEBUG_sandervl
2852
if ( !strcmp(szDesc, "Hypervisor Memory Area")
2853
&& HWACCMIsEnabled(pVM))
2858
return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Couldn't find mapping: cPTs=%#x szDesc=%s (GCPtr=%RGv)"),
2859
cPTs, szDesc, GCPtr);
2862
if ( pMapping->GCPtr != GCPtr
2863
#ifdef DEBUG_sandervl
2864
&& !(!strcmp(szDesc, "Hypervisor Memory Area") && HWACCMIsEnabled(pVM))
2868
AssertMsg((GCPtr >> X86_PD_SHIFT << X86_PD_SHIFT) == GCPtr, ("GCPtr=%RGv\n", GCPtr));
2869
pgmR3MapRelocate(pVM, pMapping, pMapping->GCPtr, GCPtr);
2872
Log(("pgmR3Load: '%s' needed no relocation (%RGv)\n", szDesc, GCPtr));
2896
return pgmR3LoadMemory(pVM, pSSM, SSM_PASS_FINAL);
2859
rc = pgmR3LoadMemory(pVM, pSSM, SSM_PASS_FINAL);
2898
return pgmR3LoadMemoryOld(pVM, pSSM, uVersion);
2862
rc = pgmR3LoadMemoryOld(pVM, pSSM, uVersion);
2972
2937
PVMCPU pVCpu = &pVM->aCpus[i];
2973
2938
VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL);
2974
2939
VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
2976
2940
pVCpu->pgm.s.fSyncFlags |= PGM_SYNC_UPDATE_PAGE_BIT_VIRTUAL;
2979
2943
pgmR3HandlerPhysicalUpdateAll(pVM);
2946
* Change the paging mode and restore PGMCPU::GCPhysCR3.
2947
* (The latter requires the CPUM state to be restored already.)
2949
if (CPUMR3IsStateRestorePending(pVM))
2950
return SSMR3SetLoadError(pSSM, VERR_WRONG_ORDER, RT_SRC_POS,
2951
N_("PGM was unexpectedly restored before CPUM"));
2981
2953
for (VMCPUID i = 0; i < pVM->cCpus; i++)
2983
2955
PVMCPU pVCpu = &pVM->aCpus[i];
2986
* Change the paging mode.
2988
2957
rc = PGMR3ChangeMode(pVM, pVCpu, pVCpu->pgm.s.enmGuestMode);
2958
AssertLogRelRCReturn(rc, rc);
2990
2960
/* Restore pVM->pgm.s.GCPhysCR3. */
2991
2961
Assert(pVCpu->pgm.s.GCPhysCR3 == NIL_RTGCPHYS);
2999
2969
GCPhysCR3 = (GCPhysCR3 & X86_CR3_PAGE_MASK);
3000
2970
pVCpu->pgm.s.GCPhysCR3 = GCPhysCR3;
2974
* Try re-fixate the guest mappings.
2976
pVM->pgm.s.fMappingsFixedRestored = false;
2977
if ( pVM->pgm.s.fMappingsFixed
2978
&& pgmMapAreMappingsEnabled(&pVM->pgm.s))
2980
RTGCPTR GCPtrFixed = pVM->pgm.s.GCPtrMappingFixed;
2981
uint32_t cbFixed = pVM->pgm.s.cbMappingFixed;
2982
pVM->pgm.s.fMappingsFixed = false;
2984
uint32_t cbRequired;
2985
int rc2 = PGMR3MappingsSize(pVM, &cbRequired); AssertRC(rc2);
2986
if ( RT_SUCCESS(rc2)
2987
&& cbRequired > cbFixed)
2988
rc2 = VERR_OUT_OF_RANGE;
2989
if (RT_SUCCESS(rc2))
2990
rc2 = pgmR3MappingsFixInternal(pVM, GCPtrFixed, cbFixed);
2991
if (RT_FAILURE(rc2))
2993
LogRel(("PGM: Unable to re-fixate the guest mappings at %RGv-%RGv: rc=%Rrc (cbRequired=%#x)\n",
2994
GCPtrFixed, GCPtrFixed + cbFixed, rc2, cbRequired));
2995
pVM->pgm.s.fMappingsFixed = false;
2996
pVM->pgm.s.fMappingsFixedRestored = true;
2997
pVM->pgm.s.GCPtrMappingFixed = GCPtrFixed;
2998
pVM->pgm.s.cbMappingFixed = cbFixed;
3003
/* We used to set fixed + disabled while we only use disabled now,
3004
so wipe the state to avoid any confusion. */
3005
pVM->pgm.s.fMappingsFixed = false;
3006
pVM->pgm.s.GCPtrMappingFixed = NIL_RTGCPTR;
3007
pVM->pgm.s.cbMappingFixed = 0;
3011
* If we have floating mappings, do a CR3 sync now to make sure the HMA
3012
* doesn't conflict with guest code / data and thereby cause trouble
3013
* when restoring other components like PATM.
3015
if (pgmMapAreMappingsFloating(&pVM->pgm.s))
3017
PVMCPU pVCpu = &pVM->aCpus[0];
3018
rc = PGMSyncCR3(pVCpu, CPUMGetGuestCR0(pVCpu), CPUMGetGuestCR3(pVCpu), CPUMGetGuestCR4(pVCpu), true);
3020
return SSMR3SetLoadError(pSSM, VERR_WRONG_ORDER, RT_SRC_POS,
3021
N_("PGMSyncCR3 failed unexpectedly with rc=%Rrc"), rc);
3023
/* Make sure to re-sync before executing code. */
3024
VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL);
3025
VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
3026
pVCpu->pgm.s.fSyncFlags |= PGM_SYNC_UPDATE_PAGE_BIT_VIRTUAL;