VirtualBox

Ignore:
Timestamp:
Jan 20, 2010 2:43:56 PM (15 years ago)
Author:
vboxsync
Message:

PGM,CPUM: Be more careful and flexible with guest mappings on restore. (#4362)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/PGMSavedState.cpp

    r25231 r25935  
    4747*   Defined Constants And Macros                                               *
    4848*******************************************************************************/
    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! */
    5051#define PGM_SAVED_STATE_VERSION                 11
    5152/** Saved state data unit version used during 3.1 development, misses the RAM
     
    19391940     * Save basic data (required / unaffected by relocation).
    19401941     */
     1942    bool const fMappingsFixed  = pVM->pgm.s.fMappingsFixed;
     1943    pVM->pgm.s.fMappingsFixed |= pVM->pgm.s.fMappingsFixedRestored;
    19411944    SSMR3PutStruct(pSSM, pPGM, &s_aPGMFields[0]);
     1945    pVM->pgm.s.fMappingsFixed  = fMappingsFixed;
    19421946
    19431947    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
    1944     {
    1945         PVMCPU pVCpu = &pVM->aCpus[idCpu];
    1946         SSMR3PutStruct(pSSM, &pVCpu->pgm.s, &s_aPGMCpuFields[0]);
    1947     }
     1948        SSMR3PutStruct(pSSM, &pVM->aCpus[idCpu].pgm.s, &s_aPGMCpuFields[0]);
    19481949
    19491950    /*
     
    27862787
    27872788        uint32_t cbRamSizeIgnored;
    2788         rc = SSMR3GetU32(pSSM, &cbRamSizeIgnored);
     2789        rc = SSMR3GetU32(pSSM,  &cbRamSizeIgnored);
    27892790        if (RT_FAILURE(rc))
    27902791            return rc;
     
    28112812
    28122813    /*
    2813      * The guest mappings.
     2814     * The guest mappings - skipped now, see re-fixation in the caller.
    28142815     */
    28152816    uint32_t i = 0;
    28162817    for (;; i++)
    28172818    {
    2818         /* Check the seqence number / separator. */
    2819         rc = SSMR3GetU32(pSSM, &u32Sep);
     2819        rc = SSMR3GetU32(pSSM, &u32Sep);        /* seqence number */
    28202820        if (RT_FAILURE(rc))
    28212821            return rc;
    28222822        if (u32Sep == ~0U)
    28232823            break;
    2824         if (u32Sep != i)
    2825         {
    2826             AssertMsgFailed(("u32Sep=%#x (last)\n", u32Sep));
    2827             return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
    2828         }
    2829 
    2830         /* get the mapping details. */
     2824        AssertMsgReturn(u32Sep == i, ("u32Sep=%#x i=%#x\n", u32Sep, i), VERR_SSM_DATA_UNIT_FORMAT_CHANGED);
     2825
    28312826        char szDesc[256];
    2832         szDesc[0] = '\0';
    28332827        rc = SSMR3GetStrZ(pSSM, szDesc, sizeof(szDesc));
    28342828        if (RT_FAILURE(rc))
    28352829            return rc;
    2836         RTGCPTR GCPtr;
    2837         SSMR3GetGCPtr(pSSM, &GCPtr);
    2838         RTGCPTR cPTs;
    2839         rc = SSMR3GetGCUIntPtr(pSSM, &cPTs);
     2830        RTGCPTR GCPtrIgnore;
     2831        SSMR3GetGCPtr(pSSM, &GCPtrIgnore);      /* GCPtr */
     2832        rc = SSMR3GetGCPtr(pSSM, &GCPtrIgnore); /* cPTs  */
    28402833        if (RT_FAILURE(rc))
    28412834            return rc;
    2842 
    2843         /* find matching range. */
    2844         PPGMMAPPING pMapping;
    2845         for (pMapping = pPGM->pMappingsR3; pMapping; pMapping = pMapping->pNextR3)
    2846         {
    2847             if (    pMapping->cPTs == cPTs
    2848                 &&  !strcmp(pMapping->pszDesc, szDesc))
    2849                 break;
    2850 #ifdef DEBUG_sandervl
    2851             if (    !strcmp(szDesc, "Hypervisor Memory Area")
    2852                 &&  HWACCMIsEnabled(pVM))
    2853                 break;
    2854 #endif
    2855         }
    2856         if (!pMapping)
    2857             return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Couldn't find mapping: cPTs=%#x szDesc=%s (GCPtr=%RGv)"),
    2858                                     cPTs, szDesc, GCPtr);
    2859 
    2860         /* relocate it. */
    2861         if (    pMapping->GCPtr != GCPtr
    2862 #ifdef DEBUG_sandervl
    2863              && !(!strcmp(szDesc, "Hypervisor Memory Area") && HWACCMIsEnabled(pVM))
    2864 #endif
    2865            )
    2866         {
    2867             AssertMsg((GCPtr >> X86_PD_SHIFT << X86_PD_SHIFT) == GCPtr, ("GCPtr=%RGv\n", GCPtr));
    2868             pgmR3MapRelocate(pVM, pMapping, pMapping->GCPtr, GCPtr);
    2869         }
    2870         else
    2871             Log(("pgmR3Load: '%s' needed no relocation (%RGv)\n", szDesc, GCPtr));
    28722835    }
    28732836
     
    28932856        }
    28942857
    2895         return pgmR3LoadMemory(pVM, pSSM, SSM_PASS_FINAL);
    2896     }
    2897     return pgmR3LoadMemoryOld(pVM, pSSM, uVersion);
     2858        rc = pgmR3LoadMemory(pVM, pSSM, SSM_PASS_FINAL);
     2859    }
     2860    else
     2861        rc = pgmR3LoadMemoryOld(pVM, pSSM, uVersion);
     2862    return rc;
    28982863}
    28992864
     
    29722937                VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL);
    29732938                VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
    2974 
    29752939                pVCpu->pgm.s.fSyncFlags |= PGM_SYNC_UPDATE_PAGE_BIT_VIRTUAL;
    29762940            }
     
    29782942            pgmR3HandlerPhysicalUpdateAll(pVM);
    29792943
     2944            /*
     2945             * Change the paging mode and restore PGMCPU::GCPhysCR3.
     2946             * (The latter requires the CPUM state to be restored already.)
     2947             */
     2948            if (CPUMR3IsStateRestorePending(pVM))
     2949                return SSMR3SetLoadError(pSSM, VERR_WRONG_ORDER, RT_SRC_POS,
     2950                                         N_("PGM was unexpectedly restored before CPUM"));
     2951
    29802952            for (VMCPUID i = 0; i < pVM->cCpus; i++)
    29812953            {
    29822954                PVMCPU pVCpu = &pVM->aCpus[i];
    29832955
    2984                 /*
    2985                  * Change the paging mode.
    2986                  */
    29872956                rc = PGMR3ChangeMode(pVM, pVCpu, pVCpu->pgm.s.enmGuestMode);
     2957                AssertLogRelRCReturn(rc, rc);
    29882958
    29892959                /* Restore pVM->pgm.s.GCPhysCR3. */
     
    29992969                pVCpu->pgm.s.GCPhysCR3 = GCPhysCR3;
    30002970            }
     2971
     2972            /*
     2973             * Try re-fixate the guest mappings.
     2974             */
     2975            pVM->pgm.s.fMappingsFixedRestored = false;
     2976            if (   pVM->pgm.s.fMappingsFixed
     2977                && pgmMapAreMappingsEnabled(&pVM->pgm.s))
     2978            {
     2979                RTGCPTR     GCPtrFixed    = pVM->pgm.s.GCPtrMappingFixed;
     2980                uint32_t    cbFixed       = pVM->pgm.s.cbMappingFixed;
     2981                pVM->pgm.s.fMappingsFixed = false;
     2982
     2983                uint32_t    cbRequired;
     2984                int rc2 = PGMR3MappingsSize(pVM, &cbRequired); AssertRC(rc2);
     2985                if (   RT_SUCCESS(rc2)
     2986                    && cbRequired > cbFixed)
     2987                    rc2 = VERR_OUT_OF_RANGE;
     2988                if (RT_SUCCESS(rc2))
     2989                    rc2 = pgmR3MappingsFixInternal(pVM, GCPtrFixed, cbFixed);
     2990                if (RT_FAILURE(rc2))
     2991                {
     2992                    LogRel(("PGM: Unable to re-fixate the guest mappings at %RGv-%RGv: rc=%Rrc (cbRequired=%#x)\n",
     2993                            GCPtrFixed, GCPtrFixed + cbFixed, rc2, cbRequired));
     2994                    pVM->pgm.s.fMappingsFixed         = false;
     2995                    pVM->pgm.s.fMappingsFixedRestored = true;
     2996                    pVM->pgm.s.GCPtrMappingFixed      = GCPtrFixed;
     2997                    pVM->pgm.s.cbMappingFixed         = cbFixed;
     2998                }
     2999            }
     3000            else
     3001            {
     3002                /* We used to set fixed + disabled while we only use disabled now,
     3003                   so wipe the state to avoid any confusion. */
     3004                pVM->pgm.s.fMappingsFixed    = false;
     3005                pVM->pgm.s.GCPtrMappingFixed = NIL_RTGCPTR;
     3006                pVM->pgm.s.cbMappingFixed    = 0;
     3007            }
     3008
     3009            /*
     3010             * If we have floating mappings, do a CR3 sync now to make sure the HMA
     3011             * doesn't conflict with guest code / data and thereby cause trouble
     3012             * when restoring other components like PATM.
     3013             */
     3014            if (pgmMapAreMappingsFloating(&pVM->pgm.s))
     3015            {
     3016                PVMCPU pVCpu = &pVM->aCpus[0];
     3017                rc = PGMSyncCR3(pVCpu, CPUMGetGuestCR0(pVCpu), CPUMGetGuestCR3(pVCpu),  CPUMGetGuestCR4(pVCpu), true);
     3018                if (RT_FAILURE(rc))
     3019                    return SSMR3SetLoadError(pSSM, VERR_WRONG_ORDER, RT_SRC_POS,
     3020                                             N_("PGMSyncCR3 failed unexpectedly with rc=%Rrc"), rc);
     3021
     3022                /* Make sure to re-sync before executing code. */
     3023                VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL);
     3024                VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
     3025                pVCpu->pgm.s.fSyncFlags |= PGM_SYNC_UPDATE_PAGE_BIT_VIRTUAL;
     3026            }
    30013027        }
    30023028    }
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