VirtualBox

Changeset 14378 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Nov 19, 2008 7:36:20 PM (16 years ago)
Author:
vboxsync
Message:

#1865: ring-0 mapping cache, code in progress.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR0/PGMR0DynMap.cpp

    r14376 r14378  
    3232#include <iprt/assert.h>
    3333#include <iprt/cpuset.h>
     34#include <iprt/memobj.h>
     35#include <iprt/mp.h>
    3436#include <iprt/spinlock.h>
    3537#include <iprt/semaphore.h>
     
    129131    /** Array containing a copy of the original page tables.
    130132     * The entries are either X86PTE or X86PTEPAE according to fLegacyMode. */
    131     void                       *pvSavedPTs;
     133    void                       *pvSavedPTEs;
     134    /** List of segments. */
     135    PPGMR0DYNMAPSEG             pSegHead;
    132136} PGMR0DYNMAP;
    133137/** Pointer to the ring-0 dynamic mapping cache */
     
    400404
    401405/**
     406 * Shoots down the TLBs for all the cache pages, pgmR0DynMapTearDown helper.
     407 *
     408 * @param   idCpu           The current CPU.
     409 * @param   pvUser1         The dynamic mapping cache instance.
     410 * @param   pvUser2         Unused, NULL.
     411 */
     412static DECLCALLBACK(void) pgmR0DynMapShootDownTlbs(RTCPUID idCpu, void *pvUser1, void *pvUser2)
     413{
     414    Assert(!pvUser2);
     415    PPGMR0DYNMAP        pThis   = (PPGMR0DYNMAP)pvUser1;
     416    AssertPtr(pThis == g_pPGMR0DynMap);
     417    PPGMR0DYNMAPENTRY   paPages = pThis->paPages;
     418    uint32_t            iPage   = pThis->cPages;
     419    while (iPage-- > 0)
     420        ASMInvalidatePage(paPages[iPage].pvPage);
     421}
     422
     423
     424/**
    402425 * Called by PGMR0DynMapTermVM under the init lock.
    403426 *
     
    407430static void pgmR0DynMapTearDown(PPGMR0DYNMAP pThis)
    408431{
     432    /*
     433     * Restore the original page table entries
     434     */
     435    PPGMR0DYNMAPENTRY   paPages = pThis->paPages;
     436    uint32_t            iPage   = pThis->cPages;
     437    if (pThis->fLegacyMode)
     438    {
     439        X86PGUINT const    *paSavedPTEs = (X86PGUINT const *)pThis->pvSavedPTEs;
     440        while (iPage-- > 0)
     441        {
     442            X86PGUINT       uOld  = paPages[iPage].uPte.pLegacy->u;
     443            X86PGUINT       uOld2 = uOld; NOREF(uOld2);
     444            X86PGUINT       uNew  = paSavedPTEs[iPage];
     445            while (!ASMAtomicCmpXchgExU32(&paPages[iPage].uPte.pLegacy->u, uNew, uOld, &uOld))
     446                AssertMsgFailed(("uOld=%#x uOld2=%#x uNew=%#x\n", uOld, uOld2, uNew));
     447        }
     448    }
     449    else
     450    {
     451        X86PGPAEUINT const *paSavedPTEs = (X86PGPAEUINT const *)pThis->pvSavedPTEs;
     452        while (iPage-- > 0)
     453        {
     454            X86PGPAEUINT    uOld  = paPages[iPage].uPte.pPae->u;
     455            X86PGPAEUINT    uOld2 = uOld; NOREF(uOld2);
     456            X86PGPAEUINT    uNew  = paSavedPTEs[iPage];
     457            while (!ASMAtomicCmpXchgExU64(&paPages[iPage].uPte.pPae->u, uNew, uOld, &uOld))
     458                AssertMsgFailed(("uOld=%#llx uOld2=%#llx uNew=%#llx\n", uOld, uOld2, uNew));
     459        }
     460    }
     461
     462    /*
     463     * Shoot down the TLBs on all CPUs before freeing them.
     464     * If RTMpOnAll fails, make sure the TLBs are invalidated on the current CPU at least.
     465     */
     466    int rc = RTMpOnAll(pgmR0DynMapShootDownTlbs, pThis, NULL);
     467    AssertRC(rc);
     468    if (RT_FAILURE(rc))
     469    {
     470        iPage = pThis->cPages;
     471        while (iPage-- > 0)
     472            ASMInvalidatePage(paPages[iPage].pvPage);
     473    }
     474
     475    /*
     476     * Free the segments.
     477     */
     478    while (pThis->pSegHead)
     479    {
     480        PPGMR0DYNMAPSEG pSeg = pThis->pSegHead;
     481        pThis->pSegHead = pSeg->pNext;
     482
     483        int rc;
     484        rc = RTR0MemObjFree(pSeg->hMemObjPT, true /* fFreeMappings */); AssertRC(rc);
     485        pSeg->hMemObjPT = NIL_RTR0MEMOBJ;
     486        rc = RTR0MemObjFree(pSeg->hMemObj,   true /* fFreeMappings */); AssertRC(rc);
     487        pSeg->hMemObj   = NIL_RTR0MEMOBJ;
     488        pSeg->pNext     = NULL;
     489        pSeg->iPage     = UINT32_MAX;
     490        pSeg->cPages    = 0;
     491        RTMemFree(pSeg);
     492    }
     493
     494    /*
     495     * Free the arrays and restore the initial state.
     496     * The cLoadMax value is left behind for the next setup.
     497     */
     498    RTMemFree(pThis->paPages);
     499    pThis->paPages = NULL;
     500    RTMemFree(pThis->pvSavedPTEs);
     501    pThis->pvSavedPTEs = NULL;
     502    pThis->cPages = 0;
     503    pThis->cLoad = 0;
    409504}
    410505
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