VirtualBox

Changeset 25935 in vbox


Ignore:
Timestamp:
Jan 20, 2010 2:43:56 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
56774
Message:

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

Location:
trunk
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/cpum.h

    r25866 r25935  
    930930VMMR3DECL(void)         CPUMR3Reset(PVM pVM);
    931931VMMR3DECL(void)         CPUMR3ResetCpu(PVMCPU pVCpu);
     932VMMDECL(bool)           CPUMR3IsStateRestorePending(PVM pVM);
    932933# ifdef DEBUG
    933934VMMR3DECL(void)         CPUMR3SaveEntryCtx(PVM pVM);
    934935# endif
    935936VMMR3DECL(int)          CPUMR3SetCR4Feature(PVM pVM, RTHCUINTREG fOr, RTHCUINTREG fAnd);
    936 
    937937VMMR3DECL(RCPTRTYPE(PCCPUMCPUID)) CPUMR3GetGuestCpuIdStdRCPtr(PVM pVM);
    938938VMMR3DECL(RCPTRTYPE(PCCPUMCPUID)) CPUMR3GetGuestCpuIdExtRCPtr(PVM pVM);
  • trunk/include/VBox/pgm.h

    r25825 r25935  
    306306#ifndef IN_RING0
    307307VMMDECL(bool)       PGMMapHasConflicts(PVM pVM);
    308 VMMDECL(int)        PGMMapResolveConflicts(PVM pVM);
    309308#endif
    310309#ifdef VBOX_STRICT
     
    488487VMMR3DECL(int)      PGMR3UnmapPT(PVM pVM, RTGCPTR GCPtr);
    489488VMMR3DECL(int)      PGMR3FinalizeMappings(PVM pVM);
     489VMMR3DECL(int)      PGMR3MappingsDisable(PVM pVM);
    490490VMMR3DECL(int)      PGMR3MappingsSize(PVM pVM, uint32_t *pcb);
    491491VMMR3DECL(int)      PGMR3MappingsFix(PVM pVM, RTGCPTR GCPtrBase, uint32_t cb);
    492492VMMR3DECL(int)      PGMR3MappingsUnfix(PVM pVM);
    493 VMMR3DECL(int)      PGMR3MappingsDisable(PVM pVM);
     493VMMR3DECL(bool)     PGMR3MappingsNeedReFixing(PVM pVM);
    494494VMMR3DECL(int)      PGMR3MapIntermediate(PVM pVM, RTUINTPTR Addr, RTHCPHYS HCPhys, unsigned cbPages);
    495495VMMR3DECL(int)      PGMR3MapRead(PVM pVM, void *pvDst, RTGCPTR GCPtrSrc, size_t cb);
  • trunk/src/VBox/VMM/CPUM.cpp

    r25825 r25935  
    104104static DECLCALLBACK(int)  cpumR3LiveExec(PVM pVM, PSSMHANDLE pSSM, uint32_t uPass);
    105105static DECLCALLBACK(int)  cpumR3SaveExec(PVM pVM, PSSMHANDLE pSSM);
     106static DECLCALLBACK(int)  cpumR3LoadPrep(PVM pVM, PSSMHANDLE pSSM);
    106107static DECLCALLBACK(int)  cpumR3LoadExec(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass);
     108static DECLCALLBACK(int)  cpumR3LoadDone(PVM pVM, PSSMHANDLE pSSM);
    107109static DECLCALLBACK(void) cpumR3InfoAll(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs);
    108110static DECLCALLBACK(void) cpumR3InfoGuest(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs);
     
    214216                                   NULL, cpumR3LiveExec, NULL,
    215217                                   NULL, cpumR3SaveExec, NULL,
    216                                    NULL, cpumR3LoadExec, NULL);
     218                                   cpumR3LoadPrep, cpumR3LoadExec, cpumR3LoadDone);
    217219    if (RT_FAILURE(rc))
    218220        return rc;
     
    18761878
    18771879/**
    1878  * Execute state load operation.
    1879  *
    1880  * @returns VBox status code.
    1881  * @param   pVM             VM Handle.
    1882  * @param   pSSM            SSM operation handle.
    1883  * @param   uVersion        Data layout version.
    1884  * @param   uPass           The data pass.
     1880 * @copydoc FNSSMINTLOADPREP
     1881 */
     1882static DECLCALLBACK(int) cpumR3LoadPrep(PVM pVM, PSSMHANDLE pSSM)
     1883{
     1884    pVM->cpum.s.fPendingRestore = true;
     1885    return VINF_SUCCESS;
     1886}
     1887
     1888
     1889/**
     1890 * @copydoc FNSSMINTLOADEXEC
    18851891 */
    18861892static DECLCALLBACK(int) cpumR3LoadExec(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
     
    19601966        }
    19611967    }
     1968
     1969    pVM->cpum.s.fPendingRestore = false;
    19621970
    19631971    /*
     
    20782086
    20792087    return rc;
     2088}
     2089
     2090
     2091/**
     2092 * @copydoc FNSSMINTLOADPREP
     2093 */
     2094static DECLCALLBACK(int) cpumR3LoadDone(PVM pVM, PSSMHANDLE pSSM)
     2095{
     2096    if (RT_FAILURE(SSMR3HandleGetStatus(pSSM)))
     2097        return VINF_SUCCESS;
     2098
     2099    /* just check this since we can. */ /** @todo Add a SSM unit flag for indicating that it's mandatory during a restore.  */
     2100    if (pVM->cpum.s.fPendingRestore)
     2101    {
     2102        LogRel(("CPUM: Missing state!\n"));
     2103        return VERR_INTERNAL_ERROR_2;
     2104    }
     2105
     2106    return VINF_SUCCESS;
     2107}
     2108
     2109
     2110/**
     2111 * Checks if the CPUM state restore is still pending.
     2112 *
     2113 * @returns true / false.
     2114 * @param   pVM                 The VM handle.
     2115 */
     2116VMMDECL(bool) CPUMR3IsStateRestorePending(PVM pVM)
     2117{
     2118    return pVM->cpum.s.fPendingRestore;
    20802119}
    20812120
     
    34713510VMMR3DECL(void) CPUMR3SaveEntryCtx(PVM pVM)
    34723511{
    3473     /* @todo SMP support!! */
     3512    /** @todo SMP support!! */
    34743513    pVM->cpum.s.GuestEntry = *CPUMQueryGuestCtxPtr(VMMGetCpu(pVM));
    34753514}
  • trunk/src/VBox/VMM/CPUMInternal.h

    r23794 r25935  
    302302    /** Synthetic CPU type? */
    303303    bool                    fSyntheticCpu;
    304     uint8_t                 abPadding[2 + (HC_ARCH_BITS == 64) * 4];
     304    /** Indiciates that a state restore is pending.
     305     * This is used to verify load order dependencies (PGM). */
     306    bool                    fPendingRestore;
     307    uint8_t                 abPadding[1 + (HC_ARCH_BITS == 64) * 4];
    305308
    306309    /** The standard set of CpuId leafs. */
  • trunk/src/VBox/VMM/CPUMInternal.mac

    r23794 r25935  
    7373    .fRawEntered          resb    1
    7474    .fSyntheticCpu        resb    1
     75    .fPendingRestore      resb    1
    7576%if RTHCPTR_CB == 8
    76     .abPadding            resb    6
     77    .abPadding            resb    5
    7778%else
    78     .abPadding            resb    2
     79    .abPadding            resb    1
    7980%endif
    8081
  • trunk/src/VBox/VMM/PGM.cpp

    r25825 r25935  
    638638/** @todo Convert the first two commands to 'info' items. */
    639639static DECLCALLBACK(int)  pgmR3CmdRam(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
    640 static DECLCALLBACK(int)  pgmR3CmdMap(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
    641640static DECLCALLBACK(int)  pgmR3CmdError(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
    642641static DECLCALLBACK(int)  pgmR3CmdSync(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
     
    672671    /* pszCmd,  cArgsMin, cArgsMax, paArgDesc,                cArgDescs,    pResultDesc,        fFlags,     pfnHandler          pszSyntax,          ....pszDescription */
    673672    { "pgmram",        0, 0,        NULL,                     0,            NULL,               0,          pgmR3CmdRam,        "",                     "Display the ram ranges." },
    674     { "pgmmap",        0, 0,        NULL,                     0,            NULL,               0,          pgmR3CmdMap,        "",                     "Display the mapping ranges." },
    675673    { "pgmsync",       0, 0,        NULL,                     0,            NULL,               0,          pgmR3CmdSync,       "",                     "Sync the CR3 page." },
    676674    { "pgmerror",      0, 1,        &g_aPgmErrorArgs[0],      1,            NULL,               0,          pgmR3CmdError,      "",                     "Enables inject runtime of errors into parts of PGM." },
     
    22242222     * Unfix any fixed mappings and disable CR3 monitoring.
    22252223     */
    2226     pVM->pgm.s.fMappingsFixed    = false;
    2227     pVM->pgm.s.GCPtrMappingFixed = 0;
    2228     pVM->pgm.s.cbMappingFixed    = 0;
    2229 
    2230     /* Exit the guest paging mode before the pgm pool gets reset.
     2224    pVM->pgm.s.fMappingsFixed         = false;
     2225    pVM->pgm.s.fMappingsFixedRestored = false;
     2226    pVM->pgm.s.GCPtrMappingFixed      = NIL_RTGCPTR;
     2227    pVM->pgm.s.cbMappingFixed         = 0;
     2228
     2229    /*
     2230     * Exit the guest paging mode before the pgm pool gets reset.
    22312231     * Important to clean up the amd64 case.
    22322232     */
     
    40344034
    40354035/**
    4036  * The '.pgmmap' command.
    4037  *
    4038  * @returns VBox status.
    4039  * @param   pCmd        Pointer to the command descriptor (as registered).
    4040  * @param   pCmdHlp     Pointer to command helper functions.
    4041  * @param   pVM         Pointer to the current VM (if any).
    4042  * @param   paArgs      Pointer to (readonly) array of arguments.
    4043  * @param   cArgs       Number of arguments in the array.
    4044  */
    4045 static DECLCALLBACK(int) pgmR3CmdMap(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
    4046 {
    4047     /*
    4048      * Validate input.
    4049      */
    4050     if (!pVM)
    4051         return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: The command requires a VM to be selected.\n");
    4052     if (!pVM->pgm.s.pMappingsR3)
    4053         return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "Sorry, no mappings are registered.\n");
    4054 
    4055     /*
    4056      * Print message about the fixedness of the mappings.
    4057      */
    4058     int rc = pCmdHlp->pfnPrintf(pCmdHlp, NULL, pVM->pgm.s.fMappingsFixed ? "The mappings are FIXED.\n" : "The mappings are FLOATING.\n");
    4059     if (RT_FAILURE(rc))
    4060         return rc;
    4061 
    4062     /*
    4063      * Dump the ranges.
    4064      */
    4065     PPGMMAPPING pCur;
    4066     for (pCur = pVM->pgm.s.pMappingsR3; pCur; pCur = pCur->pNextR3)
    4067     {
    4068         rc = pCmdHlp->pfnPrintf(pCmdHlp, NULL,
    4069             "%08x - %08x %s\n",
    4070             pCur->GCPtr, pCur->GCPtrLast, pCur->pszDesc);
    4071         if (RT_FAILURE(rc))
    4072             return rc;
    4073     }
    4074 
    4075     return VINF_SUCCESS;
    4076 }
    4077 
    4078 
    4079 /**
    40804036 * The '.pgmerror' and '.pgmerroroff' commands.
    40814037 *
  • trunk/src/VBox/VMM/PGMInternal.h

    r25825 r25935  
    25162516     * PGMR3MapIntermediate calls will be rejected. */
    25172517    bool                            fFinalizedMappings;
    2518     /** If set no conflict checks are required.  (boolean) */
     2518    /** If set no conflict checks are required. */
    25192519    bool                            fMappingsFixed;
    2520     /** If set, then no mappings are put into the shadow page table. (boolean) */
    2521     bool                            fDisableMappings;
    2522     /** Size of fixed mapping */
     2520    /** If set if restored as fixed but we were unable to re-fixate at the old
     2521     *  location because of room or address incompatibilities. */
     2522    bool                            fMappingsFixedRestored;
     2523    /** If set, then no mappings are put into the shadow page table.
     2524     * Use pgmMapAreMappingsEnabled() instead of direct access. */
     2525    bool                            fMappingsDisabled;
     2526    /** Size of fixed mapping.
     2527     * This is valid if either fMappingsFixed or fMappingsFixedRestored is set. */
    25232528    uint32_t                        cbMappingFixed;
    2524     /** Base address (GC) of fixed mapping */
     2529    /** Base address (GC) of fixed mapping.
     2530     * This is valid if either fMappingsFixed or fMappingsFixedRestored is set. */
    25252531    RTGCPTR                         GCPtrMappingFixed;
    25262532    /** The address of the previous RAM range mapping. */
     
    32433249void            pgmUnlock(PVM pVM);
    32443250
     3251int             pgmR3MappingsFixInternal(PVM pVM, RTGCPTR GCPtrBase, uint32_t cb);
    32453252int             pgmR3SyncPTResolveConflict(PVM pVM, PPGMMAPPING pMapping, PX86PD pPDSrc, RTGCPTR GCPtrOldMapping);
    32463253int             pgmR3SyncPTResolveConflictPAE(PVM pVM, PPGMMAPPING pMapping, RTGCPTR GCPtrOldMapping);
    32473254PPGMMAPPING     pgmGetMapping(PVM pVM, RTGCPTR GCPtr);
    3248 void            pgmR3MapRelocate(PVM pVM, PPGMMAPPING pMapping, RTGCPTR GCPtrOldMapping, RTGCPTR GCPtrNewMapping);
     3255int             pgmMapResolveConflicts(PVM pVM);
    32493256DECLCALLBACK(void) pgmR3MapInfo(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs);
    32503257
     
    48894896}
    48904897
    4891 /**
    4892  * Tells if mappings are to be put into the shadow page table or not
     4898
     4899/**
     4900 * Tells if mappings are to be put into the shadow page table or not.
    48934901 *
    48944902 * @returns boolean result
    48954903 * @param   pVM         VM handle.
    48964904 */
    4897 DECLINLINE(bool) pgmMapAreMappingsEnabled(PPGM pPGM)
    4898 {
    4899 #ifdef IN_RING0
     4905DECL_FORCE_INLINE(bool) pgmMapAreMappingsEnabled(PPGM pPGM)
     4906{
     4907#ifdef PGM_WITHOUT_MAPPINGS
    49004908    /* There are no mappings in VT-x and AMD-V mode. */
    4901     Assert(pPGM->fDisableMappings);
     4909    Assert(pPGM->fMappingsDisabled);
    49024910    return false;
    49034911#else
    4904     return !pPGM->fDisableMappings;
     4912    return !pPGM->fMappingsDisabled;
     4913#endif
     4914}
     4915
     4916
     4917/**
     4918 * Checks if the mappings are floating and enabled.
     4919 *
     4920 * @returns true / false.
     4921 * @param   pVM         The VM handle.
     4922 */
     4923DECL_FORCE_INLINE(bool) pgmMapAreMappingsFloating(PPGM pPGM)
     4924{
     4925#ifdef PGM_WITHOUT_MAPPINGS
     4926    /* There are no mappings in VT-x and AMD-V mode. */
     4927    Assert(pPGM->fMappingsDisabled);
     4928    return false;
     4929#else
     4930    return !pPGM->fMappingsDisabled
     4931        && !pPGM->fMappingsFixed;
    49054932#endif
    49064933}
  • trunk/src/VBox/VMM/PGMMap.cpp

    r25227 r25935  
    7474    cb = RT_ALIGN_32(cb, _4M);
    7575    RTGCPTR GCPtrLast = GCPtr + cb - 1;
    76     if (GCPtrLast < GCPtr)
    77     {
    78         AssertMsgFailed(("Range wraps! GCPtr=%x GCPtrLast=%x\n", GCPtr, GCPtrLast));
    79         return VERR_INVALID_PARAMETER;
    80     }
    81     if (pVM->pgm.s.fMappingsFixed)
    82     {
    83         AssertMsgFailed(("Mappings are fixed! It's not possible to add new mappings at this time!\n"));
    84         return VERR_PGM_MAPPINGS_FIXED;
    85     }
    86     if (!pfnRelocate)
    87     {
    88         AssertMsgFailed(("Callback is required\n"));
    89         return VERR_INVALID_PARAMETER;
    90     }
     76
     77    AssertMsgReturn(GCPtrLast >= GCPtr, ("Range wraps! GCPtr=%x GCPtrLast=%x\n", GCPtr, GCPtrLast),
     78                    VERR_INVALID_PARAMETER);
     79    AssertMsgReturn(!pVM->pgm.s.fMappingsFixed, ("Mappings are fixed! It's not possible to add new mappings at this time!\n"),
     80                    VERR_PGM_MAPPINGS_FIXED);
     81    AssertPtrReturn(pfnRelocate, VERR_INVALID_PARAMETER);
    9182
    9283    /*
     
    142133    pNew->GCPtrLast     = GCPtrLast;
    143134    pNew->cb            = cb;
    144     pNew->pszDesc       = pszDesc;
    145135    pNew->pfnRelocate   = pfnRelocate;
    146136    pNew->pvUser        = pvUser;
     137    pNew->pszDesc       = pszDesc;
    147138    pNew->cPTs          = cPTs;
    148139
     
    268259             */
    269260            MMHyperFree(pVM, pCur->aPTs[0].pPTR3);
    270             pgmR3MapClearPDEs(pVM, pCur, pCur->GCPtr >> X86_PD_SHIFT);
     261            if (pCur->GCPtr != NIL_RTGCPTR)
     262                pgmR3MapClearPDEs(pVM, pCur, pCur->GCPtr >> X86_PD_SHIFT);
    271263            MMHyperFree(pVM, pCur);
    272264
     
    414406     * Loop until all mappings have been finalized.
    415407     */
    416     /*unsigned    iPDNext = UINT32_C(0xc0000000) >> X86_PD_SHIFT;*/ /* makes CSAM/PATM freak out booting linux. :-/ */
    417408#if 0
     409    unsigned    iPDNext = UINT32_C(0xc0000000) >> X86_PD_SHIFT; /* makes CSAM/PATM freak out booting linux. :-/ */
     410#elif 0
    418411    unsigned    iPDNext = MM_HYPER_AREA_ADDRESS >> X86_PD_SHIFT;
    419412#else
    420413    unsigned    iPDNext = 1 << X86_PD_SHIFT; /* no hint, map them from the top. */
    421414#endif
     415
    422416    PPGMMAPPING pCur;
    423417    do
     
    504498
    505499/**
    506  * Fixes the guest context mappings in a range reserved from the Guest OS.
     500 * Fixates the guest context mappings in a range reserved from the Guest OS.
    507501 *
    508502 * @returns VBox status code.
     
    513507VMMR3DECL(int) PGMR3MappingsFix(PVM pVM, RTGCPTR GCPtrBase, uint32_t cb)
    514508{
    515     Log(("PGMR3MappingsFix: GCPtrBase=%#x cb=%#x\n", GCPtrBase, cb));
    516 
    517     /* Ignore the additions mapping fix call in VT-x/AMD-V. */
    518     if (    pVM->pgm.s.fMappingsFixed
    519         &&  HWACCMIsEnabled(pVM))
     509    Log(("PGMR3MappingsFix: GCPtrBase=%RGv cb=%#x (fMappingsFixed=%RTbool fMappingsDisabled=%RTbool)\n",
     510         GCPtrBase, cb, pVM->pgm.s.fMappingsFixed, pVM->pgm.s.fMappingsDisabled));
     511
     512    /*
     513     * Ignore the additions mapping fix call if disabled.
     514     */
     515    if (!pgmMapAreMappingsEnabled(&pVM->pgm.s))
     516    {
     517        Assert(HWACCMIsEnabled(pVM));
    520518        return VINF_SUCCESS;
    521 
    522     /* Only applies to VCPU 0 as we don't support SMP guests with raw mode. */
     519    }
     520
     521    /*
     522     * Only applies to VCPU 0 as we don't support SMP guests with raw mode.
     523     */
    523524    Assert(pVM->cCpus == 1);
    524 
    525525    PVMCPU pVCpu = &pVM->aCpus[0];
    526 
    527     /*
    528      * This is all or nothing at all. So, a tiny bit of paranoia first.
    529      */
    530     if (GCPtrBase & X86_PAGE_4M_OFFSET_MASK)
    531     {
    532         AssertMsgFailed(("GCPtrBase (%#x) has to be aligned on a 4MB address!\n", GCPtrBase));
    533         return VERR_INVALID_PARAMETER;
    534     }
    535     if (!cb || (cb & X86_PAGE_4M_OFFSET_MASK))
    536     {
    537         AssertMsgFailed(("cb (%#x) is 0 or not aligned on a 4MB address!\n", cb));
    538         return VERR_INVALID_PARAMETER;
    539     }
    540526
    541527    /*
     
    544530     */
    545531    PGMSyncCR3(pVCpu, CPUMGetGuestCR0(pVCpu), CPUMGetGuestCR3(pVCpu), CPUMGetGuestCR4(pVCpu), true);
     532
     533    return pgmR3MappingsFixInternal(pVM, GCPtrBase, cb);
     534}
     535
     536
     537/**
     538 * Internal worker for PGMR3MappingsFix and pgmR3Load.
     539 *
     540 * (This does not perform a SyncCR3 before the fixation like PGMR3MappingsFix.)
     541 *
     542 * @returns VBox status code.
     543 * @param   pVM         The VM.
     544 * @param   GCPtrBase   The address of the reserved range of guest memory.
     545 * @param   cb          The size of the range starting at GCPtrBase.
     546 */
     547int pgmR3MappingsFixInternal(PVM pVM, RTGCPTR GCPtrBase, uint32_t cb)
     548{
     549    /*
     550     * Check input arguments and pre-conditions.
     551     */
     552    AssertMsgReturn(!(GCPtrBase & X86_PAGE_4M_OFFSET_MASK), ("GCPtrBase (%#x) has to be aligned on a 4MB address!\n", GCPtrBase),
     553                    VERR_INVALID_PARAMETER);
     554    AssertMsgReturn(cb && !(cb & X86_PAGE_4M_OFFSET_MASK), ("cb (%#x) is 0 or not aligned on a 4MB address!\n", cb),
     555                    VERR_INVALID_PARAMETER);
     556    AssertReturn(pgmMapAreMappingsEnabled(&pVM->pgm.s), VERR_INTERNAL_ERROR_3);
     557    AssertReturn(pVM->cCpus == 1, VERR_INTERNAL_ERROR_4);
    546558
    547559    /*
     
    574586     * In PAE / PAE mode, make sure we don't cross page directories.
    575587     */
     588    PVMCPU pVCpu = &pVM->aCpus[0];
    576589    if (    (   pVCpu->pgm.s.enmGuestMode  == PGMMODE_PAE
    577590             || pVCpu->pgm.s.enmGuestMode  == PGMMODE_PAE_NX)
     
    619632    while (pCur)
    620633    {
    621         unsigned iPDOld = pCur->GCPtr >> X86_PD_SHIFT;
    622         iPDNew = GCPtrCur >> X86_PD_SHIFT;
     634        RTGCPTR const GCPtrOld = pCur->GCPtr;
    623635
    624636        /*
    625637         * Relocate the page table(s).
    626638         */
    627         pgmR3MapClearPDEs(pVM, pCur, iPDOld);
    628         pgmR3MapSetPDEs(pVM, pCur, iPDNew);
     639        if (pCur->GCPtr != NIL_RTGCPTR)
     640            pgmR3MapClearPDEs(pVM, pCur, GCPtrOld >> X86_PD_SHIFT);
     641        pgmR3MapSetPDEs(pVM, pCur, GCPtrCur >> X86_PD_SHIFT);
    629642
    630643        /*
     
    637650         * Callback to execute the relocation.
    638651         */
    639         pCur->pfnRelocate(pVM, iPDOld << X86_PD_SHIFT, iPDNew << X86_PD_SHIFT, PGMRELOCATECALL_RELOCATE, pCur->pvUser);
     652        pCur->pfnRelocate(pVM, GCPtrOld, GCPtrCur, PGMRELOCATECALL_RELOCATE, pCur->pvUser);
    640653
    641654        /*
     
    647660
    648661    /*
    649      * Mark the mappings as fixed and return.
    650      */
    651     pVM->pgm.s.fMappingsFixed    = true;
    652     pVM->pgm.s.GCPtrMappingFixed = GCPtrBase;
    653     pVM->pgm.s.cbMappingFixed    = cb;
     662     * Mark the mappings as fixed at this new location and return.
     663     */
     664    pVM->pgm.s.fMappingsFixed           = true;
     665    pVM->pgm.s.fMappingsFixedRestored   = false;
     666    pVM->pgm.s.GCPtrMappingFixed        = GCPtrBase;
     667    pVM->pgm.s.cbMappingFixed           = cb;
    654668
    655669    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
     
    661675}
    662676
    663 /**
    664  * Disable the hypervisor mappings in the shadow page tables (doesn't touch the intermediate table!)
     677
     678/**
     679 * Interface for disabling the guest mappings when switching to HWACCM mode
     680 * during VM creation and VM reset.
     681 *
     682 * (This doesn't touch the intermediate table!)
    665683 *
    666684 * @returns VBox status code.
     
    669687VMMR3DECL(int) PGMR3MappingsDisable(PVM pVM)
    670688{
    671     uint32_t cb;
    672     int rc = PGMR3MappingsSize(pVM, &cb);
    673     AssertRCReturn(rc, rc);
    674 
    675     /* Only applies to VCPU 0. */
    676     PVMCPU pVCpu = &pVM->aCpus[0];
    677 
    678     pgmLock(pVM);                           /* to avoid assertions */
    679     rc = pgmMapDeactivateCR3(pVM, pVCpu->pgm.s.pShwPageCR3R3);
    680     pgmUnlock(pVM);
    681     AssertRCReturn(rc, rc);
    682 
    683     /*
    684      * Mark the mappings as fixed (using fake values) and disabled.
    685      */
    686     pVM->pgm.s.fDisableMappings  = true;
    687     pVM->pgm.s.fMappingsFixed    = true;
    688     pVM->pgm.s.GCPtrMappingFixed = MM_HYPER_AREA_ADDRESS;
    689     pVM->pgm.s.cbMappingFixed    = cb;
     689    AssertReturn(!pVM->pgm.s.fMappingsFixed,            VERR_INTERNAL_ERROR_4);
     690    AssertReturn(!pVM->pgm.s.fMappingsFixedRestored,    VERR_INTERNAL_ERROR_4);
     691    if (pVM->pgm.s.fMappingsDisabled)
     692        return VINF_SUCCESS;
     693
     694    /*
     695     * Deactivate (only applies to Virtual CPU #0).
     696     */
     697    if (pVM->aCpus[0].pgm.s.pShwPageCR3R3)
     698    {
     699        pgmLock(pVM);                           /* to avoid assertions */
     700        int rc = pgmMapDeactivateCR3(pVM, pVM->aCpus[0].pgm.s.pShwPageCR3R3);
     701        pgmUnlock(pVM);
     702        AssertRCReturn(rc, rc);
     703    }
     704
     705    /*
     706     * Mark the mappings as disabled and trigger a CR3 re-sync.
     707     */
     708    pVM->pgm.s.fMappingsDisabled = true;
    690709    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
    691710    {
     
    699718/**
    700719 * Unfixes the mappings.
    701  * After calling this function mapping conflict detection will be enabled.
     720 *
     721 * Unless PGMR3MappingsDisable is in effect, mapping conflict detection will be
     722 * enabled after this call.  If the mappings are fixed, a full CR3 resync will
     723 * take place afterwards.
    702724 *
    703725 * @returns VBox status code.
     
    706728VMMR3DECL(int) PGMR3MappingsUnfix(PVM pVM)
    707729{
    708     Log(("PGMR3MappingsUnfix: fMappingsFixed=%d\n", pVM->pgm.s.fMappingsFixed));
    709 
    710     /* Ignore in VT-x/AMD-V mode. */
    711     if (HWACCMIsEnabled(pVM))
    712         return VINF_SUCCESS;
    713 
    714     pVM->pgm.s.fMappingsFixed    = false;
    715     pVM->pgm.s.GCPtrMappingFixed = 0;
    716     pVM->pgm.s.cbMappingFixed    = 0;
    717     for (VMCPUID i = 0; i < pVM->cCpus; i++)
    718     {
    719         PVMCPU pVCpu = &pVM->aCpus[i];
    720         VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
     730    Log(("PGMR3MappingsUnfix: fMappingsFixed=%RTbool fMappingsDisabled=%RTbool\n", pVM->pgm.s.fMappingsFixed, pVM->pgm.s.fMappingsDisabled));
     731    if (   pgmMapAreMappingsEnabled(&pVM->pgm.s)
     732        && (    pVM->pgm.s.fMappingsFixed
     733            ||  pVM->pgm.s.fMappingsFixedRestored)
     734       )
     735    {
     736        bool const fResyncCR3 = pVM->pgm.s.fMappingsFixed;
     737
     738        pVM->pgm.s.fMappingsFixed           = false;
     739        pVM->pgm.s.fMappingsFixedRestored   = false;
     740        pVM->pgm.s.GCPtrMappingFixed        = 0;
     741        pVM->pgm.s.cbMappingFixed           = 0;
     742
     743        if (fResyncCR3)
     744            for (VMCPUID i = 0; i < pVM->cCpus; i++)
     745                VMCPU_FF_SET(&pVM->aCpus[i], VMCPU_FF_PGM_SYNC_CR3);
    721746    }
    722747    return VINF_SUCCESS;
     
    725750
    726751/**
     752 * Checks if the mappings needs re-fixing after a restore.
     753 *
     754 * @returns true if they need, false if not.
     755 * @param   pVM                 The VM handle.
     756 */
     757VMMR3DECL(bool) PGMR3MappingsNeedReFixing(PVM pVM)
     758{
     759    VM_ASSERT_VALID_EXT_RETURN(pVM, false);
     760    return pVM->pgm.s.fMappingsFixedRestored;
     761}
     762
     763
     764/**
    727765 * Map pages into the intermediate context (switcher code).
    728  * These pages are mapped at both the give virtual address and at
    729  * the physical address (for identity mapping).
     766 *
     767 * These pages are mapped at both the give virtual address and at the physical
     768 * address (for identity mapping).
    730769 *
    731770 * @returns VBox status code.
     
    955994         */
    956995        pVM->pgm.s.pInterPD->a[iOldPDE].u        = 0;
     996
    957997        /*
    958998         * PAE.
     
    10281068 * @param   pMapping            The mapping to relocate.
    10291069 * @param   GCPtrOldMapping     The address of the start of the old mapping.
     1070 *                              NIL_RTGCPTR if not currently mapped.
    10301071 * @param   GCPtrNewMapping     The address of the start of the new mapping.
    10311072 */
    1032 void pgmR3MapRelocate(PVM pVM, PPGMMAPPING pMapping, RTGCPTR GCPtrOldMapping, RTGCPTR GCPtrNewMapping)
    1033 {
    1034     unsigned iPDOld = GCPtrOldMapping >> X86_PD_SHIFT;
    1035     unsigned iPDNew = GCPtrNewMapping >> X86_PD_SHIFT;
    1036 
     1073static void pgmR3MapRelocate(PVM pVM, PPGMMAPPING pMapping, RTGCPTR GCPtrOldMapping, RTGCPTR GCPtrNewMapping)
     1074{
    10371075    Log(("PGM: Relocating %s from %RGv to %RGv\n", pMapping->pszDesc, GCPtrOldMapping, GCPtrNewMapping));
    1038     AssertMsg(((unsigned)iPDOld << X86_PD_SHIFT) == pMapping->GCPtr, ("%RGv vs %RGv\n", (RTGCPTR)((unsigned)iPDOld << X86_PD_SHIFT), pMapping->GCPtr));
     1076    AssertMsg(GCPtrOldMapping == pMapping->GCPtr, ("%RGv vs %RGv\n", GCPtrOldMapping, pMapping->GCPtr));
     1077    AssertMsg((GCPtrOldMapping >> X86_PD_SHIFT) < X86_PG_ENTRIES, ("%RGv\n", GCPtrOldMapping));
     1078    AssertMsg((GCPtrNewMapping >> X86_PD_SHIFT) < X86_PG_ENTRIES, ("%RGv\n", GCPtrOldMapping));
    10391079
    10401080    /*
    10411081     * Relocate the page table(s).
    10421082     */
    1043     pgmR3MapClearPDEs(pVM, pMapping, iPDOld);
    1044     pgmR3MapSetPDEs(pVM, pMapping, iPDNew);
     1083    if (GCPtrOldMapping != NIL_RTGCPTR)
     1084        pgmR3MapClearPDEs(pVM, pMapping, GCPtrOldMapping >> X86_PD_SHIFT);
     1085    pgmR3MapSetPDEs(pVM, pMapping, GCPtrNewMapping >> X86_PD_SHIFT);
    10451086
    10461087    /*
     
    10601101
    10611102    /* Find mapping which >= than pMapping. */
    1062     RTGCPTR     GCPtrNew = iPDNew << X86_PD_SHIFT;
     1103    RTGCPTR     GCPtrNew = GCPtrNewMapping;
    10631104    PPGMMAPPING pPrev = NULL;
    10641105    pCur = pVM->pgm.s.pMappingsR3;
     
    11191160     * Callback to execute the relocation.
    11201161     */
    1121     pMapping->pfnRelocate(pVM, iPDOld << X86_PD_SHIFT, iPDNew << X86_PD_SHIFT, PGMRELOCATECALL_RELOCATE, pMapping->pvUser);
     1162    pMapping->pfnRelocate(pVM, GCPtrOldMapping, GCPtrNewMapping, PGMRELOCATECALL_RELOCATE, pMapping->pvUser);
    11221163}
    11231164
     
    12021243         * Ask for the mapping.
    12031244         */
    1204         RTGCPTR GCPtrNewMapping = iPDNew << X86_PD_SHIFT;
     1245        RTGCPTR GCPtrNewMapping = (RTGCPTR32)iPDNew << X86_PD_SHIFT;
    12051246
    12061247        if (pMapping->pfnRelocate(pVM, GCPtrOldMapping, GCPtrNewMapping, PGMRELOCATECALL_SUGGEST, pMapping->pvUser))
     
    12901331             * Ask for the mapping.
    12911332             */
    1292             RTGCPTR GCPtrNewMapping = ((RTGCPTR32)iPDPTE << X86_PDPT_SHIFT) + (iPDNew << X86_PD_PAE_SHIFT);
     1333            RTGCPTR GCPtrNewMapping = ((RTGCPTR32)iPDPTE << X86_PDPT_SHIFT) + ((RTGCPTR32)iPDNew << X86_PD_PAE_SHIFT);
    12931334
    12941335            if (pMapping->pfnRelocate(pVM, GCPtrOldMapping, GCPtrNewMapping, PGMRELOCATECALL_SUGGEST, pMapping->pvUser))
     
    14001441DECLCALLBACK(void) pgmR3MapInfo(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs)
    14011442{
    1402     pHlp->pfnPrintf(pHlp, pVM->pgm.s.fMappingsFixed
    1403                     ? "\nThe mappings are FIXED.\n"
    1404                     : "\nThe mappings are FLOATING.\n");
     1443    if (pVM->pgm.s.fMappingsDisabled)
     1444        pHlp->pfnPrintf(pHlp, "\nThe mappings are DISABLED.\n");
     1445    else if (pVM->pgm.s.fMappingsFixed)
     1446        pHlp->pfnPrintf(pHlp, "\nThe mappings are FIXED: %RGv-%RGv\n",
     1447                        pVM->pgm.s.GCPtrMappingFixed, pVM->pgm.s.GCPtrMappingFixed + pVM->pgm.s.cbMappingFixed - 1);
     1448    else if (pVM->pgm.s.fMappingsFixedRestored)
     1449        pHlp->pfnPrintf(pHlp, "\nThe mappings are FLOATING-RESTORED-FIXED: %RGv-%RGv\n",
     1450                        pVM->pgm.s.GCPtrMappingFixed, pVM->pgm.s.GCPtrMappingFixed + pVM->pgm.s.cbMappingFixed - 1);
     1451    else
     1452        pHlp->pfnPrintf(pHlp, "\nThe mappings are FLOATING.\n");
     1453
    14051454    PPGMMAPPING pCur;
    14061455    for (pCur = pVM->pgm.s.pMappingsR3; pCur; pCur = pCur->pNextR3)
     1456    {
    14071457        pHlp->pfnPrintf(pHlp, "%RGv - %RGv  %s\n", pCur->GCPtr, pCur->GCPtrLast, pCur->pszDesc);
    1408 }
    1409 
     1458        if (pCur->cConflicts > 0)
     1459        {
     1460            pHlp->pfnPrintf(pHlp, "  %u conflict%s: ", pCur->cConflicts, pCur->cConflicts == 1 ? "" : "s");
     1461            uint32_t cLeft = RT_MIN(pCur->cConflicts, RT_ELEMENTS(pCur->aGCPtrConflicts));
     1462            uint32_t i     = pCur->cConflicts;
     1463            while (cLeft-- > 0)
     1464            {
     1465                i = (i - 1) & (PGMMAPPING_CONFLICT_MAX - 1);
     1466                pHlp->pfnPrintf(pHlp, cLeft ? "%RGv, " : "%RGv\n", pCur->aGCPtrConflicts[i]);
     1467            }
     1468        }
     1469    }
     1470}
     1471
  • 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    }
  • trunk/src/VBox/VMM/VM.cpp

    r25838 r25935  
    10191019        rc = vmR3InitDoCompleted(pVM, VMINITCOMPLETED_RING0);
    10201020
    1021     /** todo: move this to the VMINITCOMPLETED_RING0 notification handler once implemented */
     1021    /** @todo Move this to the VMINITCOMPLETED_RING0 notification handler. */
    10221022    if (RT_SUCCESS(rc))
    10231023        rc = HWACCMR3InitFinalizeR0(pVM);
  • trunk/src/VBox/VMM/VMMAll/PGMAll.cpp

    r25915 r25935  
    723723     * Check for conflicts and pending CR3 monitoring updates.
    724724     */
    725     if (!pVM->pgm.s.fMappingsFixed)
     725    if (pgmMapAreMappingsFloating(&pVM->pgm.s))
    726726    {
    727727        if (    pgmGetMapping(pVM, GCPtrPage)
     
    763763    {
    764764        pVCpu->pgm.s.fSyncFlags &= ~PGM_SYNC_MONITOR_CR3;
    765         Assert(!pVM->pgm.s.fMappingsFixed);
     765        Assert(!pVM->pgm.s.fMappingsFixed); Assert(!pVM->pgm.s.fMappingsDisabled);
    766766    }
    767767
     
    16901690        if (RT_LIKELY(rc == VINF_SUCCESS))
    16911691        {
    1692             if (!pVM->pgm.s.fMappingsFixed)
    1693             {
     1692            if (pgmMapAreMappingsFloating(&pVM->pgm.s))
    16941693                pVCpu->pgm.s.fSyncFlags &= ~PGM_SYNC_MONITOR_CR3;
    1695             }
    16961694        }
    16971695        else
     
    17011699            pVCpu->pgm.s.GCPhysCR3 = GCPhysOldCR3;
    17021700            pVCpu->pgm.s.fSyncFlags |= PGM_SYNC_MAP_CR3;
    1703             if (!pVM->pgm.s.fMappingsFixed)
     1701            if (pgmMapAreMappingsFloating(&pVM->pgm.s))
    17041702                pVCpu->pgm.s.fSyncFlags |= PGM_SYNC_MONITOR_CR3;
    17051703        }
     
    17271725        {
    17281726            pVCpu->pgm.s.fSyncFlags &= ~PGM_SYNC_MONITOR_CR3;
    1729             Assert(!pVM->pgm.s.fMappingsFixed);
     1727            Assert(!pVM->pgm.s.fMappingsFixed); Assert(!pVM->pgm.s.fMappingsDisabled);
    17301728        }
    17311729        if (fGlobal)
     
    17641762
    17651763    /* We assume we're only called in nested paging mode. */
    1766     Assert(pVM->pgm.s.fMappingsFixed);
     1764    Assert(HWACCMIsNestedPagingActive(pVM) || pVCpu->pgm.s.enmShadowMode == PGMMODE_EPT);
     1765    Assert(pVM->pgm.s.fMappingsDisabled);
    17671766    Assert(!(pVCpu->pgm.s.fSyncFlags & PGM_SYNC_MONITOR_CR3));
    1768     Assert(HWACCMIsNestedPagingActive(pVM) || pVCpu->pgm.s.enmShadowMode == PGMMODE_EPT);
    17691767
    17701768    /*
     
    19111909        {
    19121910            pVCpu->pgm.s.fSyncFlags &= ~PGM_SYNC_MONITOR_CR3;
    1913             Assert(!pVM->pgm.s.fMappingsFixed);
     1911            Assert(!pVM->pgm.s.fMappingsFixed); Assert(!pVM->pgm.s.fMappingsDisabled);
    19141912        }
    19151913    }
  • trunk/src/VBox/VMM/VMMAll/PGMAllBth.h

    r25866 r25935  
    291291                 * The first thing we check is if we've got an undetected conflict.
    292292                 */
    293                 if (!pVM->pgm.s.fMappingsFixed)
     293                if (pgmMapAreMappingsFloating(&pVM->pgm.s))
    294294                {
    295295                    unsigned iPT = pMapping->cb >> GST_PD_SHIFT;
     
    25992599#  endif
    26002600    }
    2601 # else  /* PGM_WITHOUT_MAPPINGS */
    2602     Assert(!pgmMapAreMappingsEnabled(&pVM->pgm.s));
    2603 # endif /* PGM_WITHOUT_MAPPINGS */
     2601# endif /* !PGM_WITHOUT_MAPPINGS */
    26042602    Assert(!PdeDst.n.u1Present); /* We're only supposed to call SyncPT on PDE!P and conflicts.*/
    26052603
     
    34493447    STAM_PROFILE_STOP(&pVCpu->pgm.s.CTX_MID_Z(Stat,SyncCR3Handlers), h);
    34503448    pgmUnlock(pVM);
    3451 #endif
     3449#endif /* !NESTED && !EPT */
    34523450
    34533451#if PGM_SHW_TYPE == PGM_TYPE_NESTED || PGM_SHW_TYPE == PGM_TYPE_EPT
     
    34573455    /** @todo check if this is really necessary; the call does it as well... */
    34583456    HWACCMFlushTLB(pVCpu);
     3457    Assert(!pgmMapAreMappingsEnabled(&pVM->pgm.s));
    34593458    return VINF_SUCCESS;
    34603459
     
    34643463     * out the shadow parts when the guest modifies its tables.
    34653464     */
     3465    Assert(!pgmMapAreMappingsEnabled(&pVM->pgm.s));
    34663466    return VINF_SUCCESS;
    34673467
    34683468#else /* PGM_SHW_TYPE != PGM_TYPE_NESTED && PGM_SHW_TYPE != PGM_TYPE_EPT && PGM_SHW_TYPE != PGM_TYPE_AMD64 */
    34693469
    3470 #  ifdef PGM_WITHOUT_MAPPINGS
    3471     Assert(pVM->pgm.s.fMappingsFixed);
    3472     return VINF_SUCCESS;
     3470#  ifndef PGM_WITHOUT_MAPPINGS
     3471    /*
     3472     * Check for and resolve conflicts with our guest mappings if they
     3473     * are enabled and not fixed.
     3474     */
     3475    if (pgmMapAreMappingsFloating(&pVM->pgm.s))
     3476    {
     3477        int rc = pgmMapResolveConflicts(pVM);
     3478        Assert(rc == VINF_SUCCESS || rc == VINF_PGM_SYNC_CR3);
     3479        if (rc == VINF_PGM_SYNC_CR3)
     3480        {
     3481            LogFlow(("SyncCR3: detected conflict -> VINF_PGM_SYNC_CR3\n"));
     3482            return VINF_PGM_SYNC_CR3;
     3483        }
     3484    }
    34733485#  else
    3474     /* Nothing to do when mappings are fixed. */
    3475     if (pVM->pgm.s.fMappingsFixed)
    3476         return VINF_SUCCESS;
    3477 
    3478     int rc = PGMMapResolveConflicts(pVM);
    3479     Assert(rc == VINF_SUCCESS || rc == VINF_PGM_SYNC_CR3);
    3480     if (rc == VINF_PGM_SYNC_CR3)
    3481     {
    3482         LogFlow(("SyncCR3: detected conflict -> VINF_PGM_SYNC_CR3\n"));
    3483         return VINF_PGM_SYNC_CR3;
    3484     }
     3486    Assert(!pgmMapAreMappingsEnabled(&pVM->pgm.s));
    34853487#  endif
    34863488    return VINF_SUCCESS;
  • trunk/src/VBox/VMM/VMMAll/PGMAllMap.cpp

    r22890 r25935  
    389389    Log(("pgmMapClearShadowPDEs: old pde %x (cPTs=%x) (mappings enabled %d) fDeactivateCR3=%RTbool\n", iOldPDE, pMap->cPTs, pgmMapAreMappingsEnabled(&pVM->pgm.s), fDeactivateCR3));
    390390
     391    /*
     392     * Skip this if disabled or if it doesn't apply.
     393     */
    391394    if (    !pgmMapAreMappingsEnabled(&pVM->pgm.s)
    392395        ||  pVM->cCpus > 1)
     
    602605        return;
    603606
     607    /* This only applies to raw mode where we only support 1 VCPU. */
    604608    Assert(pVM->cCpus == 1);
    605 
    606     /* This only applies to raw mode where we only support 1 VCPU. */
    607609    PVMCPU pVCpu = VMMGetCpu0(pVM);
    608610    Assert(pVCpu->pgm.s.CTX_SUFF(pShwPageCR3));
     
    633635{
    634636    /*
    635      * Can skip this if mappings are disabled.
     637     * Skip this if disabled or if it doesn't apply.
    636638     */
    637639    if (    !pgmMapAreMappingsEnabled(&pVM->pgm.s)
     
    639641        return VINF_SUCCESS;
    640642
    641     /* Note. A log flush (in RC) can cause problems when called from MapCR3 (inconsistent state will trigger assertions). */
    642     Log4(("pgmMapActivateCR3: fixed mappings=%d idxShwPageCR3=%#x\n", pVM->pgm.s.fMappingsFixed, pShwPageCR3 ? pShwPageCR3->idx : NIL_PGMPOOL_IDX));
     643    /* Note! This might not be logged successfully in RC because we usually
     644             cannot flush the log at this point. */
     645    Log4(("pgmMapActivateCR3: fixed mappings=%RTbool idxShwPageCR3=%#x\n", pVM->pgm.s.fMappingsFixed, pShwPageCR3 ? pShwPageCR3->idx : NIL_PGMPOOL_IDX));
    643646
    644647#ifdef VBOX_STRICT
     
    669672{
    670673    /*
    671      * Can skip this if mappings are disabled.
     674     * Skip this if disabled or if it doesn't apply.
    672675     */
    673676    if (    !pgmMapAreMappingsEnabled(&pVM->pgm.s)
     
    702705     * Can skip this if mappings are safely fixed.
    703706     */
    704     if (pVM->pgm.s.fMappingsFixed)
     707    if (!pgmMapAreMappingsFloating(&pVM->pgm.s))
    705708        return false;
    706709
     
    788791
    789792/**
    790  * Checks and resolves (ring 3 only) guest conflicts with VMM GC mappings.
     793 * Checks and resolves (ring 3 only) guest conflicts with the guest mappings.
    791794 *
    792795 * @returns VBox status.
    793796 * @param   pVM                 The virtual machine.
    794797 */
    795 VMMDECL(int) PGMMapResolveConflicts(PVM pVM)
    796 {
    797     /*
    798      * Can skip this if mappings are safely fixed.
    799      */
    800     if (pVM->pgm.s.fMappingsFixed)
    801         return VINF_SUCCESS;
    802 
     798int pgmMapResolveConflicts(PVM pVM)
     799{
     800    /* The caller is expected to check these two conditions. */
     801    Assert(!pVM->pgm.s.fMappingsFixed);
     802    Assert(!pVM->pgm.s.fMappingsDisabled);
     803
     804    /* This only applies to raw mode where we only support 1 VCPU. */
    803805    Assert(pVM->cCpus == 1);
    804 
    805     /* This only applies to raw mode where we only support 1 VCPU. */
    806     PVMCPU pVCpu = &pVM->aCpus[0];
    807 
    808     PGMMODE const enmGuestMode = PGMGetGuestMode(pVCpu);
     806    PVMCPU          pVCpu        = &pVM->aCpus[0];
     807    PGMMODE const   enmGuestMode = PGMGetGuestMode(pVCpu);
    809808    Assert(enmGuestMode <= PGMMODE_PAE_NX);
    810809
  • trunk/src/VBox/VMM/testcase/tstVMStructGC.cpp

    r25891 r25935  
    556556    GEN_CHECK_OFF(PGM, fFinalizedMappings);
    557557    GEN_CHECK_OFF(PGM, fMappingsFixed);
     558    GEN_CHECK_OFF(PGM, fMappingsFixedRestored);
     559    GEN_CHECK_OFF(PGM, fMappingsDisabled);
    558560    GEN_CHECK_OFF(PGM, GCPtrMappingFixed);
    559561    GEN_CHECK_OFF(PGM, cbMappingFixed);
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette