Changeset 55910 in vbox
- Timestamp:
- May 18, 2015 1:36:19 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp
r55909 r55910 1379 1379 GCPhys, pPage, pPage->Core.Key, pPage->idx, pPage->GCPhys, pPage->enmKind)); 1380 1380 1381 NOREF(pvBuf); NOREF(enmAccessType); NOREF(enmOrigin); 1382 1383 /* 1384 * We don't have to be very sophisticated about this since there are relativly few calls here. 1385 * However, we must try our best to detect any non-cpu accesses (disk / networking). 1381 NOREF(pvBuf); NOREF(enmAccessType); 1382 1383 /* 1384 * Make sure the pool page wasn't modified by a different CPU. 1386 1385 */ 1387 1386 pgmLock(pVM); 1388 if (PHYS_PAGE_ADDRESS(GCPhys) != PHYS_PAGE_ADDRESS(pPage->GCPhys)) 1389 { 1390 /* Pool page changed while we were waiting for the lock; ignore. */ 1387 if (PHYS_PAGE_ADDRESS(GCPhys) == PHYS_PAGE_ADDRESS(pPage->GCPhys)) 1388 { 1389 Assert(pPage->enmKind != PGMPOOLKIND_FREE); 1390 1391 /* The max modification count before flushing depends on the context and page type. */ 1392 #ifdef IN_RING3 1393 uint16_t const cMaxModifications = 96; /* it's cheaper here, right? */ 1394 #else 1395 uint16_t cMaxModifications; 1396 if ( pPage->enmKind == PGMPOOLKIND_PAE_PT_FOR_PAE_PT 1397 || pPage->enmKind == PGMPOOLKIND_PAE_PT_FOR_32BIT_PT) 1398 cMaxModifications = 4; 1399 else 1400 cMaxModifications = 24; 1401 # ifdef IN_RC 1402 cMaxModifications *= 2; /* traps are cheaper than exists. */ 1403 # endif 1404 #endif 1405 1406 /* 1407 * We don't have to be very sophisticated about this since there are relativly few calls here. 1408 * However, we must try our best to detect any non-cpu accesses (disk / networking). 1409 */ 1410 if ( ( pPage->cModifications < cMaxModifications 1411 || pgmPoolIsPageLocked(pPage) ) 1412 && enmOrigin != PGMACCESSORIGIN_DEVICE 1413 && cbBuf <= 16) 1414 { 1415 /* Clear the shadow entry. */ 1416 if (!pPage->cModifications++) 1417 pgmPoolMonitorModifiedInsert(pPool, pPage); 1418 1419 if (cbBuf <= 8) 1420 pgmPoolMonitorChainChanging(pVCpu, pPool, pPage, GCPhys, pvBuf, (uint32_t)cbBuf); 1421 else 1422 { 1423 pgmPoolMonitorChainChanging(pVCpu, pPool, pPage, GCPhys, pvBuf, 8); 1424 pgmPoolMonitorChainChanging(pVCpu, pPool, pPage, GCPhys + 8, (uint8_t *)pvBuf + 8, (uint32_t)cbBuf - 8); 1425 } 1426 } 1427 else 1428 { 1429 /* ASSUME that VERR_PGM_POOL_CLEARED can be ignored here and that FFs will deal with it in due time. */ 1430 pgmPoolMonitorChainFlush(pPool, pPage); 1431 } 1432 1433 STAM_PROFILE_STOP_EX(&pPool->StatMonitorR3, &pPool->StatMonitorR3FlushPage, a); 1434 } 1435 else 1391 1436 Log(("CPU%d: PGM_ALL_CB_DECL pgm pool page for %RGp changed (to %RGp) while waiting!\n", pVCpu->idCpu, PHYS_PAGE_ADDRESS(GCPhys), PHYS_PAGE_ADDRESS(pPage->GCPhys))); 1392 pgmUnlock(pVM);1393 return VINF_PGM_HANDLER_DO_DEFAULT;1394 }1395 1396 Assert(pPage->enmKind != PGMPOOLKIND_FREE);1397 /** @todo we can do better than this now. */1398 if ( ( pPage->cModifications < 96 /* it's cheaper here. */1399 || pgmPoolIsPageLocked(pPage) )1400 && cbBuf <= 4)1401 {1402 /* Clear the shadow entry. */1403 if (!pPage->cModifications++)1404 pgmPoolMonitorModifiedInsert(pPool, pPage);1405 /** @todo r=bird: making unsafe assumption about not crossing entries here! */1406 pgmPoolMonitorChainChanging(pVCpu, pPool, pPage, GCPhys, pvBuf, 0 /* unknown write size */);1407 STAM_PROFILE_STOP(&pPool->StatMonitorR3, a);1408 }1409 else1410 {1411 pgmPoolMonitorChainFlush(pPool, pPage); /* ASSUME that VERR_PGM_POOL_CLEARED can be ignored here and that FFs will deal with it in due time. */1412 STAM_PROFILE_STOP_EX(&pPool->StatMonitorR3, &pPool->StatMonitorR3FlushPage, a);1413 }1414 1437 pgmUnlock(pVM); 1415 1438 return VINF_PGM_HANDLER_DO_DEFAULT; 1416 1439 } 1417 1418 1419 1440 1420 1441
Note:
See TracChangeset
for help on using the changeset viewer.