Changeset 29024 in vbox for trunk/src/VBox/VMM/PGMSharedPage.cpp
- Timestamp:
- May 4, 2010 2:12:15 PM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 61064
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/PGMSharedPage.cpp
r28800 r29024 24 24 #include <VBox/stam.h> 25 25 #include "PGMInternal.h" 26 #include "PGMInline.h" 26 27 #include <VBox/vm.h> 27 28 #include <VBox/sup.h> … … 31 32 #include <iprt/assert.h> 32 33 #include <iprt/asm.h> 34 #include <iprt/string.h> 35 #include <iprt/mem.h> 33 36 37 38 #ifdef VBOX_WITH_PAGE_SHARING 39 /** 40 * Shared module registration helper (called on the way out). 41 * 42 * @param pVM The VM handle. 43 * @param pReq Registration request info 44 */ 45 static DECLCALLBACK(void) pgmR3SharedModuleRegisterHelper(PVM pVM, PGMMREGISTERSHAREDMODULEREQ pReq) 46 { 47 int rc; 48 49 rc = GMMR3RegisterSharedModule(pVM, pReq); 50 Assert(rc == VINF_SUCCESS || rc == VINF_PGM_SHARED_MODULE_COLLISION || rc == VINF_PGM_SHARED_MODULE_ALREADY_REGISTERED); 51 if (rc == VINF_PGM_SHARED_MODULE_ALREADY_REGISTERED) 52 { 53 PVMCPU pVCpu = VMMGetCpu(pVM); 54 unsigned cFlushedPages = 0; 55 56 /** todo count copy-on-write actions in the trap handler so we don't check everything all the time! */ 57 58 /* Count the number of shared pages that were changed (copy-on-write). */ 59 for (unsigned i = 0; i < pReq->cRegions; i++) 60 { 61 Assert((pReq->aRegions[i].cbRegion & 0xfff) == 0); 62 Assert((pReq->aRegions[i].GCRegionAddr & 0xfff) == 0); 63 64 RTGCPTR GCRegion = pReq->aRegions[i].GCRegionAddr; 65 uint32_t cbRegion = pReq->aRegions[i].cbRegion & ~0xfff; 66 67 while (cbRegion) 68 { 69 RTGCPHYS GCPhys; 70 uint64_t fFlags; 71 72 rc = PGMGstGetPage(pVCpu, GCRegion, &GCPhys, &fFlags); 73 if ( rc == VINF_SUCCESS 74 && !(fFlags & X86_PTE_RW)) 75 { 76 PPGMPAGE pPage = pgmPhysGetPage(&pVM->pgm.s, GCPhys); 77 if ( pPage 78 && !PGM_PAGE_IS_SHARED(pPage)) 79 { 80 cFlushedPages++; 81 } 82 } 83 84 GCRegion += PAGE_SIZE; 85 cbRegion -= PAGE_SIZE; 86 } 87 } 88 89 if (cFlushedPages > 32) 90 rc = VINF_SUCCESS; /* force recheck below */ 91 } 92 /* Full (re)check needed? */ 93 if (rc == VINF_SUCCESS) 94 { 95 96 } 97 RTMemFree(pReq); 98 return; 99 } 100 #endif 34 101 35 102 /** … … 49 116 { 50 117 #ifdef VBOX_WITH_PAGE_SHARING 51 return GMMR3RegisterSharedModule(pVM, pszModuleName, pszVersion, GCBaseAddr, cbModule, cRegions, pRegions); 52 #else 118 PGMMREGISTERSHAREDMODULEREQ pReq; 119 120 /* Sanity check. */ 121 AssertReturn(cRegions < VMMDEVSHAREDREGIONDESC_MAX, VERR_INVALID_PARAMETER); 122 123 pReq = (PGMMREGISTERSHAREDMODULEREQ)RTMemAllocZ(RT_OFFSETOF(GMMREGISTERSHAREDMODULEREQ, aRegions[cRegions])); 124 AssertReturn(pReq, VERR_NO_MEMORY); 125 126 pReq->Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC; 127 pReq->Hdr.cbReq = sizeof(*pReq); 128 pReq->GCBaseAddr = GCBaseAddr; 129 pReq->cbModule = cbModule; 130 pReq->cRegions = cRegions; 131 for (unsigned i = 0; i < cRegions; i++) 132 pReq->aRegions[i] = pRegions[i]; 133 134 if ( RTStrCopy(pReq->szName, sizeof(pReq->szName), pszModuleName) != VINF_SUCCESS 135 || RTStrCopy(pReq->szVersion, sizeof(pReq->szVersion), pszVersion) != VINF_SUCCESS) 136 { 137 RTMemFree(pReq); 138 return VERR_BUFFER_OVERFLOW; 139 } 140 141 /* Queue the actual registration as we are under the IOM lock right now. Perform this operation on the way out. */ 142 return VMR3ReqCallNoWait(pVM, VMMGetCpuId(pVM), (PFNRT)pgmR3SharedModuleRegisterHelper, 2, pVM, pReq); 143 #else 53 144 return VERR_NOT_IMPLEMENTED; 54 145 #endif
Note:
See TracChangeset
for help on using the changeset viewer.