Changeset 30488 in vbox
- Timestamp:
- Jun 29, 2010 9:02:04 AM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 63179
- Location:
- trunk
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/gmm.h
r30237 r30488 306 306 #endif 307 307 308 309 308 /** 310 309 * Request buffer for GMMR0InitialReservationReq / VMMR0_DO_GMM_INITIAL_RESERVATION. … … 588 587 GMMR0DECL(int) GMMR0UnregisterSharedModuleReq(PVM pVM, VMCPUID idCpu, PGMMUNREGISTERSHAREDMODULEREQ pReq); 589 588 589 #if defined(VBOX_STRICT) && HC_ARCH_BITS == 64 590 /** 591 * Request buffer for GMMR0FindDuplicatePageReq / VMMR0_DO_GMM_FIND_DUPLICATE_PAGE. 592 * @see GMMR0FindDuplicatePage. 593 */ 594 typedef struct GMMFINDDUPLICATEPAGEREQ 595 { 596 /** The header. */ 597 SUPVMMR0REQHDR Hdr; 598 /** Page id. */ 599 uint32_t idPage; 600 /** Duplicate flag (out) */ 601 bool fDuplicate; 602 } GMMFINDDUPLICATEPAGEREQ; 603 /** Pointer to a GMMR0FindDuplicatePageReq / VMMR0_DO_GMM_FIND_DUPLICATE_PAGE request buffer. */ 604 typedef GMMFINDDUPLICATEPAGEREQ *PGMMFINDDUPLICATEPAGEREQ; 605 606 GMMR0DECL(int) GMMR0FindDuplicatePageReq(PVM pVM, PGMMFINDDUPLICATEPAGEREQ pReq); 607 #endif /* VBOX_STRICT && HC_ARCH_BITS == 64 */ 590 608 591 609 #ifdef IN_RING3 … … 616 634 GMMR3DECL(int) GMMR3CheckSharedModules(PVM pVM); 617 635 GMMR3DECL(int) GMMR3ResetSharedModules(PVM pVM); 636 637 # if defined(VBOX_STRICT) && HC_ARCH_BITS == 64 638 GMMR3DECL(bool) GMMR3IsDuplicatePage(PVM pVM, uint32_t idPage); 639 # endif 640 618 641 /** @} */ 619 642 #endif /* IN_RING3 */ -
trunk/include/VBox/pci.h
r28800 r30488 462 462 } 463 463 464 /** 465 * Gets the interrupt line config register. 466 * 467 * @returns The interrupt line. 468 * @param pPciDev The PCI device. 469 */ 470 DECLINLINE(uint8_t) PCIDevGetInterruptLine(PPCIDEVICE pPciDev) 471 { 472 return pPciDev->config[VBOX_PCI_INTERRUPT_LINE]; 473 } 464 474 465 475 /** … … 475 485 476 486 487 /** 488 * Gets the interrupt pin config register. 489 * 490 * @returns The interrupt pin. 491 * @param pPciDev The PCI device. 492 */ 493 DECLINLINE(uint8_t) PCIDevGetInterruptPin(PPCIDEVICE pPciDev) 494 { 495 return pPciDev->config[VBOX_PCI_INTERRUPT_PIN]; 496 } 497 498 477 499 /** @} */ 478 500 479 501 #endif 502 -
trunk/include/VBox/vmm.h
r30160 r30488 312 312 /** Call GMMR0CheckSharedModules. */ 313 313 VMMR0_DO_GMM_CHECK_SHARED_MODULES, 314 /** Call GMMR0FindDuplicatePage. */ 315 VMMR0_DO_GMM_FIND_DUPLICATE_PAGE, 314 316 315 317 /** Set a GVMM or GMM configuration value. */ -
trunk/src/VBox/VMM/GMM.cpp
r30344 r30488 419 419 return VMMR3CallR0(pVM, VMMR0_DO_GMM_CHECK_SHARED_MODULES, 0, NULL); 420 420 } 421 422 #if defined(VBOX_STRICT) && HC_ARCH_BITS == 64 423 /** 424 * @see GMMR0FindDuplicatePage 425 */ 426 GMMR3DECL(bool) GMMR3IsDuplicatePage(PVM pVM, uint32_t idPage) 427 { 428 GMMFINDDUPLICATEPAGEREQ Req; 429 Req.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC; 430 Req.Hdr.cbReq = sizeof(Req); 431 Req.idPage = idPage; 432 Req.fDuplicate = false; 433 434 int rc = VMMR3CallR0(pVM, VMMR0_DO_GMM_FIND_DUPLICATE_PAGE, 0, &Req.Hdr); 435 if (rc == VINF_SUCCESS) 436 return Req.fDuplicate; 437 else 438 return false; 439 } 440 #endif /* VBOX_STRICT && HC_ARCH_BITS == 64 */ 441 -
trunk/src/VBox/VMM/PGM.cpp
r30050 r30488 641 641 static DECLCALLBACK(int) pgmR3CmdAssertCR3(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult); 642 642 # endif 643 # if defined(VBOX_STRICT) && HC_ARCH_BITS == 64 644 static DECLCALLBACK(int) pgmR3CmdCheckDuplicatePages(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult); 645 # endif 643 646 static DECLCALLBACK(int) pgmR3CmdPhysToFile(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult); 644 647 #endif … … 673 676 #ifdef VBOX_STRICT 674 677 { "pgmassertcr3", 0, 0, NULL, 0, NULL, 0, pgmR3CmdAssertCR3, "", "Check the shadow CR3 mapping." }, 678 #endif 679 #if defined(VBOX_STRICT) && HC_ARCH_BITS == 64 680 { "pgmcheckduppages", 0, 0, NULL, 0, NULL, 0, pgmR3CmdCheckDuplicatePages, "", "Check for duplicate pages in all running VMs." }, 675 681 #endif 676 682 { "pgmsyncalways", 0, 0, NULL, 0, NULL, 0, pgmR3CmdSyncAlways, "", "Toggle permanent CR3 syncing." }, … … 4156 4162 #endif /* VBOX_STRICT */ 4157 4163 4164 #if defined(VBOX_STRICT) && HC_ARCH_BITS == 64 4165 /** 4166 * The '.pgmcheckduppages' command. 4167 * 4168 * @returns VBox status. 4169 * @param pCmd Pointer to the command descriptor (as registered). 4170 * @param pCmdHlp Pointer to command helper functions. 4171 * @param pVM Pointer to the current VM (if any). 4172 * @param paArgs Pointer to (readonly) array of arguments. 4173 * @param cArgs Number of arguments in the array. 4174 */ 4175 static DECLCALLBACK(int) pgmR3CmdCheckDuplicatePages(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult) 4176 { 4177 unsigned cBallooned = 0; 4178 unsigned cShared = 0; 4179 unsigned cZero = 0; 4180 unsigned cUnique = 0; 4181 unsigned cDuplicate = 0; 4182 4183 pgmLock(pVM); 4184 4185 for (PPGMRAMRANGE pRam = pVM->pgm.s.pRamRangesR3; pRam; pRam = pRam->pNextR3) 4186 { 4187 PPGMPAGE pPage = &pRam->aPages[0]; 4188 RTGCPHYS GCPhys = pRam->GCPhys; 4189 uint32_t cLeft = pRam->cb >> PAGE_SHIFT; 4190 while (cLeft-- > 0) 4191 { 4192 if (PGM_PAGE_GET_TYPE(pPage) == PGMPAGETYPE_RAM) 4193 { 4194 switch (PGM_PAGE_GET_STATE(pPage)) 4195 { 4196 case PGM_PAGE_STATE_ZERO: 4197 cZero++; 4198 break; 4199 4200 case PGM_PAGE_STATE_BALLOONED: 4201 cBallooned++; 4202 break; 4203 4204 case PGM_PAGE_STATE_SHARED: 4205 cShared++; 4206 break; 4207 4208 case PGM_PAGE_STATE_ALLOCATED: 4209 case PGM_PAGE_STATE_WRITE_MONITORED: 4210 if (GMMR3IsDuplicatePage(pVM, PGM_PAGE_GET_PAGEID(pPage))) 4211 cDuplicate++; 4212 else 4213 cUnique++; 4214 4215 break; 4216 4217 default: 4218 AssertFailed(); 4219 break; 4220 } 4221 } 4222 4223 /* next */ 4224 pPage++; 4225 GCPhys += PAGE_SIZE; 4226 } 4227 } 4228 pgmUnlock(pVM); 4229 4230 pCmdHlp->pfnPrintf(pCmdHlp, NULL, "Number of zero pages %x\n", cZero); 4231 pCmdHlp->pfnPrintf(pCmdHlp, NULL, "Number of ballooned pages %x\n", cBallooned); 4232 pCmdHlp->pfnPrintf(pCmdHlp, NULL, "Number of shared pages %x\n", cShared); 4233 pCmdHlp->pfnPrintf(pCmdHlp, NULL, "Number of unique pages %x\n", cUnique); 4234 pCmdHlp->pfnPrintf(pCmdHlp, NULL, "Number of duplicate pages %x\n", cDuplicate); 4235 return VINF_SUCCESS; 4236 } 4237 4238 #endif /* VBOX_STRICT && HC_ARCH_BITS == 64*/ 4239 4158 4240 4159 4241 /** -
trunk/src/VBox/VMM/VMMR0/GMMR0.cpp
r30373 r30488 4189 4189 #endif 4190 4190 } 4191 4192 #if defined(VBOX_STRICT) && HC_ARCH_BITS == 64 4193 typedef struct 4194 { 4195 PGVM pGVM; 4196 PGMM pGMM; 4197 uint8_t *pSourcePage; 4198 bool fFoundDuplicate; 4199 } GMMFINDDUPPAGEINFO, *PGMMFINDDUPPAGEINFO; 4200 4201 /** 4202 * RTAvlU32DoWithAll callback. 4203 * 4204 * @returns 0 4205 * @param pNode The node to search. 4206 * @param pvInfo Pointer to the input parameters 4207 */ 4208 static DECLCALLBACK(int) gmmR0FindDupPageInChunk(PAVLU32NODECORE pNode, void *pvInfo) 4209 { 4210 PGMMCHUNK pChunk = (PGMMCHUNK)pNode; 4211 PGMMFINDDUPPAGEINFO pInfo = (PGMMFINDDUPPAGEINFO)pvInfo; 4212 PGVM pGVM = pInfo->pGVM; 4213 PGMM pGMM = pInfo->pGMM; 4214 uint8_t *pbChunk; 4215 4216 /* Only take chunks not mapped into this VM process; not entirely correct. */ 4217 if (!gmmR0IsChunkMapped(pGVM, pChunk, (PRTR3PTR)&pbChunk)) 4218 { 4219 int rc = gmmR0MapChunk(pGMM, pGVM, pChunk, (PRTR3PTR)&pbChunk); 4220 if (rc != VINF_SUCCESS) 4221 goto end; 4222 4223 /* 4224 * Look for duplicate pages 4225 */ 4226 unsigned iPage = (GMM_CHUNK_SIZE >> PAGE_SHIFT); 4227 while (iPage-- > 0) 4228 { 4229 if (GMM_PAGE_IS_PRIVATE(&pChunk->aPages[iPage])) 4230 { 4231 uint8_t *pbDestPage = pbChunk + (iPage << PAGE_SHIFT); 4232 4233 if (!memcmp(pInfo->pSourcePage, pbDestPage, PAGE_SIZE)) 4234 { 4235 pInfo->fFoundDuplicate = true; 4236 break; 4237 } 4238 } 4239 } 4240 gmmR0UnmapChunk(pGMM, pGVM, pChunk); 4241 } 4242 end: 4243 if (pInfo->fFoundDuplicate) 4244 return 1; /* stop search */ 4245 else 4246 return 0; 4247 } 4248 4249 /** 4250 * Find a duplicate of the specified page in other active VMs 4251 * 4252 * @returns VBox status code. 4253 * @param pVM VM handle 4254 * @param pReq Request packet 4255 */ 4256 GMMR0DECL(int) GMMR0FindDuplicatePageReq(PVM pVM, PGMMFINDDUPLICATEPAGEREQ pReq) 4257 { 4258 /* 4259 * Validate input and pass it on. 4260 */ 4261 AssertPtrReturn(pVM, VERR_INVALID_POINTER); 4262 AssertPtrReturn(pReq, VERR_INVALID_POINTER); 4263 AssertMsgReturn(pReq->Hdr.cbReq == sizeof(*pReq), ("%#x != %#x\n", pReq->Hdr.cbReq, sizeof(*pReq)), VERR_INVALID_PARAMETER); 4264 4265 PGMM pGMM; 4266 GMM_GET_VALID_INSTANCE(pGMM, VERR_INTERNAL_ERROR); 4267 4268 /* 4269 * Take the sempahore and do some more validations. 4270 */ 4271 int rc = RTSemFastMutexRequest(pGMM->Mtx); 4272 AssertRC(rc); 4273 if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM)) 4274 { 4275 PGVM pGVM; 4276 rc = GVMMR0ByVM(pVM, &pGVM); 4277 if (RT_FAILURE(rc)) 4278 goto end; 4279 4280 uint8_t *pbChunk; 4281 PGMMCHUNK pChunk = gmmR0GetChunk(pGMM, pReq->idPage >> GMM_CHUNKID_SHIFT); 4282 if (!pChunk) 4283 { 4284 AssertFailed(); 4285 goto end; 4286 } 4287 4288 if (!gmmR0IsChunkMapped(pGVM, pChunk, (PRTR3PTR)&pbChunk)) 4289 { 4290 AssertFailed(); 4291 goto end; 4292 } 4293 4294 uint8_t *pbSourcePage = pbChunk + ((pReq->idPage & GMM_PAGEID_IDX_MASK) << PAGE_SHIFT); 4295 4296 PGMMPAGE pPage = gmmR0GetPage(pGMM, pReq->idPage); 4297 if (!pPage) 4298 { 4299 AssertFailed(); 4300 rc = VERR_PGM_PHYS_INVALID_PAGE_ID; 4301 goto end; 4302 } 4303 GMMFINDDUPPAGEINFO Info; 4304 4305 Info.pGVM = pGVM; 4306 Info.pGMM = pGMM; 4307 Info.pSourcePage = pbSourcePage; 4308 Info.fFoundDuplicate = false; 4309 RTAvlU32DoWithAll(&pGMM->pChunks, true /* fFromLeft */, gmmR0FindDupPageInChunk, pGVM); 4310 4311 pReq->fDuplicate = Info.fFoundDuplicate; 4312 } 4313 else 4314 rc = VERR_INTERNAL_ERROR_5; 4315 4316 end: 4317 RTSemFastMutexRelease(pGMM->Mtx); 4318 return rc; 4319 } 4320 4321 #endif /* VBOX_STRICT && HC_ARCH_BITS == 64 */ 4322 -
trunk/src/VBox/VMM/VMMR0/VMMR0.cpp
r30251 r30488 986 986 #endif 987 987 988 #if defined(VBOX_STRICT) && HC_ARCH_BITS == 64 989 case VMMR0_DO_GMM_FIND_DUPLICATE_PAGE: 990 { 991 if (u64Arg) 992 return VERR_INVALID_PARAMETER; 993 return GMMR0FindDuplicatePageReq(pVM, (PGMMFINDDUPLICATEPAGEREQ)pReqHdr); 994 } 995 #endif 996 988 997 /* 989 998 * A quick GCFGM mock-up.
Note:
See TracChangeset
for help on using the changeset viewer.