VirtualBox

Changeset 16898 in vbox


Ignore:
Timestamp:
Feb 18, 2009 12:27:00 PM (16 years ago)
Author:
vboxsync
Message:

VBOX_WITH_PGMPOOL_PAGING_ONLY: simplified SyncCR3; introduced PGMMapResolveConflicts

Location:
trunk
Files:
4 edited

Legend:

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

    r16890 r16898  
    331331VMMDECL(int)        PGMMapActivateAll(PVM pVM);
    332332VMMDECL(int)        PGMMapDeactivateAll(PVM pVM);
    333 VMMDECL(bool)       PGMMapHasConflicts(PVM pVM, bool fResolveConflicts);
    334 
     333#ifndef IN_RING0
     334VMMDECL(bool)       PGMMapHasConflicts(PVM pVM);
     335VMMDECL(int)        PGMMapResolveConflicts(PVM pVM);
     336#endif
    335337VMMDECL(int)        PGMShwGetPage(PVM pVM, RTGCPTR GCPtr, uint64_t *pfFlags, PRTHCPHYS pHCPhys);
    336338VMMDECL(int)        PGMShwSetPage(PVM pVM, RTGCPTR GCPtr, size_t cb, uint64_t fFlags);
  • trunk/src/VBox/VMM/EM.cpp

    r16890 r16898  
    26072607                  ("Tried to execute code with IF at EIP=%08x!\n", pCtx->eip));
    26082608        if (    !VM_FF_ISPENDING(pVM, VM_FF_PGM_SYNC_CR3 | VM_FF_PGM_SYNC_CR3_NON_GLOBAL)
    2609             &&  PGMMapHasConflicts(pVM, false))
     2609            &&  PGMMapHasConflicts(pVM))
    26102610        {
    26112611            AssertMsgFailed(("We should not get conflicts any longer!!!\n"));
     
    27202720         */
    27212721        if (    !VM_FF_ISPENDING(pVM, VM_FF_PGM_SYNC_CR3 | VM_FF_PGM_SYNC_CR3_NON_GLOBAL)
    2722             &&  PGMMapHasConflicts(pVM, false))
     2722            &&  PGMMapHasConflicts(pVM))
    27232723        {
    27242724            AssertMsgFailed(("We should not get conflicts any longer!!!\n"));
  • trunk/src/VBox/VMM/VMMAll/PGMAllBth.h

    r16866 r16898  
    32993299
    33003300# ifdef VBOX_WITH_PGMPOOL_PAGING_ONLY
     3301#  ifdef PGM_WITHOUT_MAPPINGS
     3302    Assert(!pVM->pgm.s.fMappingsFixed);
     3303    return VINF_SUCCESS;
     3304#  else
    33013305    /* Nothing to do when mappings are fixed. */
    33023306    if (pVM->pgm.s.fMappingsFixed)
    33033307        return VINF_SUCCESS;
    3304 # endif
    3305 
     3308
     3309    int rc = PGMMapResolveConflicts(pVM);
     3310    Assert(rc == VINF_SUCCESS || rc == VINF_PGM_SYNC_CR3);
     3311    if (rc == VINF_PGM_SYNC_CR3)
     3312    {
     3313        LogFlow(("SyncCR3: detected conflict -> VINF_PGM_SYNC_CR3\n"));
     3314        return VINF_PGM_SYNC_CR3;
     3315    }
     3316#  endif
     3317    return VINF_SUCCESS;
     3318# else
    33063319    /*
    33073320     * PAE and 32-bit legacy mode (shadow).
     
    33413354    PPGMPOOL    pPool         = pVM->pgm.s.CTX_SUFF(pPool);
    33423355
    3343 #  ifdef VBOX_WITH_PGMPOOL_PAGING_ONLY
    3344     /* Mappings are always enabled when we get here. */
    3345     Assert(pgmMapAreMappingsEnabled(&pVM->pgm.s));
    3346     pMapping      = pVM->pgm.s.CTX_SUFF(pMappings);
    3347     iPdNoMapping  = (pMapping) ? (pMapping->GCPtr >> GST_PD_SHIFT) : ~0U;
    3348 #  else
    33493356    /* Only check mappings if they are supposed to be put into the shadow page table. */
    33503357    if (pgmMapAreMappingsEnabled(&pVM->pgm.s))
     
    33583365        iPdNoMapping  = ~0U;
    33593366    }
    3360 #  endif
    33613367
    33623368#  if PGM_GST_TYPE == PGM_TYPE_PAE
     
    33693375        PX86PDPT        pPdptDst  = pgmShwGetPaePDPTPtr(&pVM->pgm.s);
    33703376
    3371 #   ifndef VBOX_WITH_PGMPOOL_PAGING_ONLY
    33723377        if (pPDSrc == NULL)
    33733378        {
     
    33913396            continue;
    33923397        }
    3393 #    endif /* !VBOX_WITH_PGMPOOL_PAGING_ONLY */
    33943398#  else  /* PGM_GST_TYPE != PGM_TYPE_PAE */
    33953399    {
     
    34693473#  endif /* (PGM_GST_TYPE != PGM_TYPE_32BIT && PGM_GST_TYPE != PGM_TYPE_PAE) || PGM_WITHOUT_MAPPINGS */
    34703474
    3471 #  ifdef VBOX_WITH_PGMPOOL_PAGING_ONLY
    3472                 /* advance */
    3473 #   if PGM_SHW_TYPE == PGM_TYPE_PAE && PGM_GST_TYPE == PGM_TYPE_32BIT
    3474                 pPDEDst += 2;
    3475 #   else
    3476                 pPDEDst++;
    3477 #   endif
    3478 #  else
    34793475                /*
    34803476                 * Sync page directory entry.
     
    35653561                    pPDEDst++;
    35663562                } /* foreach 2MB PAE PDE in 4MB guest PDE */
    3567 #  endif /* !VBOX_WITH_PGMPOOL_PAGING_ONLY */
    35683563            }
    35693564#  if PGM_GST_TYPE == PGM_TYPE_PAE
     
    35763571                 * Check if there is any page directory to mark not present here.
    35773572                 */
    3578 #  ifdef VBOX_WITH_PGMPOOL_PAGING_ONLY
    3579                 /* advance */
    3580 #   if PGM_SHW_TYPE == PGM_TYPE_PAE && PGM_GST_TYPE == PGM_TYPE_32BIT
    3581                 pPDEDst += 2;
    3582 #   else
    3583                 pPDEDst++;
    3584 #   endif
    3585 #  else
    35863573#   if PGM_SHW_TYPE == PGM_TYPE_PAE && PGM_GST_TYPE == PGM_TYPE_32BIT
    35873574                for (unsigned i = 0, iPdShw = iPD * 2; i < 2; i++, iPdShw++) /* pray that the compiler unrolls this */
     
    36003587                    pPDEDst++;
    36013588                }
    3602 #  endif /* !VBOX_WITH_PGMPOOL_PAGING_ONLY */
    36033589            }
    36043590            else
     
    36113597
    36123598                Assert(pgmMapAreMappingsEnabled(&pVM->pgm.s));
    3613 #   ifndef VBOX_WITH_PGMPOOL_PAGING_ONLY
    36143599                if (pVM->pgm.s.fMappingsFixed)
    36153600                {
     
    36193604                }
    36203605                else
    3621 #   endif /* !VBOX_WITH_PGMPOOL_PAGING_ONLY */
    36223606                {
    36233607                    /*
     
    36863670    return VINF_SUCCESS;
    36873671# endif
     3672#endif /* VBOX_WITH_PGMPOOL_PAGING_ONLY */
    36883673#endif /* PGM_SHW_TYPE != PGM_TYPE_NESTED && PGM_SHW_TYPE != PGM_TYPE_EPT && PGM_SHW_TYPE != PGM_TYPE_AMD64 */
    36893674}
  • trunk/src/VBox/VMM/VMMAll/PGMAllMap.cpp

    r16892 r16898  
    525525}
    526526
     527#ifndef IN_RING0
    527528/**
    528529 * Checks guest PD for conflicts with VMM GC mappings.
     
    531532 * @returns false if not.
    532533 * @param   pVM                 The virtual machine.
    533  * @param   fResolveConflicts   Whether to resolve found conflicts or not (only valid in ring 3)
    534  */
    535 VMMDECL(bool) PGMMapHasConflicts(PVM pVM, bool fResolveConflicts)
     534 */
     535VMMDECL(bool) PGMMapHasConflicts(PVM pVM)
    536536{
    537537    /*
     
    564564                {
    565565                    STAM_COUNTER_INC(&pVM->pgm.s.StatR3DetectedConflicts);
     566
    566567                    Log(("PGMHasMappingConflicts: Conflict was detected at %08RX32 for mapping %s (32 bits)\n"
    567568                         "                        iPDE=%#x iPT=%#x PDE=%RGp.\n",
     
    602603    return false;
    603604}
     605
     606/**
     607 * Checks and resolves (ring 3 only) guest conflicts with VMM GC mappings.
     608 *
     609 * @returns VBox status.
     610 * @param   pVM                 The virtual machine.
     611 */
     612VMMDECL(int) PGMMapResolveConflicts(PVM pVM)
     613{
     614    /*
     615     * Can skip this if mappings are safely fixed.
     616     */
     617    if (pVM->pgm.s.fMappingsFixed)
     618        return VINF_SUCCESS;
     619
     620    PGMMODE const enmGuestMode = PGMGetGuestMode(pVM);
     621    Assert(enmGuestMode <= PGMMODE_PAE_NX);
     622
     623    /*
     624     * Iterate mappings.
     625     */
     626    if (enmGuestMode == PGMMODE_32_BIT)
     627    {
     628        /*
     629         * Resolve the page directory.
     630         */
     631        PX86PD pPD = pgmGstGet32bitPDPtr(&pVM->pgm.s);
     632        Assert(pPD);
     633
     634        for (PPGMMAPPING pCur = pVM->pgm.s.CTX_SUFF(pMappings); pCur; pCur = pCur->CTX_SUFF(pNext))
     635        {
     636            unsigned iPDE = pCur->GCPtr >> X86_PD_SHIFT;
     637            unsigned iPT = pCur->cPTs;
     638            while (iPT-- > 0)
     639            {
     640                if (    pPD->a[iPDE + iPT].n.u1Present /** @todo PGMGstGetPDE. */
     641                    &&  (pVM->fRawR0Enabled || pPD->a[iPDE + iPT].n.u1User))
     642                {
     643                    STAM_COUNTER_INC(&pVM->pgm.s.StatR3DetectedConflicts);
     644
     645                    Log(("PGMHasMappingConflicts: Conflict was detected at %08RX32 for mapping %s (32 bits)\n"
     646                         "                        iPDE=%#x iPT=%#x PDE=%RGp.\n",
     647                        (iPT + iPDE) << X86_PD_SHIFT, pCur->pszDesc,
     648                        iPDE, iPT, pPD->a[iPDE + iPT].au32[0]));
     649#ifdef IN_RING3
     650                    int rc = pgmR3SyncPTResolveConflict(pVM, pCur, pPD, iPDE << X86_PD_SHIFT);
     651                    AssertRCReturn(rc, rc);
     652
     653                    /*
     654                     * Update pCur.
     655                     */
     656                    pCur = pVM->pgm.s.CTX_SUFF(pMappings);
     657                    while (pCur && pCur->GCPtr < (iPDE << X86_PD_SHIFT))
     658                        pCur = pCur->CTX_SUFF(pNext);
     659                    break;
     660#else
     661                    return VINF_PGM_SYNC_CR3;
     662#endif
     663                }
     664            }
     665            if (!pCur)
     666                break;
     667        }
     668    }
     669    else if (   enmGuestMode == PGMMODE_PAE
     670             || enmGuestMode == PGMMODE_PAE_NX)
     671    {
     672        for (PPGMMAPPING pCur = pVM->pgm.s.CTX_SUFF(pMappings); pCur; pCur = pCur->CTX_SUFF(pNext))
     673        {
     674            RTGCPTR   GCPtr = pCur->GCPtr;
     675
     676            unsigned  iPT = pCur->cb >> X86_PD_PAE_SHIFT;
     677            while (iPT-- > 0)
     678            {
     679                X86PDEPAE Pde = pgmGstGetPaePDE(&pVM->pgm.s, GCPtr);
     680
     681                if (   Pde.n.u1Present
     682                    && (pVM->fRawR0Enabled || Pde.n.u1User))
     683                {
     684                    STAM_COUNTER_INC(&pVM->pgm.s.StatR3DetectedConflicts);
     685                    Log(("PGMHasMappingConflicts: Conflict was detected at %RGv for mapping %s (PAE)\n"
     686                         "                        PDE=%016RX64.\n",
     687                        GCPtr, pCur->pszDesc, Pde.u));
     688#ifdef IN_RING3
     689                    int rc = pgmR3SyncPTResolveConflictPAE(pVM, pCur, GCPtr);
     690                    AssertRCReturn(rc, rc);
     691
     692                    /*
     693                     * Update pCur.
     694                     */
     695                    pCur = pVM->pgm.s.CTX_SUFF(pMappings);
     696                    while (pCur && pCur->GCPtr < GCPtr)
     697                        pCur = pCur->CTX_SUFF(pNext);
     698                    break;
     699#else
     700                    return VINF_PGM_SYNC_CR3;
     701#endif
     702                }
     703                GCPtr += (1 << X86_PD_PAE_SHIFT);
     704            }
     705            if (!pCur)
     706                break;
     707        }
     708    }
     709    else
     710        AssertFailed();
     711
     712    return VINF_SUCCESS;
     713}
     714#endif /* IN_RING0 */
     715
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