- Timestamp:
- Dec 11, 2019 11:56:54 PM (5 years ago)
- svn:sync-xref-src-repo-rev:
- 135429
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 1 added
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/Makefile.kmk
r82313 r82555 490 490 VMMR0/PDMR0Driver.cpp \ 491 491 VMMR0/PGMR0.cpp \ 492 VMMR0/PGMR0Pool.cpp \ 492 493 VMMR0/PGMR0SharedPage.cpp \ 493 494 VMMR0/VMMR0.cpp \ … … 514 515 VMMAll/MMAll.cpp \ 515 516 VMMAll/MMAllHyper.cpp \ 516 VMMAll/MMAllPagePool.cpp \517 517 VMMAll/NEMAll.cpp \ 518 518 VMMAll/PDMAll.cpp \ -
trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp
r80333 r82555 4974 4974 STAM_PROFILE_ADV_SUSPEND(&pPool->StatAlloc, a); 4975 4975 #ifdef IN_RING3 4976 int rc = PGMR3PoolGrow(pVM );4976 int rc = PGMR3PoolGrow(pVM, VMMGetCpu(pVM)); 4977 4977 #else 4978 4978 int rc = VMMRZCallRing3NoCpu(pVM, VMMCALLRING3_PGM_POOL_GROW, 0); … … 5189 5189 PGM_LOCK_ASSERT_OWNER(pPool->CTX_SUFF(pVM)); 5190 5190 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 */ 5202 int 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; 5191 5210 } 5192 5211 … … 5333 5352 PPGMPOOLPAGE pPage = &pPool->aPages[i]; 5334 5353 5335 Assert(pPage->Core.Key == MMPage2Phys(pVM, pPage->pvPageR3));5336 5354 if (pPage->fMonitored) 5337 5355 pgmPoolMonitorFlush(pPool, pPage); -
trunk/src/VBox/VMM/VMMR0/GVMMR0.cpp
r80641 r82555 902 902 RT_BZERO(pGVM, cPages << PAGE_SHIFT); 903 903 gvmmR0InitPerVMData(pGVM, iHandle, cCpus, pSession); 904 pGVM->gvmm.s.VMMemObj = hVMMemObj; 904 905 GMMR0InitPerVMData(pGVM); 906 rc = PGMR0InitPerVMData(pGVM); 905 907 PDMR0InitPerVMData(pGVM); 906 908 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 */);914 909 if (RT_SUCCESS(rc)) 915 910 { 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 924 911 /* 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. 926 914 */ 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 */); 942 916 if (RT_SUCCESS(rc)) 943 917 { 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 944 926 /* 945 * Initialize all the VM pointers.927 * Map the page array, VM and VMCPU structures into ring-3. 946 928 */ 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++) 951 934 { 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)); 958 939 } 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); 980 944 if (RT_SUCCESS(rc)) 981 945 { 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); 983 982 if (RT_SUCCESS(rc)) 984 983 { 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); 998 1003 } 999 1000 SUPR0SetSessionVM(pSession, NULL, NULL); 1004 GVMMR0_USED_EXCLUSIVE_UNLOCK(pGVMM); 1001 1005 } 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) 1013 1009 { 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; 1016 1012 } 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 } 1021 1024 } 1022 1025 } 1023 1026 } 1024 1025 1027 } 1026 1028 /* else: The user wasn't permitted to create this VM. */ … … 1297 1299 PDMR0CleanupVM(pGVM); 1298 1300 IOMR0CleanupVM(pGVM); 1301 PGMR0CleanupVM(pGVM); 1299 1302 1300 1303 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 33 33 #include <iprt/assert.h> 34 34 #include <iprt/mem.h> 35 #include <iprt/memobj.h> 35 36 36 37 … … 54 55 #include "PGMR0Bth.h" 55 56 #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 */ 68 VMMR0_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 */ 89 VMMR0_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 */ 103 VMMR0_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 } 56 125 57 126 -
trunk/src/VBox/VMM/VMMR0/VMMR0.cpp
r82544 r82555 465 465 { 466 466 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); 470 468 if (RT_SUCCESS(rc)) 471 469 { … … 1800 1798 break; 1801 1799 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 1802 1807 /* 1803 1808 * GMM wrappers. … … 2344 2349 2345 2350 default: 2351 case VMMR0_DO_PGM_POOL_GROW: 2346 2352 break; 2347 2353 } -
trunk/src/VBox/VMM/VMMR3/MM.cpp
r80333 r82555 460 460 VMMR3DECL(int) MMR3Term(PVM pVM) 461 461 { 462 #if 0 462 463 /* 463 464 * Destroy the page pool. (first as it used the hyper heap) 464 465 */ 465 466 mmR3PagePoolTerm(pVM); 467 #endif 466 468 467 469 /* Clean up the hypervisor heap. */ … … 740 742 VMMR3DECL(int) MMR3HCPhys2HCVirt(PVM pVM, RTHCPHYS HCPhys, void **ppv) 741 743 { 744 #if 0 742 745 /* 743 746 * Try page tables. … … 746 749 if (RT_SUCCESS(rc)) 747 750 return rc; 751 #endif 748 752 749 753 /* -
trunk/src/VBox/VMM/VMMR3/MMPagePool.cpp
r80333 r82555 379 379 } 380 380 381 #if 0 381 382 382 383 /** … … 483 484 } 484 485 486 #endif 485 487 486 488 /** -
trunk/src/VBox/VMM/VMMR3/PGMDbg.cpp
r80673 r82555 1116 1116 if (!fIsMapping) 1117 1117 { 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) 1120 1120 { 1121 1121 pState->pHlp->pfnPrintf(pState->pHlp, "%0*llx error! %s at HCPhys=%RHp was not found in the page pool!\n", 1122 1122 pState->cchAddress, pState->u64Address, pszDesc, HCPhys); 1123 return rc;1123 return VERR_PGM_POOL_GET_PAGE_FAILED; 1124 1124 } 1125 pvPage = (uint8_t *)pPoolPage->pvPageR3 + (HCPhys & PAGE_OFFSET_MASK); 1125 1126 } 1126 1127 else -
trunk/src/VBox/VMM/VMMR3/PGMPool.cpp
r80334 r82555 170 170 AssertLogRelMsgReturn(cMaxPages <= PGMPOOL_IDX_LAST && cMaxPages >= RT_ALIGN(PGMPOOL_IDX_FIRST, 16), 171 171 ("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); 173 175 if (cMaxPages > PGMPOOL_IDX_LAST) 174 176 cMaxPages = PGMPOOL_IDX_LAST; … … 314 316 Assert(!pPool->aPages[NIL_PGMPOOL_IDX].fReusedFlushPending); 315 317 316 #ifdef VBOX_WITH_STATISTICS317 318 /* 318 319 * Register statistics. 319 320 */ 321 STAM_REL_REG(pVM, &pPool->StatGrow, STAMTYPE_PROFILE, "/PGM/Pool/Grow", STAMUNIT_TICKS, "Profiling PGMR0PoolGrow"); 322 #ifdef VBOX_WITH_STATISTICS 320 323 STAM_REG(pVM, &pPool->cCurPages, STAMTYPE_U16, "/PGM/Pool/cCurPages", STAMUNIT_PAGES, "Current pool size."); 321 324 STAM_REG(pVM, &pPool->cMaxPages, STAMTYPE_U16, "/PGM/Pool/cMaxPages", STAMUNIT_PAGES, "Max pool size."); … … 473 476 * @returns VBox status code. 474 477 * @param pVM The cross context VM structure. 478 * @param pVCpu The cross context virtual CPU structure of the calling EMT. 475 479 */ 476 VMMR3 DECL(int) PGMR3PoolGrow(PVM pVM)480 VMMR3_INT_DECL(int) PGMR3PoolGrow(PVM pVM, PVMCPU pVCpu) 477 481 { 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); 533 485 } 534 486 -
trunk/src/VBox/VMM/VMMR3/VMM.cpp
r81198 r82555 2393 2393 case VMMCALLRING3_PGM_POOL_GROW: 2394 2394 { 2395 pVCpu->vmm.s.rcCallRing3 = PGMR3PoolGrow(pVM );2395 pVCpu->vmm.s.rcCallRing3 = PGMR3PoolGrow(pVM, pVCpu); 2396 2396 break; 2397 2397 } -
trunk/src/VBox/VMM/include/PGMInternal.h
r81624 r82555 140 140 * The maximum number of pages to add to the pool in one go. 141 141 */ 142 #define PGMPOOL_CFG_MAX_GROW (_2 56K>> PAGE_SHIFT)142 #define PGMPOOL_CFG_MAX_GROW (_2M >> PAGE_SHIFT) 143 143 144 144 /** @def VBOX_STRICT_PGM_HANDLER_VIRTUAL … … 266 266 * this. 267 267 * 268 * @remark Use with care as we don't have so much dynamic mapping space in269 * ring-0 on 32-bit darwin and in RC.270 268 * @remark There is no need to assert on the result. 271 269 */ 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)) 279 271 280 272 /** @def PGM_GCPHYS_2_PTR_V2 … … 2055 2047 AVLOHCPHYSNODECORE Core; 2056 2048 /** Pointer to the R3 mapping of the page. */ 2057 #ifdef VBOX_WITH_2X_4GB_ADDR_SPACE2058 2049 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; 2065 2052 /** The guest physical address. */ 2066 2053 RTGCPHYS GCPhys; … … 2347 2334 uint32_t Alignment3; /**< Align the next member on a 64-bit boundary. */ 2348 2335 #endif 2336 /** Profiling PGMR0PoolGrow(). */ 2337 STAMPROFILE StatGrow; 2349 2338 /** The AVL tree for looking up a page by its HC physical address. */ 2350 2339 AVLOHCPHYSTREE HCPhysTree; … … 2382 2371 { 2383 2372 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); 2386 2377 } 2387 2378 #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)) 2389 2380 #endif 2390 2381 … … 3834 3825 3835 3826 3827 /** 3828 * PGM GVM instance data. 3829 */ 3830 typedef 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 3836 3843 RT_C_DECLS_BEGIN 3837 3844 … … 3949 3956 PPGMPOOLPAGE pgmPoolGetPage(PPGMPOOL pPool, RTHCPHYS HCPhys); 3950 3957 PPGMPOOLPAGE pgmPoolQueryPageForDbg(PPGMPOOL pPool, RTHCPHYS HCPhys); 3958 int pgmPoolHCPhys2Ptr(PVM pVM, RTHCPHYS HCPhys, void **ppv); 3951 3959 int pgmPoolSyncCR3(PVMCPUCC pVCpu); 3952 3960 bool pgmPoolIsDirtyPageSlow(PVM pVM, RTGCPHYS GCPhys);
Note:
See TracChangeset
for help on using the changeset viewer.