Changeset 14378 in vbox for trunk/src/VBox
- Timestamp:
- Nov 19, 2008 7:36:20 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR0/PGMR0DynMap.cpp
r14376 r14378 32 32 #include <iprt/assert.h> 33 33 #include <iprt/cpuset.h> 34 #include <iprt/memobj.h> 35 #include <iprt/mp.h> 34 36 #include <iprt/spinlock.h> 35 37 #include <iprt/semaphore.h> … … 129 131 /** Array containing a copy of the original page tables. 130 132 * The entries are either X86PTE or X86PTEPAE according to fLegacyMode. */ 131 void *pvSavedPTs; 133 void *pvSavedPTEs; 134 /** List of segments. */ 135 PPGMR0DYNMAPSEG pSegHead; 132 136 } PGMR0DYNMAP; 133 137 /** Pointer to the ring-0 dynamic mapping cache */ … … 400 404 401 405 /** 406 * Shoots down the TLBs for all the cache pages, pgmR0DynMapTearDown helper. 407 * 408 * @param idCpu The current CPU. 409 * @param pvUser1 The dynamic mapping cache instance. 410 * @param pvUser2 Unused, NULL. 411 */ 412 static DECLCALLBACK(void) pgmR0DynMapShootDownTlbs(RTCPUID idCpu, void *pvUser1, void *pvUser2) 413 { 414 Assert(!pvUser2); 415 PPGMR0DYNMAP pThis = (PPGMR0DYNMAP)pvUser1; 416 AssertPtr(pThis == g_pPGMR0DynMap); 417 PPGMR0DYNMAPENTRY paPages = pThis->paPages; 418 uint32_t iPage = pThis->cPages; 419 while (iPage-- > 0) 420 ASMInvalidatePage(paPages[iPage].pvPage); 421 } 422 423 424 /** 402 425 * Called by PGMR0DynMapTermVM under the init lock. 403 426 * … … 407 430 static void pgmR0DynMapTearDown(PPGMR0DYNMAP pThis) 408 431 { 432 /* 433 * Restore the original page table entries 434 */ 435 PPGMR0DYNMAPENTRY paPages = pThis->paPages; 436 uint32_t iPage = pThis->cPages; 437 if (pThis->fLegacyMode) 438 { 439 X86PGUINT const *paSavedPTEs = (X86PGUINT const *)pThis->pvSavedPTEs; 440 while (iPage-- > 0) 441 { 442 X86PGUINT uOld = paPages[iPage].uPte.pLegacy->u; 443 X86PGUINT uOld2 = uOld; NOREF(uOld2); 444 X86PGUINT uNew = paSavedPTEs[iPage]; 445 while (!ASMAtomicCmpXchgExU32(&paPages[iPage].uPte.pLegacy->u, uNew, uOld, &uOld)) 446 AssertMsgFailed(("uOld=%#x uOld2=%#x uNew=%#x\n", uOld, uOld2, uNew)); 447 } 448 } 449 else 450 { 451 X86PGPAEUINT const *paSavedPTEs = (X86PGPAEUINT const *)pThis->pvSavedPTEs; 452 while (iPage-- > 0) 453 { 454 X86PGPAEUINT uOld = paPages[iPage].uPte.pPae->u; 455 X86PGPAEUINT uOld2 = uOld; NOREF(uOld2); 456 X86PGPAEUINT uNew = paSavedPTEs[iPage]; 457 while (!ASMAtomicCmpXchgExU64(&paPages[iPage].uPte.pPae->u, uNew, uOld, &uOld)) 458 AssertMsgFailed(("uOld=%#llx uOld2=%#llx uNew=%#llx\n", uOld, uOld2, uNew)); 459 } 460 } 461 462 /* 463 * Shoot down the TLBs on all CPUs before freeing them. 464 * If RTMpOnAll fails, make sure the TLBs are invalidated on the current CPU at least. 465 */ 466 int rc = RTMpOnAll(pgmR0DynMapShootDownTlbs, pThis, NULL); 467 AssertRC(rc); 468 if (RT_FAILURE(rc)) 469 { 470 iPage = pThis->cPages; 471 while (iPage-- > 0) 472 ASMInvalidatePage(paPages[iPage].pvPage); 473 } 474 475 /* 476 * Free the segments. 477 */ 478 while (pThis->pSegHead) 479 { 480 PPGMR0DYNMAPSEG pSeg = pThis->pSegHead; 481 pThis->pSegHead = pSeg->pNext; 482 483 int rc; 484 rc = RTR0MemObjFree(pSeg->hMemObjPT, true /* fFreeMappings */); AssertRC(rc); 485 pSeg->hMemObjPT = NIL_RTR0MEMOBJ; 486 rc = RTR0MemObjFree(pSeg->hMemObj, true /* fFreeMappings */); AssertRC(rc); 487 pSeg->hMemObj = NIL_RTR0MEMOBJ; 488 pSeg->pNext = NULL; 489 pSeg->iPage = UINT32_MAX; 490 pSeg->cPages = 0; 491 RTMemFree(pSeg); 492 } 493 494 /* 495 * Free the arrays and restore the initial state. 496 * The cLoadMax value is left behind for the next setup. 497 */ 498 RTMemFree(pThis->paPages); 499 pThis->paPages = NULL; 500 RTMemFree(pThis->pvSavedPTEs); 501 pThis->pvSavedPTEs = NULL; 502 pThis->cPages = 0; 503 pThis->cLoad = 0; 409 504 } 410 505
Note:
See TracChangeset
for help on using the changeset viewer.