Changeset 30807 in vbox
- Timestamp:
- Jul 13, 2010 4:49:13 PM (14 years ago)
- File:
-
- 1 edited
-
trunk/src/VBox/VMM/PGMPhys.cpp (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/PGMPhys.cpp
r30756 r30807 3339 3339 } 3340 3340 3341 /** 3342 * Rendezvous callback used by pgmR3PhysUnmapChunk that clears all shadow pages 3343 * and all modification counters. 3344 * 3345 * This is only called on one of the EMTs while the other ones are waiting for 3346 * it to complete this function. 3347 * 3348 * @returns VINF_SUCCESS (VBox strict status code). 3349 * @param pVM The VM handle. 3350 * @param pVCpu The VMCPU for the EMT we're being called on. Unused. 3351 * @param pvUser User pointer. Unused 3352 * 3353 */ 3354 DECLCALLBACK(VBOXSTRICTRC) pgmR3PhysUnmapChunkRendezvous(PVM pVM, PVMCPU pVCpu, void *pvUser) 3355 { 3356 int rc = VINF_SUCCESS; 3357 pgmLock(pVM); 3358 3359 if (pVM->pgm.s.ChunkR3Map.c >= pVM->pgm.s.ChunkR3Map.cMax) 3360 { 3361 /* 3362 * Request the ring-0 part to unmap a chunk to make space in the mapping cache. 3363 */ 3364 GMMMAPUNMAPCHUNKREQ Req; 3365 Req.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC; 3366 Req.Hdr.cbReq = sizeof(Req); 3367 Req.pvR3 = NULL; 3368 Req.idChunkMap = NIL_GMM_CHUNKID; 3369 Req.idChunkUnmap = pgmR3PhysChunkFindUnmapCandidate(pVM); 3370 3371 rc = VMMR3CallR0(pVM, VMMR0_DO_GMM_MAP_UNMAP_CHUNK, 0, &Req.Hdr); 3372 if (RT_SUCCESS(rc)) 3373 { 3374 /* remove the unmapped one. */ 3375 PPGMCHUNKR3MAP pUnmappedChunk = (PPGMCHUNKR3MAP)RTAvlU32Remove(&pVM->pgm.s.ChunkR3Map.pTree, Req.idChunkUnmap); 3376 AssertRelease(pUnmappedChunk); 3377 pUnmappedChunk->pv = NULL; 3378 pUnmappedChunk->Core.Key = UINT32_MAX; 3379 #ifdef VBOX_WITH_2X_4GB_ADDR_SPACE 3380 MMR3HeapFree(pUnmappedChunk); 3381 #else 3382 MMR3UkHeapFree(pVM, pUnmappedChunk, MM_TAG_PGM_CHUNK_MAPPING); 3383 #endif 3384 pVM->pgm.s.ChunkR3Map.c--; 3385 3386 /* Chunk removed, so clear the chunk map TLB; PGMR3PhysChunkInvalidateTLB clears the page map TLB as well. */ 3387 PGMR3PhysChunkInvalidateTLB(pVM); 3388 3389 /* Flush all REM caches. */ 3390 REMFlushTBs(pVM); 3391 for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++) 3392 CPUMSetChangedFlags(&pVM->aCpus[idCpu], CPUM_CHANGED_GLOBAL_TLB_FLUSH); 3393 3394 /* Flush the pgm pool cache; call the internal rendezvous handler as we're already in a rendezvous handler here. */ 3395 pgmR3PoolClearAllRendezvous(pVM, &pVM->aCpus[0], false /* no need to flush the REM TLB as we already did that above */); 3396 } 3397 } 3398 pgmUnlock(pVM); 3399 return rc; 3400 } 3401 3402 /** 3403 * Unmap a chunk to free up virtual address space (request packet handler for pgmR3PhysChunkMap) 3404 * 3405 * @returns VBox status code. 3406 * @param pVM The VM to operate on. 3407 */ 3408 void pgmR3PhysUnmapChunk(PVM pVM) 3409 { 3410 int rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ONCE, pgmR3PhysUnmapChunkRendezvous, NULL); 3411 AssertRC(rc); 3412 } 3341 3413 3342 3414 /** … … 3374 3446 3375 3447 /* 3376 * Request the ring-0 part to map the chunk in question and if 3377 * necessary unmap another one to make space in the mapping cache. 3448 * Request the ring-0 part to map the chunk in question. 3378 3449 */ 3379 3450 GMMMAPUNMAPCHUNKREQ Req; … … 3383 3454 Req.idChunkMap = idChunk; 3384 3455 Req.idChunkUnmap = NIL_GMM_CHUNKID; 3385 if (pVM->pgm.s.ChunkR3Map.c >= pVM->pgm.s.ChunkR3Map.cMax)3386 Req.idChunkUnmap = pgmR3PhysChunkFindUnmapCandidate(pVM);3387 3456 3388 3457 /* Must be callable from any thread, so can't use VMMR3CallR0. */ … … 3403 3472 AssertRelease(fRc); 3404 3473 3405 /* remove the unmapped one. */ 3406 if (Req.idChunkUnmap != NIL_GMM_CHUNKID) 3407 { 3408 PPGMCHUNKR3MAP pUnmappedChunk = (PPGMCHUNKR3MAP)RTAvlU32Remove(&pVM->pgm.s.ChunkR3Map.pTree, Req.idChunkUnmap); 3409 AssertRelease(pUnmappedChunk); 3410 pUnmappedChunk->pv = NULL; 3411 pUnmappedChunk->Core.Key = UINT32_MAX; 3412 #ifdef VBOX_WITH_2X_4GB_ADDR_SPACE 3413 MMR3HeapFree(pUnmappedChunk); 3414 #else 3415 MMR3UkHeapFree(pVM, pUnmappedChunk, MM_TAG_PGM_CHUNK_MAPPING); 3416 #endif 3417 pVM->pgm.s.ChunkR3Map.c--; 3418 3419 /* Chunk removed, so clear the page map TLB as well (might still be referenced). */ 3420 PGMPhysInvalidatePageMapTLB(pVM); 3474 /* If we're running out of virtual address space, then we should unmap another chunk. */ 3475 if (pVM->pgm.s.ChunkR3Map.c >= pVM->pgm.s.ChunkR3Map.cMax) 3476 { 3477 /* Postpone the unmap operation (which requires a rendezvous operation) as we own the PGM lock here. */ 3478 int rc = VMR3ReqCallNoWaitU(pVM->pUVM, VMCPUID_ANY_QUEUE, (PFNRT)pgmR3PhysUnmapChunk, 1, pVM); 3479 AssertRC(rc); 3421 3480 } 3422 3481 }
Note:
See TracChangeset
for help on using the changeset viewer.

