VirtualBox

Changeset 82555 in vbox for trunk/src/VBox/VMM/VMMR0


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/VMMR0
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • 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        }
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