VirtualBox

Ignore:
Timestamp:
Dec 11, 2019 11:56:54 PM (5 years ago)
Author:
vboxsync
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

File:
1 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. */
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