VirtualBox

Changeset 82555 in vbox for trunk/src


Ignore:
Timestamp:
Dec 11, 2019 11:56:54 PM (5 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
135429
Message:

PGMPool,MM: Use ring-0 mapping while in ring-0, so let the page pool do its own allocations rather than going through MMPage*. The MMPage* code is mostly code, but we still need it for a dummy page allocation. I'll address this tomorrow. bugref:9528

Location:
trunk/src/VBox/VMM
Files:
1 added
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/Makefile.kmk

    r82313 r82555  
    490490        VMMR0/PDMR0Driver.cpp \
    491491        VMMR0/PGMR0.cpp \
     492        VMMR0/PGMR0Pool.cpp \
    492493        VMMR0/PGMR0SharedPage.cpp \
    493494        VMMR0/VMMR0.cpp \
     
    514515        VMMAll/MMAll.cpp \
    515516        VMMAll/MMAllHyper.cpp \
    516         VMMAll/MMAllPagePool.cpp \
    517517        VMMAll/NEMAll.cpp \
    518518        VMMAll/PDMAll.cpp \
  • trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp

    r80333 r82555  
    49744974        STAM_PROFILE_ADV_SUSPEND(&pPool->StatAlloc, a);
    49754975#ifdef IN_RING3
    4976         int rc = PGMR3PoolGrow(pVM);
     4976        int rc = PGMR3PoolGrow(pVM, VMMGetCpu(pVM));
    49774977#else
    49784978        int rc = VMMRZCallRing3NoCpu(pVM, VMMCALLRING3_PGM_POOL_GROW, 0);
     
    51895189    PGM_LOCK_ASSERT_OWNER(pPool->CTX_SUFF(pVM));
    51905190    return (PPGMPOOLPAGE)RTAvloHCPhysGet(&pPool->HCPhysTree, HCPhys & X86_PTE_PAE_PG_MASK);
     5191}
     5192
     5193
     5194/**
     5195 * Internal worker for PGM_HCPHYS_2_PTR.
     5196 *
     5197 * @returns VBox status code.
     5198 * @param   pVM         The cross context VM structure.
     5199 * @param   HCPhys      The HC physical address of the shadow page.
     5200 * @param   ppv         Where to return the address.
     5201 */
     5202int pgmPoolHCPhys2Ptr(PVM pVM, RTHCPHYS HCPhys, void **ppv)
     5203{
     5204    PPGMPOOLPAGE pPage = (PPGMPOOLPAGE)RTAvloHCPhysGet(&pVM->pgm.s.CTX_SUFF(pPool)->HCPhysTree, HCPhys & X86_PTE_PAE_PG_MASK);
     5205    AssertMsgReturn(pPage && pPage->enmKind != PGMPOOLKIND_FREE,
     5206                    ("HCPhys=%RHp pPage=%p idx=%d\n", HCPhys, pPage, (pPage) ? pPage->idx : 0),
     5207                    VERR_PGM_POOL_GET_PAGE_FAILED);
     5208    *ppv = (uint8_t *)pPage->CTX_SUFF(pvPage) + (HCPhys & PAGE_OFFSET_MASK);
     5209    return VINF_SUCCESS;
    51915210}
    51925211
     
    53335352        PPGMPOOLPAGE pPage = &pPool->aPages[i];
    53345353
    5335         Assert(pPage->Core.Key == MMPage2Phys(pVM, pPage->pvPageR3));
    53365354        if (pPage->fMonitored)
    53375355            pgmPoolMonitorFlush(pPool, pPage);
  • trunk/src/VBox/VMM/VMMR0/GVMMR0.cpp

    r80641 r82555  
    902902                        RT_BZERO(pGVM, cPages << PAGE_SHIFT);
    903903                        gvmmR0InitPerVMData(pGVM, iHandle, cCpus, pSession);
     904                        pGVM->gvmm.s.VMMemObj  = hVMMemObj;
    904905                        GMMR0InitPerVMData(pGVM);
     906                        rc = PGMR0InitPerVMData(pGVM);
    905907                        PDMR0InitPerVMData(pGVM);
    906908                        IOMR0InitPerVMData(pGVM);
    907                         pGVM->gvmm.s.VMMemObj  = hVMMemObj;
    908 
    909                         /*
    910                          * Allocate page array.
    911                          * This currently have to be made available to ring-3, but this is should change eventually.
    912                          */
    913                         rc = RTR0MemObjAllocPage(&pGVM->gvmm.s.VMPagesMemObj, cPages * sizeof(SUPPAGE), false /* fExecutable */);
    914909                        if (RT_SUCCESS(rc))
    915910                        {
    916                             PSUPPAGE paPages = (PSUPPAGE)RTR0MemObjAddress(pGVM->gvmm.s.VMPagesMemObj); AssertPtr(paPages);
    917                             for (uint32_t iPage = 0; iPage < cPages; iPage++)
    918                             {
    919                                 paPages[iPage].uReserved = 0;
    920                                 paPages[iPage].Phys = RTR0MemObjGetPagePhysAddr(pGVM->gvmm.s.VMMemObj, iPage);
    921                                 Assert(paPages[iPage].Phys != NIL_RTHCPHYS);
    922                             }
    923 
    924911                            /*
    925                              * Map the page array, VM and VMCPU structures into ring-3.
     912                             * Allocate page array.
     913                             * This currently have to be made available to ring-3, but this is should change eventually.
    926914                             */
    927                             AssertCompileSizeAlignment(VM, PAGE_SIZE);
    928                             rc = RTR0MemObjMapUserEx(&pGVM->gvmm.s.VMMapObj, pGVM->gvmm.s.VMMemObj, (RTR3PTR)-1, 0,
    929                                                      RTMEM_PROT_READ | RTMEM_PROT_WRITE, NIL_RTR0PROCESS,
    930                                                      0 /*offSub*/, sizeof(VM));
    931                             for (VMCPUID i = 0; i < cCpus && RT_SUCCESS(rc); i++)
    932                             {
    933                                 AssertCompileSizeAlignment(VMCPU, PAGE_SIZE);
    934                                 rc = RTR0MemObjMapUserEx(&pGVM->aCpus[i].gvmm.s.VMCpuMapObj, pGVM->gvmm.s.VMMemObj,
    935                                                          (RTR3PTR)-1, 0, RTMEM_PROT_READ | RTMEM_PROT_WRITE, NIL_RTR0PROCESS,
    936                                                          RT_UOFFSETOF_DYN(GVM, aCpus[i]), sizeof(VMCPU));
    937                             }
    938                             if (RT_SUCCESS(rc))
    939                                 rc = RTR0MemObjMapUser(&pGVM->gvmm.s.VMPagesMapObj, pGVM->gvmm.s.VMPagesMemObj, (RTR3PTR)-1,
    940                                                        0 /* uAlignment */, RTMEM_PROT_READ | RTMEM_PROT_WRITE,
    941                                                        NIL_RTR0PROCESS);
     915                            rc = RTR0MemObjAllocPage(&pGVM->gvmm.s.VMPagesMemObj, cPages * sizeof(SUPPAGE), false /* fExecutable */);
    942916                            if (RT_SUCCESS(rc))
    943917                            {
     918                                PSUPPAGE paPages = (PSUPPAGE)RTR0MemObjAddress(pGVM->gvmm.s.VMPagesMemObj); AssertPtr(paPages);
     919                                for (uint32_t iPage = 0; iPage < cPages; iPage++)
     920                                {
     921                                    paPages[iPage].uReserved = 0;
     922                                    paPages[iPage].Phys = RTR0MemObjGetPagePhysAddr(pGVM->gvmm.s.VMMemObj, iPage);
     923                                    Assert(paPages[iPage].Phys != NIL_RTHCPHYS);
     924                                }
     925
    944926                                /*
    945                                  * Initialize all the VM pointers.
     927                                 * Map the page array, VM and VMCPU structures into ring-3.
    946928                                 */
    947                                 PVMR3 pVMR3 = RTR0MemObjAddressR3(pGVM->gvmm.s.VMMapObj);
    948                                 AssertPtr((void *)pVMR3);
    949 
    950                                 for (VMCPUID i = 0; i < cCpus; i++)
     929                                AssertCompileSizeAlignment(VM, PAGE_SIZE);
     930                                rc = RTR0MemObjMapUserEx(&pGVM->gvmm.s.VMMapObj, pGVM->gvmm.s.VMMemObj, (RTR3PTR)-1, 0,
     931                                                         RTMEM_PROT_READ | RTMEM_PROT_WRITE, NIL_RTR0PROCESS,
     932                                                         0 /*offSub*/, sizeof(VM));
     933                                for (VMCPUID i = 0; i < cCpus && RT_SUCCESS(rc); i++)
    951934                                {
    952                                     pGVM->aCpus[i].pVMR0 = pGVM;
    953                                     pGVM->aCpus[i].pVMR3 = pVMR3;
    954                                     pGVM->apCpusR3[i] = RTR0MemObjAddressR3(pGVM->aCpus[i].gvmm.s.VMCpuMapObj);
    955                                     pGVM->aCpus[i].pVCpuR3 = pGVM->apCpusR3[i];
    956                                     pGVM->apCpusR0[i] = &pGVM->aCpus[i];
    957                                     AssertPtr((void *)pGVM->apCpusR3[i]);
     935                                    AssertCompileSizeAlignment(VMCPU, PAGE_SIZE);
     936                                    rc = RTR0MemObjMapUserEx(&pGVM->aCpus[i].gvmm.s.VMCpuMapObj, pGVM->gvmm.s.VMMemObj,
     937                                                             (RTR3PTR)-1, 0, RTMEM_PROT_READ | RTMEM_PROT_WRITE, NIL_RTR0PROCESS,
     938                                                             RT_UOFFSETOF_DYN(GVM, aCpus[i]), sizeof(VMCPU));
    958939                                }
    959 
    960                                 pGVM->paVMPagesR3 = RTR0MemObjAddressR3(pGVM->gvmm.s.VMPagesMapObj);
    961                                 AssertPtr((void *)pGVM->paVMPagesR3);
    962 
    963                                 /*
    964                                  * Complete the handle - take the UsedLock sem just to be careful.
    965                                  */
    966                                 rc = GVMMR0_USED_EXCLUSIVE_LOCK(pGVMM);
    967                                 AssertRC(rc);
    968 
    969                                 pHandle->pGVM                   = pGVM;
    970                                 pHandle->hEMT0                  = hEMT0;
    971                                 pHandle->ProcId                 = ProcId;
    972                                 pGVM->pVMR3                     = pVMR3;
    973                                 pGVM->pVMR3Unsafe               = pVMR3;
    974                                 pGVM->aCpus[0].hEMT             = hEMT0;
    975                                 pGVM->aCpus[0].hNativeThreadR0  = hEMT0;
    976                                 pGVMM->cEMTs += cCpus;
    977 
    978                                 /* Associate it with the session and create the context hook for EMT0. */
    979                                 rc = SUPR0SetSessionVM(pSession, pGVM, pGVM);
     940                                if (RT_SUCCESS(rc))
     941                                    rc = RTR0MemObjMapUser(&pGVM->gvmm.s.VMPagesMapObj, pGVM->gvmm.s.VMPagesMemObj, (RTR3PTR)-1,
     942                                                           0 /* uAlignment */, RTMEM_PROT_READ | RTMEM_PROT_WRITE,
     943                                                           NIL_RTR0PROCESS);
    980944                                if (RT_SUCCESS(rc))
    981945                                {
    982                                     rc = VMMR0ThreadCtxHookCreateForEmt(&pGVM->aCpus[0]);
     946                                    /*
     947                                     * Initialize all the VM pointers.
     948                                     */
     949                                    PVMR3 pVMR3 = RTR0MemObjAddressR3(pGVM->gvmm.s.VMMapObj);
     950                                    AssertPtr((void *)pVMR3);
     951
     952                                    for (VMCPUID i = 0; i < cCpus; i++)
     953                                    {
     954                                        pGVM->aCpus[i].pVMR0 = pGVM;
     955                                        pGVM->aCpus[i].pVMR3 = pVMR3;
     956                                        pGVM->apCpusR3[i] = RTR0MemObjAddressR3(pGVM->aCpus[i].gvmm.s.VMCpuMapObj);
     957                                        pGVM->aCpus[i].pVCpuR3 = pGVM->apCpusR3[i];
     958                                        pGVM->apCpusR0[i] = &pGVM->aCpus[i];
     959                                        AssertPtr((void *)pGVM->apCpusR3[i]);
     960                                    }
     961
     962                                    pGVM->paVMPagesR3 = RTR0MemObjAddressR3(pGVM->gvmm.s.VMPagesMapObj);
     963                                    AssertPtr((void *)pGVM->paVMPagesR3);
     964
     965                                    /*
     966                                     * Complete the handle - take the UsedLock sem just to be careful.
     967                                     */
     968                                    rc = GVMMR0_USED_EXCLUSIVE_LOCK(pGVMM);
     969                                    AssertRC(rc);
     970
     971                                    pHandle->pGVM                   = pGVM;
     972                                    pHandle->hEMT0                  = hEMT0;
     973                                    pHandle->ProcId                 = ProcId;
     974                                    pGVM->pVMR3                     = pVMR3;
     975                                    pGVM->pVMR3Unsafe               = pVMR3;
     976                                    pGVM->aCpus[0].hEMT             = hEMT0;
     977                                    pGVM->aCpus[0].hNativeThreadR0  = hEMT0;
     978                                    pGVMM->cEMTs += cCpus;
     979
     980                                    /* Associate it with the session and create the context hook for EMT0. */
     981                                    rc = SUPR0SetSessionVM(pSession, pGVM, pGVM);
    983982                                    if (RT_SUCCESS(rc))
    984983                                    {
    985                                         /*
    986                                          * Done!
    987                                          */
    988                                         VBOXVMM_R0_GVMM_VM_CREATED(pGVM, pGVM, ProcId, (void *)hEMT0, cCpus);
    989 
    990                                         GVMMR0_USED_EXCLUSIVE_UNLOCK(pGVMM);
    991                                         gvmmR0CreateDestroyUnlock(pGVMM);
    992 
    993                                         CPUMR0RegisterVCpuThread(&pGVM->aCpus[0]);
    994 
    995                                         *ppGVM = pGVM;
    996                                         Log(("GVMMR0CreateVM: pVMR3=%p pGVM=%p hGVM=%d\n", pVMR3, pGVM, iHandle));
    997                                         return VINF_SUCCESS;
     984                                        rc = VMMR0ThreadCtxHookCreateForEmt(&pGVM->aCpus[0]);
     985                                        if (RT_SUCCESS(rc))
     986                                        {
     987                                            /*
     988                                             * Done!
     989                                             */
     990                                            VBOXVMM_R0_GVMM_VM_CREATED(pGVM, pGVM, ProcId, (void *)hEMT0, cCpus);
     991
     992                                            GVMMR0_USED_EXCLUSIVE_UNLOCK(pGVMM);
     993                                            gvmmR0CreateDestroyUnlock(pGVMM);
     994
     995                                            CPUMR0RegisterVCpuThread(&pGVM->aCpus[0]);
     996
     997                                            *ppGVM = pGVM;
     998                                            Log(("GVMMR0CreateVM: pVMR3=%p pGVM=%p hGVM=%d\n", pVMR3, pGVM, iHandle));
     999                                            return VINF_SUCCESS;
     1000                                        }
     1001
     1002                                        SUPR0SetSessionVM(pSession, NULL, NULL);
    9981003                                    }
    999 
    1000                                     SUPR0SetSessionVM(pSession, NULL, NULL);
     1004                                    GVMMR0_USED_EXCLUSIVE_UNLOCK(pGVMM);
    10011005                                }
    1002                                 GVMMR0_USED_EXCLUSIVE_UNLOCK(pGVMM);
    1003                             }
    1004 
    1005                             /* Cleanup mappings. */
    1006                             if (pGVM->gvmm.s.VMMapObj != NIL_RTR0MEMOBJ)
    1007                             {
    1008                                 RTR0MemObjFree(pGVM->gvmm.s.VMMapObj, false /* fFreeMappings */);
    1009                                 pGVM->gvmm.s.VMMapObj = NIL_RTR0MEMOBJ;
    1010                             }
    1011                             for (VMCPUID i = 0; i < cCpus; i++)
    1012                                 if (pGVM->aCpus[i].gvmm.s.VMCpuMapObj != NIL_RTR0MEMOBJ)
     1006
     1007                                /* Cleanup mappings. */
     1008                                if (pGVM->gvmm.s.VMMapObj != NIL_RTR0MEMOBJ)
    10131009                                {
    1014                                     RTR0MemObjFree(pGVM->aCpus[i].gvmm.s.VMCpuMapObj, false /* fFreeMappings */);
    1015                                     pGVM->aCpus[i].gvmm.s.VMCpuMapObj = NIL_RTR0MEMOBJ;
     1010                                    RTR0MemObjFree(pGVM->gvmm.s.VMMapObj, false /* fFreeMappings */);
     1011                                    pGVM->gvmm.s.VMMapObj = NIL_RTR0MEMOBJ;
    10161012                                }
    1017                             if (pGVM->gvmm.s.VMPagesMapObj != NIL_RTR0MEMOBJ)
    1018                             {
    1019                                 RTR0MemObjFree(pGVM->gvmm.s.VMPagesMapObj, false /* fFreeMappings */);
    1020                                 pGVM->gvmm.s.VMPagesMapObj = NIL_RTR0MEMOBJ;
     1013                                for (VMCPUID i = 0; i < cCpus; i++)
     1014                                    if (pGVM->aCpus[i].gvmm.s.VMCpuMapObj != NIL_RTR0MEMOBJ)
     1015                                    {
     1016                                        RTR0MemObjFree(pGVM->aCpus[i].gvmm.s.VMCpuMapObj, false /* fFreeMappings */);
     1017                                        pGVM->aCpus[i].gvmm.s.VMCpuMapObj = NIL_RTR0MEMOBJ;
     1018                                    }
     1019                                if (pGVM->gvmm.s.VMPagesMapObj != NIL_RTR0MEMOBJ)
     1020                                {
     1021                                    RTR0MemObjFree(pGVM->gvmm.s.VMPagesMapObj, false /* fFreeMappings */);
     1022                                    pGVM->gvmm.s.VMPagesMapObj = NIL_RTR0MEMOBJ;
     1023                                }
    10211024                            }
    10221025                        }
    10231026                    }
    1024 
    10251027                }
    10261028                /* else: The user wasn't permitted to create this VM. */
     
    12971299    PDMR0CleanupVM(pGVM);
    12981300    IOMR0CleanupVM(pGVM);
     1301    PGMR0CleanupVM(pGVM);
    12991302
    13001303    AssertCompile(NIL_RTTHREADCTXHOOK == (RTTHREADCTXHOOK)0); /* Depends on zero initialized memory working for NIL at the moment. */
  • trunk/src/VBox/VMM/VMMR0/PGMR0.cpp

    r81624 r82555  
    3333#include <iprt/assert.h>
    3434#include <iprt/mem.h>
     35#include <iprt/memobj.h>
    3536
    3637
     
    5455#include "PGMR0Bth.h"
    5556#undef PGM_BTH_NAME
     57
     58
     59/**
     60 * Initializes the per-VM data for the PGM.
     61 *
     62 * This is called from under the GVMM lock, so it should only initialize the
     63 * data so PGMR0CleanupVM and others will work smoothly.
     64 *
     65 * @returns VBox status code.
     66 * @param   pGVM    Pointer to the global VM structure.
     67 */
     68VMMR0_INT_DECL(int) PGMR0InitPerVMData(PGVM pGVM)
     69{
     70    AssertCompile(sizeof(pGVM->pgm.s) <= sizeof(pGVM->pgm.padding));
     71    AssertCompile(sizeof(pGVM->pgmr0.s) <= sizeof(pGVM->pgmr0.padding));
     72
     73    AssertCompile(RT_ELEMENTS(pGVM->pgmr0.s.ahPoolMemObjs) == RT_ELEMENTS(pGVM->pgmr0.s.ahPoolMapObjs));
     74    for (uint32_t i = 0; i < RT_ELEMENTS(pGVM->pgmr0.s.ahPoolMemObjs); i++)
     75    {
     76        pGVM->pgmr0.s.ahPoolMemObjs[i] = NIL_RTR0MEMOBJ;
     77        pGVM->pgmr0.s.ahPoolMapObjs[i] = NIL_RTR0MEMOBJ;
     78    }
     79    return RTCritSectInit(&pGVM->pgmr0.s.PoolGrowCritSect);
     80}
     81
     82
     83/**
     84 * Initalize the per-VM PGM for ring-0.
     85 *
     86 * @returns VBox status code.
     87 * @param   pGVM    Pointer to the global VM structure.
     88 */
     89VMMR0_INT_DECL(int) PGMR0InitVM(PGVM pGVM)
     90{
     91    int rc = VINF_SUCCESS;
     92#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
     93    rc = PGMR0DynMapInitVM(pGVM);
     94#endif
     95    RT_NOREF(pGVM);
     96    return rc;
     97}
     98
     99
     100/**
     101 * Cleans up any loose ends before the GVM structure is destroyed.
     102 */
     103VMMR0_INT_DECL(void) PGMR0CleanupVM(PGVM pGVM)
     104{
     105    for (uint32_t i = 0; i < RT_ELEMENTS(pGVM->pgmr0.s.ahPoolMemObjs); i++)
     106    {
     107        if (pGVM->pgmr0.s.ahPoolMapObjs[i] != NIL_RTR0MEMOBJ)
     108        {
     109            int rc = RTR0MemObjFree(pGVM->pgmr0.s.ahPoolMapObjs[i], true /*fFreeMappings*/);
     110            AssertRC(rc);
     111            pGVM->pgmr0.s.ahPoolMapObjs[i] = NIL_RTR0MEMOBJ;
     112        }
     113
     114        if (pGVM->pgmr0.s.ahPoolMemObjs[i] != NIL_RTR0MEMOBJ)
     115        {
     116            int rc = RTR0MemObjFree(pGVM->pgmr0.s.ahPoolMemObjs[i], true /*fFreeMappings*/);
     117            AssertRC(rc);
     118            pGVM->pgmr0.s.ahPoolMemObjs[i] = NIL_RTR0MEMOBJ;
     119        }
     120    }
     121
     122    if (RTCritSectIsInitialized(&pGVM->pgmr0.s.PoolGrowCritSect))
     123        RTCritSectDelete(&pGVM->pgmr0.s.PoolGrowCritSect);
     124}
    56125
    57126
  • trunk/src/VBox/VMM/VMMR0/VMMR0.cpp

    r82544 r82555  
    465465            {
    466466                VMM_CHECK_SMAP_CHECK2(pGVM, RT_NOTHING);
    467 #ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
    468                 rc = PGMR0DynMapInitVM(pGVM);
    469 #endif
     467                rc = PGMR0InitVM(pGVM);
    470468                if (RT_SUCCESS(rc))
    471469                {
     
    18001798            break;
    18011799
     1800        case VMMR0_DO_PGM_POOL_GROW:
     1801            if (idCpu == NIL_VMCPUID)
     1802                return VERR_INVALID_CPU_ID;
     1803            rc = PGMR0PoolGrow(pGVM);
     1804            VMM_CHECK_SMAP_CHECK2(pGVM, RT_NOTHING);
     1805            break;
     1806
    18021807        /*
    18031808         * GMM wrappers.
     
    23442349
    23452350            default:
     2351            case VMMR0_DO_PGM_POOL_GROW:
    23462352                break;
    23472353        }
  • trunk/src/VBox/VMM/VMMR3/MM.cpp

    r80333 r82555  
    460460VMMR3DECL(int) MMR3Term(PVM pVM)
    461461{
     462#if 0
    462463    /*
    463464     * Destroy the page pool. (first as it used the hyper heap)
    464465     */
    465466    mmR3PagePoolTerm(pVM);
     467#endif
    466468
    467469    /* Clean up the hypervisor heap. */
     
    740742VMMR3DECL(int) MMR3HCPhys2HCVirt(PVM pVM, RTHCPHYS HCPhys, void **ppv)
    741743{
     744#if 0
    742745    /*
    743746     * Try page tables.
     
    746749    if (RT_SUCCESS(rc))
    747750        return rc;
     751#endif
    748752
    749753    /*
  • trunk/src/VBox/VMM/VMMR3/MMPagePool.cpp

    r80333 r82555  
    379379}
    380380
     381#if 0
    381382
    382383/**
     
    483484}
    484485
     486#endif
    485487
    486488/**
  • trunk/src/VBox/VMM/VMMR3/PGMDbg.cpp

    r80673 r82555  
    11161116    if (!fIsMapping)
    11171117    {
    1118         int rc = MMPagePhys2PageTry(pState->pVM, HCPhys, &pvPage);
    1119         if (RT_FAILURE(rc))
     1118        PPGMPOOLPAGE pPoolPage = pgmPoolQueryPageForDbg(pState->pVM->pgm.s.pPoolR3, HCPhys);
     1119        if (pPoolPage)
    11201120        {
    11211121            pState->pHlp->pfnPrintf(pState->pHlp, "%0*llx error! %s at HCPhys=%RHp was not found in the page pool!\n",
    11221122                                    pState->cchAddress, pState->u64Address, pszDesc, HCPhys);
    1123             return rc;
     1123            return VERR_PGM_POOL_GET_PAGE_FAILED;
    11241124        }
     1125        pvPage = (uint8_t *)pPoolPage->pvPageR3 + (HCPhys & PAGE_OFFSET_MASK);
    11251126    }
    11261127    else
  • trunk/src/VBox/VMM/VMMR3/PGMPool.cpp

    r80334 r82555  
    170170    AssertLogRelMsgReturn(cMaxPages <= PGMPOOL_IDX_LAST && cMaxPages >= RT_ALIGN(PGMPOOL_IDX_FIRST, 16),
    171171                          ("cMaxPages=%u (%#x)\n", cMaxPages, cMaxPages), VERR_INVALID_PARAMETER);
    172     cMaxPages = RT_ALIGN(cMaxPages, 16);
     172    AssertCompile(RT_IS_POWER_OF_TWO(PGMPOOL_CFG_MAX_GROW));
     173    if (cMaxPages < PGMPOOL_IDX_LAST)
     174        cMaxPages = RT_ALIGN(cMaxPages, PGMPOOL_CFG_MAX_GROW / 2);
    173175    if (cMaxPages > PGMPOOL_IDX_LAST)
    174176        cMaxPages = PGMPOOL_IDX_LAST;
     
    314316    Assert(!pPool->aPages[NIL_PGMPOOL_IDX].fReusedFlushPending);
    315317
    316 #ifdef VBOX_WITH_STATISTICS
    317318    /*
    318319     * Register statistics.
    319320     */
     321    STAM_REL_REG(pVM, &pPool->StatGrow,                 STAMTYPE_PROFILE,   "/PGM/Pool/Grow",           STAMUNIT_TICKS, "Profiling PGMR0PoolGrow");
     322#ifdef VBOX_WITH_STATISTICS
    320323    STAM_REG(pVM, &pPool->cCurPages,                    STAMTYPE_U16,       "/PGM/Pool/cCurPages",      STAMUNIT_PAGES,             "Current pool size.");
    321324    STAM_REG(pVM, &pPool->cMaxPages,                    STAMTYPE_U16,       "/PGM/Pool/cMaxPages",      STAMUNIT_PAGES,             "Max pool size.");
     
    473476 * @returns VBox status code.
    474477 * @param   pVM     The cross context VM structure.
     478 * @param   pVCpu   The cross context virtual CPU structure of the calling EMT.
    475479 */
    476 VMMR3DECL(int) PGMR3PoolGrow(PVM pVM)
     480VMMR3_INT_DECL(int) PGMR3PoolGrow(PVM pVM, PVMCPU pVCpu)
    477481{
    478     PPGMPOOL pPool = pVM->pgm.s.pPoolR3;
    479     AssertReturn(pPool->cCurPages < pPool->cMaxPages, VERR_PGM_POOL_MAXED_OUT_ALREADY);
    480 
    481     /* With 32-bit guests and no EPT, the CR3 limits the root pages to low
    482        (below 4 GB) memory. */
    483     /** @todo change the pool to handle ROOT page allocations specially when
    484      *        required. */
    485     bool fCanUseHighMemory = HMIsNestedPagingActive(pVM);
    486 
    487     pgmLock(pVM);
    488 
    489     /*
    490      * How much to grow it by?
    491      */
    492     uint32_t cPages = pPool->cMaxPages - pPool->cCurPages;
    493     cPages = RT_MIN(PGMPOOL_CFG_MAX_GROW, cPages);
    494     LogFlow(("PGMR3PoolGrow: Growing the pool by %d (%#x) pages. fCanUseHighMemory=%RTbool\n", cPages, cPages, fCanUseHighMemory));
    495 
    496     for (unsigned i = pPool->cCurPages; cPages-- > 0; i++)
    497     {
    498         PPGMPOOLPAGE pPage = &pPool->aPages[i];
    499 
    500         if (fCanUseHighMemory)
    501             pPage->pvPageR3 = MMR3PageAlloc(pVM);
    502         else
    503             pPage->pvPageR3 = MMR3PageAllocLow(pVM);
    504         if (!pPage->pvPageR3)
    505         {
    506             Log(("We're out of memory!! i=%d fCanUseHighMemory=%RTbool\n", i, fCanUseHighMemory));
    507             pgmUnlock(pVM);
    508             return i ? VINF_SUCCESS : VERR_NO_PAGE_MEMORY;
    509         }
    510         pPage->Core.Key  = MMPage2Phys(pVM, pPage->pvPageR3);
    511         AssertFatal(pPage->Core.Key < _4G || fCanUseHighMemory);
    512         pPage->GCPhys    = NIL_RTGCPHYS;
    513         pPage->enmKind   = PGMPOOLKIND_FREE;
    514         pPage->idx       = pPage - &pPool->aPages[0];
    515         LogFlow(("PGMR3PoolGrow: insert page #%#x - %RHp\n", pPage->idx, pPage->Core.Key));
    516         pPage->iNext     = pPool->iFreeHead;
    517         pPage->iUserHead = NIL_PGMPOOL_USER_INDEX;
    518         pPage->iModifiedNext  = NIL_PGMPOOL_IDX;
    519         pPage->iModifiedPrev  = NIL_PGMPOOL_IDX;
    520         pPage->iMonitoredNext = NIL_PGMPOOL_IDX;
    521         pPage->iMonitoredPrev = NIL_PGMPOOL_IDX;
    522         pPage->iAgeNext  = NIL_PGMPOOL_IDX;
    523         pPage->iAgePrev  = NIL_PGMPOOL_IDX;
    524         /* commit it */
    525         bool fRc = RTAvloHCPhysInsert(&pPool->HCPhysTree, &pPage->Core); Assert(fRc); NOREF(fRc);
    526         pPool->iFreeHead = i;
    527         pPool->cCurPages = i + 1;
    528     }
    529 
    530     pgmUnlock(pVM);
    531     Assert(pPool->cCurPages <= pPool->cMaxPages);
    532     return VINF_SUCCESS;
     482    /* This used to do a lot of stuff, but it has moved to ring-0 (PGMR0PoolGrow). */
     483    AssertReturn(pVM->pgm.s.pPoolR3->cCurPages < pVM->pgm.s.pPoolR3->cMaxPages, VERR_PGM_POOL_MAXED_OUT_ALREADY);
     484    return VMMR3CallR0Emt(pVM, pVCpu, VMMR0_DO_PGM_POOL_GROW, 0, NULL);
    533485}
    534486
  • trunk/src/VBox/VMM/VMMR3/VMM.cpp

    r81198 r82555  
    23932393        case VMMCALLRING3_PGM_POOL_GROW:
    23942394        {
    2395             pVCpu->vmm.s.rcCallRing3 = PGMR3PoolGrow(pVM);
     2395            pVCpu->vmm.s.rcCallRing3 = PGMR3PoolGrow(pVM, pVCpu);
    23962396            break;
    23972397        }
  • trunk/src/VBox/VMM/include/PGMInternal.h

    r81624 r82555  
    140140 * The maximum number of pages to add to the pool in one go.
    141141 */
    142 #define PGMPOOL_CFG_MAX_GROW            (_256K >> PAGE_SHIFT)
     142#define PGMPOOL_CFG_MAX_GROW            (_2M >> PAGE_SHIFT)
    143143
    144144/** @def VBOX_STRICT_PGM_HANDLER_VIRTUAL
     
    266266 *                      this.
    267267 *
    268  * @remark  Use with care as we don't have so much dynamic mapping space in
    269  *          ring-0 on 32-bit darwin and in RC.
    270268 * @remark  There is no need to assert on the result.
    271269 */
    272 #ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0
    273 # define PGM_HCPHYS_2_PTR(pVM, pVCpu, HCPhys, ppv) \
    274      pgmRZDynMapHCPageInlined(pVCpu, HCPhys, (void **)(ppv) RTLOG_COMMA_SRC_POS)
    275 #else
    276 # define PGM_HCPHYS_2_PTR(pVM, pVCpu, HCPhys, ppv) \
    277      MMPagePhys2PageEx(pVM, HCPhys, (void **)(ppv))
    278 #endif
     270#define PGM_HCPHYS_2_PTR(pVM, pVCpu, HCPhys, ppv) pgmPoolHCPhys2Ptr(pVM, HCPhys, (void **)(ppv))
    279271
    280272/** @def PGM_GCPHYS_2_PTR_V2
     
    20552047    AVLOHCPHYSNODECORE  Core;
    20562048    /** Pointer to the R3 mapping of the page. */
    2057 #ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
    20582049    R3PTRTYPE(void *)   pvPageR3;
    2059 #else
    2060     R3R0PTRTYPE(void *) pvPageR3;
    2061 #endif
    2062 #if HC_ARCH_BITS == 32 && GC_ARCH_BITS == 64
    2063     uint32_t            Alignment0;
    2064 #endif
     2050    /** Pointer to the R0 mapping of the page. */
     2051    R0PTRTYPE(void *)   pvPageR0;
    20652052    /** The guest physical address. */
    20662053    RTGCPHYS            GCPhys;
     
    23472334    uint32_t                    Alignment3;         /**< Align the next member on a 64-bit boundary. */
    23482335#endif
     2336    /** Profiling PGMR0PoolGrow(). */
     2337    STAMPROFILE                 StatGrow;
    23492338    /** The AVL tree for looking up a page by its HC physical address. */
    23502339    AVLOHCPHYSTREE              HCPhysTree;
     
    23822371{
    23832372    AssertPtr(a_pPage);
    2384     AssertReleaseMsg(RT_VALID_PTR(a_pPage->pvPageR3), ("enmKind=%d idx=%#x HCPhys=%RHp GCPhys=%RGp caller=%s\n", a_pPage->enmKind, a_pPage->idx, a_pPage->Core.Key, a_pPage->GCPhys, pszCaller));
    2385     return a_pPage->pvPageR3;
     2373    AssertMsg(RT_VALID_PTR(a_pPage->CTX_SUFF(pvPage)),
     2374              ("enmKind=%d idx=%#x HCPhys=%RHp GCPhys=%RGp pvPageR3=%p pvPageR0=%p caller=%s\n",
     2375               a_pPage->enmKind, a_pPage->idx, a_pPage->Core.Key, a_pPage->GCPhys, a_pPage->pvPageR3, a_pPage->pvPageR0, pszCaller));
     2376    return a_pPage->CTX_SUFF(pvPage);
    23862377}
    23872378#else
    2388 # define PGMPOOL_PAGE_2_PTR(pVM, a_pPage)       ((a_pPage)->pvPageR3)
     2379# define PGMPOOL_PAGE_2_PTR(pVM, a_pPage)       ((a_pPage)->CTX_SUFF(pvPage))
    23892380#endif
    23902381
     
    38343825
    38353826
     3827/**
     3828 * PGM GVM instance data.
     3829 */
     3830typedef struct PGMR0PERVM
     3831{
     3832    /** @name PGM Pool related stuff.
     3833     * @{ */
     3834    /** Critical section for serializing pool growth. */
     3835    RTCRITSECT  PoolGrowCritSect;
     3836    /** The memory objects for the pool pages. */
     3837    RTR0MEMOBJ  ahPoolMemObjs[(PGMPOOL_IDX_LAST + PGMPOOL_CFG_MAX_GROW - 1) / PGMPOOL_CFG_MAX_GROW];
     3838    /** The ring-3 mapping objects for the pool pages. */
     3839    RTR0MEMOBJ  ahPoolMapObjs[(PGMPOOL_IDX_LAST + PGMPOOL_CFG_MAX_GROW - 1) / PGMPOOL_CFG_MAX_GROW];
     3840    /** @} */
     3841} PGMR0PERVM;
     3842
    38363843RT_C_DECLS_BEGIN
    38373844
     
    39493956PPGMPOOLPAGE    pgmPoolGetPage(PPGMPOOL pPool, RTHCPHYS HCPhys);
    39503957PPGMPOOLPAGE    pgmPoolQueryPageForDbg(PPGMPOOL pPool, RTHCPHYS HCPhys);
     3958int             pgmPoolHCPhys2Ptr(PVM pVM, RTHCPHYS HCPhys, void **ppv);
    39513959int             pgmPoolSyncCR3(PVMCPUCC pVCpu);
    39523960bool            pgmPoolIsDirtyPageSlow(PVM pVM, RTGCPHYS GCPhys);
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