- Timestamp:
- Oct 6, 2011 8:49:36 AM (14 years ago)
- svn:sync-xref-src-repo-rev:
- 74324
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/PGMAll.cpp
r38707 r38953 1452 1452 { 1453 1453 RTHCPTR HCPtrGuestCR3; 1454 rc = pgmPhysGCPhys2CCPtrInternal (pVM, pPage, GCPhysCR3, (void **)&HCPtrGuestCR3);1454 rc = pgmPhysGCPhys2CCPtrInternalDepr(pVM, pPage, GCPhysCR3, (void **)&HCPtrGuestCR3); 1455 1455 if (RT_SUCCESS(rc)) 1456 1456 { … … 1494 1494 { 1495 1495 RTHCPTR HCPtrGuestCR3; 1496 rc = pgmPhysGCPhys2CCPtrInternal (pVM, pPage, GCPhysCR3, (void **)&HCPtrGuestCR3);1496 rc = pgmPhysGCPhys2CCPtrInternalDepr(pVM, pPage, GCPhysCR3, (void **)&HCPtrGuestCR3); 1497 1497 if (RT_SUCCESS(rc)) 1498 1498 { … … 1544 1544 RTHCPTR HCPtr = NIL_RTHCPTR; 1545 1545 #if !defined(IN_RC) && !defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0) 1546 rc = pgmPhysGCPhys2CCPtrInternal (pVM, pPage, GCPhys, &HCPtr);1546 rc = pgmPhysGCPhys2CCPtrInternalDepr(pVM, pPage, GCPhys, &HCPtr); 1547 1547 AssertRC(rc); 1548 1548 #endif … … 1604 1604 { 1605 1605 RTHCPTR HCPtrGuestCR3; 1606 rc = pgmPhysGCPhys2CCPtrInternal (pVM, pPage, GCPhysCR3, (void **)&HCPtrGuestCR3);1606 rc = pgmPhysGCPhys2CCPtrInternalDepr(pVM, pPage, GCPhysCR3, (void **)&HCPtrGuestCR3); 1607 1607 if (RT_SUCCESS(rc)) 1608 1608 { … … 2337 2337 VMMDECL(bool) PGMIsLockOwner(PVM pVM) 2338 2338 { 2339 return PDMCritSectIsOwner(&pVM->pgm.s.CritSect );2339 return PDMCritSectIsOwner(&pVM->pgm.s.CritSectX); 2340 2340 } 2341 2341 … … 2365 2365 int pgmLock(PVM pVM) 2366 2366 { 2367 int rc = PDMCritSectEnter(&pVM->pgm.s.CritSect , VERR_SEM_BUSY);2367 int rc = PDMCritSectEnter(&pVM->pgm.s.CritSectX, VERR_SEM_BUSY); 2368 2368 #if defined(IN_RC) || defined(IN_RING0) 2369 2369 if (rc == VERR_SEM_BUSY) … … 2383 2383 void pgmUnlock(PVM pVM) 2384 2384 { 2385 PDMCritSectLeave(&pVM->pgm.s.CritSect); 2385 uint32_t cDeprecatedPageLocks = pVM->pgm.s.cDeprecatedPageLocks; 2386 pVM->pgm.s.cDeprecatedPageLocks = 0; 2387 int rc = PDMCritSectLeave(&pVM->pgm.s.CritSectX); 2388 if (rc == VINF_SEM_NESTED) 2389 pVM->pgm.s.cDeprecatedPageLocks = cDeprecatedPageLocks; 2386 2390 } 2387 2391 -
trunk/src/VBox/VMM/VMMAll/PGMAllBth.h
r38707 r38953 4425 4425 int rc = VINF_SUCCESS; 4426 4426 # else 4427 int rc = pgmPhysGCPhys2CCPtrInternal (pVM, pPageCR3, GCPhysCR3 & GST_CR3_PAGE_MASK, (void **)&HCPtrGuestCR3); /** @todo r=bird: This GCPhysCR3 masking isn't necessary. */4427 int rc = pgmPhysGCPhys2CCPtrInternalDepr(pVM, pPageCR3, GCPhysCR3 & GST_CR3_PAGE_MASK, (void **)&HCPtrGuestCR3); /** @todo r=bird: This GCPhysCR3 masking isn't necessary. */ 4428 4428 # endif 4429 4429 pgmUnlock(pVM); … … 4473 4473 int rc2 = VINF_SUCCESS; 4474 4474 # else 4475 int rc2 = pgmPhysGCPhys2CCPtrInternal (pVM, pPage, GCPhys, (void **)&HCPtr);4475 int rc2 = pgmPhysGCPhys2CCPtrInternalDepr(pVM, pPage, GCPhys, (void **)&HCPtr); 4476 4476 # endif 4477 4477 pgmUnlock(pVM); -
trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp
r37360 r38953 632 632 pVM->pgm.s.aHandyPages[iHandyPage].HCPhysGCPhys = GCPhys & ~(RTGCPHYS)PAGE_OFFSET_MASK; 633 633 634 const void *pvSharedPage = NULL; 635 634 void *pvSharedPage = NULL; 636 635 if (PGM_PAGE_IS_SHARED(pPage)) 637 636 { … … 645 644 pVM->pgm.s.cSharedPages--; 646 645 647 /* Grab the address of the page so we can make a copy later on. */648 rc = pgmPhys GCPhys2CCPtrInternalReadOnly(pVM, pPage, GCPhys, &pvSharedPage);646 /* Grab the address of the page so we can make a copy later on. (safe) */ 647 rc = pgmPhysPageMap(pVM, pPage, GCPhys, &pvSharedPage); 649 648 AssertRC(rc); 650 649 } … … 670 669 { 671 670 /* Get the virtual address of the new page. */ 672 void *pvNewPage;673 rc = pgmPhysGCPhys2CCPtrInternal(pVM, pPage, GCPhys, &pvNewPage);674 AssertRC(rc);675 if ( rc == VINF_SUCCESS)676 { 677 /** @todo todo write ASMMemCopyPage */678 memcpy(pvNewPage, pvSharedPage, PAGE_SIZE);671 PGMPAGEMAPLOCK PgMpLck; 672 void *pvNewPage; 673 rc = pgmPhysGCPhys2CCPtrInternal(pVM, pPage, GCPhys, &pvNewPage, &PgMpLck); AssertRC(rc); 674 if (RT_SUCCESS(rc)) 675 { 676 memcpy(pvNewPage, pvSharedPage, PAGE_SIZE); /** @todo todo write ASMMemCopyPage */ 677 pgmPhysReleaseInternalPageMappingLock(pVM, &PgMpLck); 679 678 } 680 679 } … … 922 921 * 923 922 * @remarks Called from within the PGM critical section. The mapping is only 924 * valid while you rinside this section.923 * valid while you are inside this section. 925 924 */ 926 925 int pgmPhysPageMapByPageID(PVM pVM, uint32_t idPage, RTHCPHYS HCPhys, void **ppv) … … 1120 1119 * 1121 1120 * @remarks Called from within the PGM critical section. The mapping is only 1122 * valid while you r inside thissection.1121 * valid while you are inside section. 1123 1122 */ 1124 1123 int pgmPhysPageMakeWritableAndMap(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys, void **ppv) … … 1156 1155 * 1157 1156 * @remarks Called from within the PGM critical section. The mapping is only 1158 * valid while you r inside thissection.1157 * valid while you are inside section. 1159 1158 */ 1160 1159 int pgmPhysPageMap(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys, void **ppv) … … 1184 1183 * 1185 1184 * @remarks Called from within the PGM critical section. The mapping is only 1186 * valid while you rinside this section.1185 * valid while you are inside this section. 1187 1186 */ 1188 1187 int pgmPhysPageMapReadOnly(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys, void const **ppv) … … 1292 1291 * 1293 1292 * @internal 1294 */ 1295 int pgmPhysGCPhys2CCPtrInternal(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys, void **ppv) 1293 * @deprecated Use pgmPhysGCPhys2CCPtrInternalEx. 1294 */ 1295 int pgmPhysGCPhys2CCPtrInternalDepr(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys, void **ppv) 1296 1296 { 1297 1297 int rc; 1298 1298 AssertReturn(pPage, VERR_INTERNAL_ERROR); 1299 1299 PGM_LOCK_ASSERT_OWNER(pVM); 1300 pVM->pgm.s.cDeprecatedPageLocks++; 1300 1301 1301 1302 /* … … 1333 1334 } 1334 1335 1335 1336 /** 1337 * Internal version of PGMPhysGCPhys2CCPtrReadOnly that expects the caller to 1338 * own the PGM lock and therefore not need to lock the mapped page. 1336 #if !defined(IN_RC) && !defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0) 1337 1338 /** 1339 * Locks a page mapping for writing. 1340 * 1341 * @param pVM The VM handle. 1342 * @param pPage The page. 1343 * @param pTlbe The mapping TLB entry for the page. 1344 * @param pLock The lock structure (output). 1345 */ 1346 DECLINLINE(void) pgmPhysPageMapLockForWriting(PVM pVM, PPGMPAGE pPage, PPGMPAGEMAPTLBE pTlbe, PPGMPAGEMAPLOCK pLock) 1347 { 1348 PPGMPAGEMAP pMap = pTlbe->pMap; 1349 if (pMap) 1350 pMap->cRefs++; 1351 1352 unsigned cLocks = PGM_PAGE_GET_WRITE_LOCKS(pPage); 1353 if (RT_LIKELY(cLocks < PGM_PAGE_MAX_LOCKS - 1)) 1354 { 1355 if (cLocks == 0) 1356 pVM->pgm.s.cWriteLockedPages++; 1357 PGM_PAGE_INC_WRITE_LOCKS(pPage); 1358 } 1359 else if (cLocks != PGM_PAGE_MAX_LOCKS) 1360 { 1361 PGM_PAGE_INC_WRITE_LOCKS(pPage); 1362 AssertMsgFailed(("%R[pgmpage] is entering permanent write locked state!\n", pPage)); 1363 if (pMap) 1364 pMap->cRefs++; /* Extra ref to prevent it from going away. */ 1365 } 1366 1367 pLock->uPageAndType = (uintptr_t)pPage | PGMPAGEMAPLOCK_TYPE_WRITE; 1368 pLock->pvMap = pMap; 1369 } 1370 1371 /** 1372 * Locks a page mapping for reading. 1373 * 1374 * @param pVM The VM handle. 1375 * @param pPage The page. 1376 * @param pTlbe The mapping TLB entry for the page. 1377 * @param pLock The lock structure (output). 1378 */ 1379 DECLINLINE(void) pgmPhysPageMapLockForReading(PVM pVM, PPGMPAGE pPage, PPGMPAGEMAPTLBE pTlbe, PPGMPAGEMAPLOCK pLock) 1380 { 1381 PPGMPAGEMAP pMap = pTlbe->pMap; 1382 if (pMap) 1383 pMap->cRefs++; 1384 1385 unsigned cLocks = PGM_PAGE_GET_READ_LOCKS(pPage); 1386 if (RT_LIKELY(cLocks < PGM_PAGE_MAX_LOCKS - 1)) 1387 { 1388 if (cLocks == 0) 1389 pVM->pgm.s.cReadLockedPages++; 1390 PGM_PAGE_INC_READ_LOCKS(pPage); 1391 } 1392 else if (cLocks != PGM_PAGE_MAX_LOCKS) 1393 { 1394 PGM_PAGE_INC_READ_LOCKS(pPage); 1395 AssertMsgFailed(("%R[pgmpage] is entering permanent read locked state!\n", pPage)); 1396 if (pMap) 1397 pMap->cRefs++; /* Extra ref to prevent it from going away. */ 1398 } 1399 1400 pLock->uPageAndType = (uintptr_t)pPage | PGMPAGEMAPLOCK_TYPE_READ; 1401 pLock->pvMap = pMap; 1402 } 1403 1404 #endif /* !IN_RC && !VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0 */ 1405 1406 1407 /** 1408 * Internal version of PGMPhysGCPhys2CCPtr that expects the caller to 1409 * own the PGM lock and have access to the page structure. 1339 1410 * 1340 1411 * @returns VBox status code. … … 1347 1418 * @param pPage Pointer to the PGMPAGE structure for the page. 1348 1419 * @param ppv Where to store the address corresponding to GCPhys. 1420 * @param pLock Where to store the lock information that 1421 * pgmPhysReleaseInternalPageMappingLock needs. 1349 1422 * 1350 1423 * @internal 1351 1424 */ 1352 int pgmPhysGCPhys2CCPtrInternalReadOnly(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys, const void **ppv) 1425 int pgmPhysGCPhys2CCPtrInternal(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys, void **ppv, PPGMPAGEMAPLOCK pLock) 1426 { 1427 int rc; 1428 AssertReturn(pPage, VERR_INTERNAL_ERROR); 1429 PGM_LOCK_ASSERT_OWNER(pVM); 1430 1431 /* 1432 * Make sure the page is writable. 1433 */ 1434 if (RT_UNLIKELY(PGM_PAGE_GET_STATE(pPage) != PGM_PAGE_STATE_ALLOCATED)) 1435 { 1436 rc = pgmPhysPageMakeWritable(pVM, pPage, GCPhys); 1437 if (RT_FAILURE(rc)) 1438 return rc; 1439 AssertMsg(rc == VINF_SUCCESS || rc == VINF_PGM_SYNC_CR3 /* not returned */, ("%Rrc\n", rc)); 1440 } 1441 Assert(PGM_PAGE_GET_HCPHYS(pPage) != 0); 1442 1443 /* 1444 * Do the job. 1445 */ 1446 #if defined(IN_RC) || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0) 1447 void *pv; 1448 PVMCPU pVCpu = VMMGetCpu(pVM); 1449 rc = pgmRZDynMapHCPageInlined(pVCpu, 1450 PGM_PAGE_GET_HCPHYS(pPage), 1451 &pv 1452 RTLOG_COMMA_SRC_POS); 1453 if (RT_FAILURE(rc)) 1454 return rc; 1455 *ppv = (void *)((uintptr_t)pv | (uintptr_t)(GCPhys & PAGE_OFFSET_MASK)); 1456 pLock->pvPage = pv; 1457 pLock->pVCpu = pVCpu; 1458 1459 #else 1460 PPGMPAGEMAPTLBE pTlbe; 1461 rc = pgmPhysPageQueryTlbeWithPage(pVM, pPage, GCPhys, &pTlbe); 1462 if (RT_FAILURE(rc)) 1463 return rc; 1464 pgmPhysPageMapLockForWriting(pVM, pPage, pTlbe, pLock); 1465 *ppv = (void *)((uintptr_t)pTlbe->pv | (uintptr_t)(GCPhys & PAGE_OFFSET_MASK)); 1466 #endif 1467 return VINF_SUCCESS; 1468 } 1469 1470 1471 /** 1472 * Internal version of PGMPhysGCPhys2CCPtrReadOnly that expects the caller to 1473 * own the PGM lock and have access to the page structure. 1474 * 1475 * @returns VBox status code. 1476 * @retval VINF_SUCCESS on success. 1477 * @retval VERR_PGM_PHYS_PAGE_RESERVED it it's a valid page but has no physical backing. 1478 * @retval VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS if it's not a valid physical address. 1479 * 1480 * @param pVM The VM handle. 1481 * @param GCPhys The guest physical address of the page that should be mapped. 1482 * @param pPage Pointer to the PGMPAGE structure for the page. 1483 * @param ppv Where to store the address corresponding to GCPhys. 1484 * @param pLock Where to store the lock information that 1485 * pgmPhysReleaseInternalPageMappingLock needs. 1486 * 1487 * @internal 1488 */ 1489 int pgmPhysGCPhys2CCPtrInternalReadOnly(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys, const void **ppv, PPGMPAGEMAPLOCK pLock) 1353 1490 { 1354 1491 AssertReturn(pPage, VERR_INTERNAL_ERROR); … … 1357 1494 1358 1495 /* 1359 * Get the mapping address.1496 * Do the job. 1360 1497 */ 1361 1498 #if defined(IN_RC) || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0) 1362 1499 void *pv; 1363 int rc = pgmRZDynMapHCPageInlined(VMMGetCpu(pVM), 1500 PVMCPU pVCpu = VMMGetCpu(pVM); 1501 int rc = pgmRZDynMapHCPageInlined(pVCpu, 1364 1502 PGM_PAGE_GET_HCPHYS(pPage), 1365 1503 &pv … … 1368 1506 return rc; 1369 1507 *ppv = (void *)((uintptr_t)pv | (uintptr_t)(GCPhys & PAGE_OFFSET_MASK)); 1508 pLock->pvPage = pv; 1509 pLock->pVCpu = pVCpu; 1510 1370 1511 #else 1371 1512 PPGMPAGEMAPTLBE pTlbe; … … 1373 1514 if (RT_FAILURE(rc)) 1374 1515 return rc; 1516 pgmPhysPageMapLockForReading(pVM, pPage, pTlbe, pLock); 1375 1517 *ppv = (void *)((uintptr_t)pTlbe->pv | (uintptr_t)(GCPhys & PAGE_OFFSET_MASK)); 1376 1518 #endif … … 1382 1524 * Requests the mapping of a guest page into the current context. 1383 1525 * 1384 * This API should only be used for very short term, as it will consume 1385 * scarse resources (R0 and GC) in the mapping cache. When you're done1386 * with the page,call PGMPhysReleasePageMappingLock() ASAP to release it.1526 * This API should only be used for very short term, as it will consume scarse 1527 * resources (R0 and GC) in the mapping cache. When you're done with the page, 1528 * call PGMPhysReleasePageMappingLock() ASAP to release it. 1387 1529 * 1388 1530 * This API will assume your intention is to write to the page, and will … … 1396 1538 * 1397 1539 * @param pVM The VM handle. 1398 * @param GCPhys The guest physical address of the page that should be mapped. 1540 * @param GCPhys The guest physical address of the page that should be 1541 * mapped. 1399 1542 * @param ppv Where to store the address corresponding to GCPhys. 1400 * @param pLock Where to store the lock information that PGMPhysReleasePageMappingLock needs. 1543 * @param pLock Where to store the lock information that 1544 * PGMPhysReleasePageMappingLock needs. 1401 1545 * 1402 1546 * @remarks The caller is responsible for dealing with access handlers. 1403 1547 * @todo Add an informational return code for pages with access handlers? 1404 1548 * 1405 * @remark Avoid calling this API from within critical sections (other than the 1406 * PGM one) because of the deadlock risk. External threads may need to 1407 * delegate jobs to the EMTs. 1549 * @remark Avoid calling this API from within critical sections (other than 1550 * the PGM one) because of the deadlock risk. External threads may 1551 * need to delegate jobs to the EMTs. 1552 * @remarks Only one page is mapped! Make no assumption about what's after or 1553 * before the returned page! 1408 1554 * @thread Any thread. 1409 1555 */ … … 1446 1592 1447 1593 #else /* IN_RING3 || IN_RING0 */ 1448 /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */1449 /** @todo : This can be dangerous if abused for more than one page; the ring-3 mapping is only valid for ranges that do NOT cross a chunk boundary. */1450 /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */1451 1452 1594 /* 1453 1595 * Query the Physical TLB entry for the page (may fail). … … 1476 1618 * Now, just perform the locking and calculate the return address. 1477 1619 */ 1478 PPGMPAGEMAP pMap = pTlbe->pMap; 1479 if (pMap) 1480 pMap->cRefs++; 1481 1482 unsigned cLocks = PGM_PAGE_GET_WRITE_LOCKS(pPage); 1483 if (RT_LIKELY(cLocks < PGM_PAGE_MAX_LOCKS - 1)) 1484 { 1485 if (cLocks == 0) 1486 pVM->pgm.s.cWriteLockedPages++; 1487 PGM_PAGE_INC_WRITE_LOCKS(pPage); 1488 } 1489 else if (cLocks != PGM_PAGE_GET_WRITE_LOCKS(pPage)) 1490 { 1491 PGM_PAGE_INC_WRITE_LOCKS(pPage); 1492 AssertMsgFailed(("%RGp / %R[pgmpage] is entering permanent write locked state!\n", GCPhys, pPage)); 1493 if (pMap) 1494 pMap->cRefs++; /* Extra ref to prevent it from going away. */ 1495 } 1496 1620 pgmPhysPageMapLockForWriting(pVM, pPage, pTlbe, pLock); 1497 1621 *ppv = (void *)((uintptr_t)pTlbe->pv | (uintptr_t)(GCPhys & PAGE_OFFSET_MASK)); 1498 pLock->uPageAndType = (uintptr_t)pPage | PGMPAGEMAPLOCK_TYPE_WRITE;1499 pLock->pvMap = pMap;1500 1622 } 1501 1623 } … … 1510 1632 * Requests the mapping of a guest page into the current context. 1511 1633 * 1512 * This API should only be used for very short term, as it will consume 1513 * scarse resources (R0 and GC) in the mapping cache. When you're done1514 * with the page,call PGMPhysReleasePageMappingLock() ASAP to release it.1634 * This API should only be used for very short term, as it will consume scarse 1635 * resources (R0 and GC) in the mapping cache. When you're done with the page, 1636 * call PGMPhysReleasePageMappingLock() ASAP to release it. 1515 1637 * 1516 1638 * @returns VBox status code. … … 1520 1642 * 1521 1643 * @param pVM The VM handle. 1522 * @param GCPhys The guest physical address of the page that should be mapped. 1644 * @param GCPhys The guest physical address of the page that should be 1645 * mapped. 1523 1646 * @param ppv Where to store the address corresponding to GCPhys. 1524 * @param pLock Where to store the lock information that PGMPhysReleasePageMappingLock needs. 1647 * @param pLock Where to store the lock information that 1648 * PGMPhysReleasePageMappingLock needs. 1525 1649 * 1526 1650 * @remarks The caller is responsible for dealing with access handlers. 1527 1651 * @todo Add an informational return code for pages with access handlers? 1528 1652 * 1529 * @remark 1653 * @remarks Avoid calling this API from within critical sections (other than 1530 1654 * the PGM one) because of the deadlock risk. 1655 * @remarks Only one page is mapped! Make no assumption about what's after or 1656 * before the returned page! 1531 1657 * @thread Any thread. 1532 1658 */ … … 1567 1693 1568 1694 #else /* IN_RING3 || IN_RING0 */ 1569 1570 /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */1571 /** @todo : This can be dangerous if abused for more than one page; the ring-3 mapping is only valid for ranges that do NOT cross a chunk boundary. */1572 /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */1573 1574 1695 /* 1575 1696 * Query the Physical TLB entry for the page (may fail). … … 1588 1709 * Now, just perform the locking and calculate the return address. 1589 1710 */ 1590 PPGMPAGEMAP pMap = pTlbe->pMap; 1591 if (pMap) 1592 pMap->cRefs++; 1593 1594 unsigned cLocks = PGM_PAGE_GET_READ_LOCKS(pPage); 1595 if (RT_LIKELY(cLocks < PGM_PAGE_MAX_LOCKS - 1)) 1596 { 1597 if (cLocks == 0) 1598 pVM->pgm.s.cReadLockedPages++; 1599 PGM_PAGE_INC_READ_LOCKS(pPage); 1600 } 1601 else if (cLocks != PGM_PAGE_GET_READ_LOCKS(pPage)) 1602 { 1603 PGM_PAGE_INC_READ_LOCKS(pPage); 1604 AssertMsgFailed(("%RGp / %R[pgmpage] is entering permanent readonly locked state!\n", GCPhys, pPage)); 1605 if (pMap) 1606 pMap->cRefs++; /* Extra ref to prevent it from going away. */ 1607 } 1608 1711 pgmPhysPageMapLockForReading(pVM, pPage, pTlbe, pLock); 1609 1712 *ppv = (void *)((uintptr_t)pTlbe->pv | (uintptr_t)(GCPhys & PAGE_OFFSET_MASK)); 1610 pLock->uPageAndType = (uintptr_t)pPage | PGMPAGEMAPLOCK_TYPE_READ;1611 pLock->pvMap = pMap;1612 1713 } 1613 1714 } … … 1764 1865 pgmUnlock(pVM); 1765 1866 #endif /* IN_RING3 */ 1867 } 1868 1869 1870 /** 1871 * Release the internal mapping of a guest page. 1872 * 1873 * This is the counter part of pgmPhysGCPhys2CCPtrInternalEx and 1874 * pgmPhysGCPhys2CCPtrInternalReadOnly. 1875 * 1876 * @param pVM The VM handle. 1877 * @param pLock The lock structure initialized by the mapping function. 1878 * 1879 * @remarks Caller must hold the PGM lock. 1880 */ 1881 void pgmPhysReleaseInternalPageMappingLock(PVM pVM, PPGMPAGEMAPLOCK pLock) 1882 { 1883 PGM_LOCK_ASSERT_OWNER(pVM); 1884 PGMPhysReleasePageMappingLock(pVM, pLock); /* lazy for now */ 1766 1885 } 1767 1886 … … 1780 1899 * @param pVM The VM handle. 1781 1900 * @param GCPhys The GC physical address to convert. 1782 * @param cbRange Physical range1783 1901 * @param pR3Ptr Where to store the R3 pointer on success. 1784 1902 * 1785 1903 * @deprecated Avoid when possible! 1786 1904 */ 1787 VMMDECL(int) PGMPhysGCPhys2R3Ptr(PVM pVM, RTGCPHYS GCPhys, RTUINT cbRange, PRTR3PTR pR3Ptr)1905 int pgmPhysGCPhys2R3Ptr(PVM pVM, RTGCPHYS GCPhys, PRTR3PTR pR3Ptr) 1788 1906 { 1789 1907 /** @todo this is kind of hacky and needs some more work. */ … … 1792 1910 #endif 1793 1911 1794 Log((" PGMPhysGCPhys2R3Ptr(,%RGp,%#x,): dont use this API!\n", GCPhys, cbRange)); /** @todo eliminate this API! */1912 Log(("pgmPhysGCPhys2R3Ptr(,%RGp,): dont use this API!\n", GCPhys)); /** @todo eliminate this API! */ 1795 1913 #if defined(IN_RC) || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0) 1796 1914 AssertFailedReturn(VERR_NOT_IMPLEMENTED); … … 1802 1920 int rc = pgmPhysGetPageAndRangeEx(pVM, GCPhys, &pPage, &pRam); 1803 1921 if (RT_SUCCESS(rc)) 1804 rc = pgmPhysGCPhys2CCPtrInternal (pVM, pPage, GCPhys, (void **)pR3Ptr);1922 rc = pgmPhysGCPhys2CCPtrInternalDepr(pVM, pPage, GCPhys, (void **)pR3Ptr); 1805 1923 1806 1924 pgmUnlock(pVM); … … 1809 1927 #endif 1810 1928 } 1811 1812 1813 #ifdef VBOX_STRICT1814 /**1815 * PGMPhysGCPhys2R3Ptr convenience for use with assertions.1816 *1817 * @returns The R3Ptr, NIL_RTR3PTR on failure.1818 * @param pVM The VM handle.1819 * @param GCPhys The GC Physical address.1820 * @param cbRange Physical range.1821 *1822 * @deprecated Avoid when possible.1823 */1824 VMMDECL(RTR3PTR) PGMPhysGCPhys2R3PtrAssert(PVM pVM, RTGCPHYS GCPhys, RTUINT cbRange)1825 {1826 RTR3PTR R3Ptr;1827 int rc = PGMPhysGCPhys2R3Ptr(pVM, GCPhys, cbRange, &R3Ptr);1828 if (RT_SUCCESS(rc))1829 return R3Ptr;1830 return NIL_RTR3PTR;1831 }1832 #endif /* VBOX_STRICT */1833 1929 1834 1930 … … 1931 2027 * Whatever we do we need the source page, map it first. 1932 2028 */ 1933 const void *pvSrc = NULL; 1934 int rc = pgmPhysGCPhys2CCPtrInternalReadOnly(pVM, pPage, GCPhys, &pvSrc); 2029 PGMPAGEMAPLOCK PgMpLck; 2030 const void *pvSrc = NULL; 2031 int rc = pgmPhysGCPhys2CCPtrInternalReadOnly(pVM, pPage, GCPhys, &pvSrc, &PgMpLck); 1935 2032 if (RT_FAILURE(rc)) 1936 2033 { … … 1977 2074 /* In R0 and RC the callbacks cannot handle this context, so we'll fail. */ 1978 2075 //AssertReleaseMsgFailed(("Wrong API! GCPhys=%RGp cb=%#x\n", GCPhys, cb)); 2076 pgmPhysReleaseInternalPageMappingLock(pVM, &PgMpLck); 1979 2077 return VERR_PGM_PHYS_WR_HIT_HANDLER; 1980 2078 #endif … … 2018 2116 /* In R0 and RC the callbacks cannot handle this context, so we'll fail. */ 2019 2117 //AssertReleaseMsgFailed(("Wrong API! GCPhys=%RGp cb=%#x\n", GCPhys, cb)); 2118 pgmPhysReleaseInternalPageMappingLock(pVM, &PgMpLck); 2020 2119 return VERR_PGM_PHYS_WR_HIT_HANDLER; 2021 2120 #endif … … 2027 2126 if (rc == VINF_PGM_HANDLER_DO_DEFAULT) 2028 2127 memcpy(pvBuf, pvSrc, cb); 2128 pgmPhysReleaseInternalPageMappingLock(pVM, &PgMpLck); 2029 2129 return rc; 2030 2130 } … … 2094 2194 * Get the pointer to the page. 2095 2195 */ 2096 const void *pvSrc; 2097 int rc = pgmPhysGCPhys2CCPtrInternalReadOnly(pVM, pPage, pRam->GCPhys + off, &pvSrc); 2196 PGMPAGEMAPLOCK PgMpLck; 2197 const void *pvSrc; 2198 int rc = pgmPhysGCPhys2CCPtrInternalReadOnly(pVM, pPage, pRam->GCPhys + off, &pvSrc, &PgMpLck); 2098 2199 if (RT_SUCCESS(rc)) 2200 { 2099 2201 memcpy(pvBuf, pvSrc, cb); 2202 pgmPhysReleaseInternalPageMappingLock(pVM, &PgMpLck); 2203 } 2100 2204 else 2101 2205 { … … 2164 2268 static int pgmPhysWriteHandler(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys, void const *pvBuf, size_t cbWrite) 2165 2269 { 2166 void *pvDst = NULL; 2167 int rc; 2270 PGMPAGEMAPLOCK PgMpLck; 2271 void *pvDst = NULL; 2272 int rc; 2168 2273 2169 2274 /* … … 2196 2301 Log5(("pgmPhysWriteHandler: GCPhys=%RGp cbRange=%#x pPage=%R[pgmpage] phys %s\n", GCPhys, cbRange, pPage, R3STRING(pCur->pszDesc) )); 2197 2302 if (!PGM_PAGE_IS_MMIO(pPage)) 2198 rc = pgmPhysGCPhys2CCPtrInternal(pVM, pPage, GCPhys, &pvDst );2303 rc = pgmPhysGCPhys2CCPtrInternal(pVM, pPage, GCPhys, &pvDst, &PgMpLck); 2199 2304 else 2200 2305 rc = VINF_SUCCESS; … … 2217 2322 pCur = NULL; /* might not be valid anymore. */ 2218 2323 # endif 2219 if (rc == VINF_PGM_HANDLER_DO_DEFAULT) 2220 memcpy(pvDst, pvBuf, cbRange); 2324 if (rc == VINF_PGM_HANDLER_DO_DEFAULT && pvDst) 2325 { 2326 if (pvDst) 2327 memcpy(pvDst, pvBuf, cbRange); 2328 } 2221 2329 else 2222 2330 AssertLogRelMsg(rc == VINF_SUCCESS || rc == VINF_PGM_HANDLER_DO_DEFAULT, ("rc=%Rrc GCPhys=%RGp pPage=%R[pgmpage] %s\n", rc, GCPhys, pPage, (pCur) ? pCur->pszDesc : "")); … … 2226 2334 GCPhys, pPage, rc), rc); 2227 2335 if (RT_LIKELY(cbRange == cbWrite)) 2336 { 2337 if (pvBuf) 2338 pgmPhysReleaseInternalPageMappingLock(pVM, &PgMpLck); 2228 2339 return VINF_SUCCESS; 2340 } 2229 2341 2230 2342 /* more fun to be had below */ … … 2262 2374 2263 2375 Log5(("pgmPhysWriteHandler: GCPhys=%RGp cbRange=%#x pPage=%R[pgmpage] virt %s\n", GCPhys, cbRange, pPage, R3STRING(pCur->pszDesc) )); 2264 rc = pgmPhysGCPhys2CCPtrInternal(pVM, pPage, GCPhys, &pvDst );2376 rc = pgmPhysGCPhys2CCPtrInternal(pVM, pPage, GCPhys, &pvDst, &PgMpLck); 2265 2377 if (RT_SUCCESS(rc)) 2266 2378 { … … 2285 2397 GCPhys, pPage, rc), rc); 2286 2398 if (RT_LIKELY(cbRange == cbWrite)) 2399 { 2400 if (pvBuf) 2401 pgmPhysReleaseInternalPageMappingLock(pVM, &PgMpLck); 2287 2402 return VINF_SUCCESS; 2403 } 2288 2404 2289 2405 /* more fun to be had below */ … … 2304 2420 if (!pvDst) 2305 2421 { 2306 rc = pgmPhysGCPhys2CCPtrInternal(pVM, pPage, GCPhys, &pvDst );2422 rc = pgmPhysGCPhys2CCPtrInternal(pVM, pPage, GCPhys, &pvDst, &PgMpLck); 2307 2423 AssertLogRelMsgReturn(RT_SUCCESS(rc), 2308 2424 ("pgmPhysGCPhys2CCPtrInternal failed on %RGp / %R[pgmpage] -> %Rrc\n", … … 2434 2550 NOREF(cbRange); 2435 2551 //AssertReleaseMsgFailed(("Wrong API! GCPhys=%RGp cbRange=%#x\n", GCPhys, cbRange)); 2552 pgmPhysReleaseInternalPageMappingLock(pVM, &PgMpLck); 2436 2553 return VERR_PGM_PHYS_WR_HIT_HANDLER; 2437 2554 #endif … … 2463 2580 NOREF(cbRange); 2464 2581 //AssertReleaseMsgFailed(("Wrong API! GCPhys=%RGp cbRange=%#x\n", GCPhys, cbRange)); 2582 pgmPhysReleaseInternalPageMappingLock(pVM, &PgMpLck); 2465 2583 return VERR_PGM_PHYS_WR_HIT_HANDLER; 2466 2584 #endif … … 2519 2637 NOREF(cbRange); 2520 2638 //AssertReleaseMsgFailed(("Wrong API! GCPhys=%RGp cbRange=%#x\n", GCPhys, cbRange)); 2639 pgmPhysReleaseInternalPageMappingLock(pVM, &PgMpLck); 2521 2640 return VERR_PGM_PHYS_WR_HIT_HANDLER; 2522 2641 #endif … … 2529 2648 */ 2530 2649 if (cbRange >= cbWrite) 2650 { 2651 pgmPhysReleaseInternalPageMappingLock(pVM, &PgMpLck); 2531 2652 return VINF_SUCCESS; 2653 } 2532 2654 2533 2655 cbWrite -= cbRange; … … 2608 2730 * Get the pointer to the page. 2609 2731 */ 2610 void *pvDst; 2611 int rc = pgmPhysGCPhys2CCPtrInternal(pVM, pPage, pRam->GCPhys + off, &pvDst); 2732 PGMPAGEMAPLOCK PgMpLck; 2733 void *pvDst; 2734 int rc = pgmPhysGCPhys2CCPtrInternal(pVM, pPage, pRam->GCPhys + off, &pvDst, &PgMpLck); 2612 2735 if (RT_SUCCESS(rc)) 2613 2736 { 2614 2737 Assert(!PGM_PAGE_IS_BALLOONED(pPage)); 2615 2738 memcpy(pvDst, pvBuf, cb); 2739 pgmPhysReleaseInternalPageMappingLock(pVM, &PgMpLck); 2616 2740 } 2617 else2618 2741 /* Ignore writes to ballooned pages. */ 2619 if (!PGM_PAGE_IS_BALLOONED(pPage))2742 else if (!PGM_PAGE_IS_BALLOONED(pPage)) 2620 2743 AssertLogRelMsgFailed(("pgmPhysGCPhys2CCPtrInternal failed on %RGp / %R[pgmpage] -> %Rrc\n", 2621 2744 pRam->GCPhys + off, pPage, rc)); … … 3279 3402 { 3280 3403 /** @todo we should check reserved bits ... */ 3281 void *pvSrc; 3282 rc = PGM_GCPHYS_2_PTR_V2(pVM, pVCpu, GCPhys, &pvSrc); 3404 PGMPAGEMAPLOCK PgMpLck; 3405 void const *pvSrc; 3406 rc = PGMPhysGCPhys2CCPtrReadOnly(pVM, GCPhys, &pvSrc, &PgMpLck); 3283 3407 switch (rc) 3284 3408 { … … 3286 3410 Log(("PGMPhysInterpretedRead: pvDst=%p pvSrc=%p cb=%d\n", pvDst, (uint8_t *)pvSrc + (GCPtrSrc & PAGE_OFFSET_MASK), cb)); 3287 3411 memcpy(pvDst, (uint8_t *)pvSrc + (GCPtrSrc & PAGE_OFFSET_MASK), cb); 3412 PGMPhysReleasePageMappingLock(pVM, &PgMpLck); 3288 3413 break; 3289 3414 case VERR_PGM_PHYS_PAGE_RESERVED: 3290 3415 case VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS: 3291 memset(pvDst, 0 , cb); /** @todo this is wrong, it should be 0xff */3416 memset(pvDst, 0xff, cb); 3292 3417 break; 3293 3418 default: 3419 Assert(RT_FAILURE_NP(rc)); 3294 3420 return rc; 3295 3421 } … … 3321 3447 /** @todo we should check reserved bits ... */ 3322 3448 AssertMsgFailed(("cb=%d cb1=%d cb2=%d GCPtrSrc=%RGv\n", cb, cb1, cb2, GCPtrSrc)); 3323 void *pvSrc1; 3324 rc = PGM_GCPHYS_2_PTR_V2(pVM, pVCpu, GCPhys1, &pvSrc1); 3449 PGMPAGEMAPLOCK PgMpLck; 3450 void const *pvSrc1; 3451 rc = PGMPhysGCPhys2CCPtrReadOnly(pVM, GCPhys1, &pvSrc1, &PgMpLck); 3325 3452 switch (rc) 3326 3453 { 3327 3454 case VINF_SUCCESS: 3328 3455 memcpy(pvDst, (uint8_t *)pvSrc1 + (GCPtrSrc & PAGE_OFFSET_MASK), cb1); 3456 PGMPhysReleasePageMappingLock(pVM, &PgMpLck); 3329 3457 break; 3330 3458 case VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS: 3331 memset(pvDst, 0 , cb1); /** @todo this is wrong, it should be 0xff */3459 memset(pvDst, 0xff, cb1); 3332 3460 break; 3333 3461 default: 3462 Assert(RT_FAILURE_NP(rc)); 3334 3463 return rc; 3335 3464 } 3336 3465 3337 void *pvSrc2;3338 rc = PGM _GCPHYS_2_PTR_V2(pVM, pVCpu, GCPhys2, &pvSrc2);3466 void const *pvSrc2; 3467 rc = PGMPhysGCPhys2CCPtrReadOnly(pVM, GCPhys2, &pvSrc2, &PgMpLck); 3339 3468 switch (rc) 3340 3469 { 3341 3470 case VINF_SUCCESS: 3342 3471 memcpy((uint8_t *)pvDst + cb1, pvSrc2, cb2); 3472 PGMPhysReleasePageMappingLock(pVM, &PgMpLck); 3343 3473 break; 3344 3474 case VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS: 3345 memset((uint8_t *)pvDst + cb1, 0 , cb2); /** @todo this is wrong, it should be 0xff */3475 memset((uint8_t *)pvDst + cb1, 0xff, cb2); 3346 3476 break; 3347 3477 default: 3478 Assert(RT_FAILURE_NP(rc)); 3348 3479 return rc; 3349 3480 } -
trunk/src/VBox/VMM/VMMR0/PGMR0.cpp
r37950 r38953 68 68 VMMR0DECL(int) PGMR0PhysAllocateHandyPages(PVM pVM, PVMCPU pVCpu) 69 69 { 70 Assert(PDMCritSectIsOwnerEx(&pVM->pgm.s.CritSect, pVCpu));70 PGM_LOCK_ASSERT_OWNER_EX(pVM, pVCpu); 71 71 72 72 /* … … 183 183 VMMR0DECL(int) PGMR0PhysAllocateLargeHandyPage(PVM pVM, PVMCPU pVCpu) 184 184 { 185 Assert(PDMCritSectIsOwnerEx(&pVM->pgm.s.CritSect, pVCpu)); 186 185 PGM_LOCK_ASSERT_OWNER_EX(pVM, pVCpu); 187 186 Assert(!pVM->pgm.s.cLargeHandyPages); 188 int rc = GMMR0AllocateLargePage(pVM, pVCpu->idCpu, _2M, &pVM->pgm.s.aLargeHandyPage[0].idPage, &pVM->pgm.s.aLargeHandyPage[0].HCPhysGCPhys); 187 188 int rc = GMMR0AllocateLargePage(pVM, pVCpu->idCpu, _2M, 189 &pVM->pgm.s.aLargeHandyPage[0].idPage, 190 &pVM->pgm.s.aLargeHandyPage[0].HCPhysGCPhys); 189 191 if (RT_SUCCESS(rc)) 190 192 pVM->pgm.s.cLargeHandyPages = 1; -
trunk/src/VBox/VMM/VMMR3/PGM.cpp
r38712 r38953 1186 1186 AssertCompile(sizeof(pVM->pgm.s) <= sizeof(pVM->pgm.padding)); 1187 1187 AssertCompile(sizeof(pVM->aCpus[0].pgm.s) <= sizeof(pVM->aCpus[0].pgm.padding)); 1188 AssertCompileMemberAlignment(PGM, CritSect , sizeof(uintptr_t));1188 AssertCompileMemberAlignment(PGM, CritSectX, sizeof(uintptr_t)); 1189 1189 1190 1190 /* … … 1342 1342 * Initialize the PGM critical section and flush the phys TLBs 1343 1343 */ 1344 rc = PDMR3CritSectInit(pVM, &pVM->pgm.s.CritSect , RT_SRC_POS, "PGM");1344 rc = PDMR3CritSectInit(pVM, &pVM->pgm.s.CritSectX, RT_SRC_POS, "PGM"); 1345 1345 AssertRCReturn(rc, rc); 1346 1346 … … 1454 1454 1455 1455 /* Almost no cleanup necessary, MM frees all memory. */ 1456 PDMR3CritSectDelete(&pVM->pgm.s.CritSect );1456 PDMR3CritSectDelete(&pVM->pgm.s.CritSectX); 1457 1457 1458 1458 return rc; … … 2578 2578 2579 2579 PGMDeregisterStringFormatTypes(); 2580 return PDMR3CritSectDelete(&pVM->pgm.s.CritSect );2580 return PDMR3CritSectDelete(&pVM->pgm.s.CritSectX); 2581 2581 } 2582 2582 … … 2689 2689 * Get page directory addresses. 2690 2690 */ 2691 pgmLock(pVM); 2691 2692 PX86PD pPDSrc = pgmGstGet32bitPDPtr(pVCpu); 2692 2693 Assert(pPDSrc); 2693 Assert(PGMPhysGCPhys2R3PtrAssert(pVM, (RTGCPHYS)(CPUMGetGuestCR3(pVCpu) & X86_CR3_PAGE_MASK), sizeof(*pPDSrc)) == pPDSrc);2694 2694 2695 2695 /* … … 2715 2715 } 2716 2716 } 2717 pgmUnlock(pVM); 2717 2718 } 2718 2719 … … 2726 2727 VMMR3DECL(int) PGMR3LockCall(PVM pVM) 2727 2728 { 2728 int rc = PDMR3CritSectEnterEx(&pVM->pgm.s.CritSect , true /* fHostCall */);2729 int rc = PDMR3CritSectEnterEx(&pVM->pgm.s.CritSectX, true /* fHostCall */); 2729 2730 AssertRC(rc); 2730 2731 return rc; -
trunk/src/VBox/VMM/VMMR3/PGMPhys.cpp
r38838 r38953 150 150 * Simple stuff, go ahead. 151 151 */ 152 size_t cb= PAGE_SIZE - (off & PAGE_OFFSET_MASK);152 size_t cb = PAGE_SIZE - (off & PAGE_OFFSET_MASK); 153 153 if (cb > cbRead) 154 154 cb = cbRead; 155 const void *pvSrc; 156 int rc = pgmPhysGCPhys2CCPtrInternalReadOnly(pVM, pPage, pRam->GCPhys + off, &pvSrc); 155 PGMPAGEMAPLOCK PgMpLck; 156 const void *pvSrc; 157 int rc = pgmPhysGCPhys2CCPtrInternalReadOnly(pVM, pPage, pRam->GCPhys + off, &pvSrc, &PgMpLck); 157 158 if (RT_SUCCESS(rc)) 159 { 158 160 memcpy(pvBuf, pvSrc, cb); 161 pgmPhysReleaseInternalPageMappingLock(pVM, &PgMpLck); 162 } 159 163 else 160 164 { … … 290 294 * Simple stuff, go ahead. 291 295 */ 292 size_t cb= PAGE_SIZE - (off & PAGE_OFFSET_MASK);296 size_t cb = PAGE_SIZE - (off & PAGE_OFFSET_MASK); 293 297 if (cb > cbWrite) 294 298 cb = cbWrite; 295 void *pvDst; 296 int rc = pgmPhysGCPhys2CCPtrInternal(pVM, pPage, pRam->GCPhys + off, &pvDst); 299 PGMPAGEMAPLOCK PgMpLck; 300 void *pvDst; 301 int rc = pgmPhysGCPhys2CCPtrInternal(pVM, pPage, pRam->GCPhys + off, &pvDst, &PgMpLck); 297 302 if (RT_SUCCESS(rc)) 303 { 298 304 memcpy(pvDst, pvBuf, cb); 305 pgmPhysReleaseInternalPageMappingLock(pVM, &PgMpLck); 306 } 299 307 else 300 308 AssertLogRelMsgFailed(("pgmPhysGCPhys2CCPtrInternal failed on %RGp / %R[pgmpage] -> %Rrc\n", … … 3996 4004 pVM->pgm.s.cMappedChunks++; 3997 4005 3998 /* If we're running out of virtual address space, then we should unmap another chunk. */ 4006 /* 4007 * If we're running out of virtual address space, then we should 4008 * unmap another chunk. 4009 * 4010 * Currently, an unmap operation requires that all other virtual CPUs 4011 * are idling and not by chance making use of the memory we're 4012 * unmapping. So, we create an async unmap operation here. 4013 * 4014 * Now, when creating or restoring a saved state this wont work very 4015 * well since we may want to restore all guest RAM + a little something. 4016 * So, we have to do the unmap synchronously. Fortunately for us 4017 * though, during these operations the other virtual CPUs are inactive 4018 * and it should be safe to do this. 4019 */ 4020 /** @todo Eventually we should lock all memory when used and do 4021 * map+unmap as one kernel call without any rendezvous or 4022 * other precautions. */ 3999 4023 if (pVM->pgm.s.ChunkR3Map.c >= pVM->pgm.s.ChunkR3Map.cMax) 4000 4024 { 4001 /* Postpone the unmap operation (which requires a rendezvous operation) as we own the PGM lock here. */ 4002 rc = VMR3ReqCallNoWait(pVM, VMCPUID_ANY_QUEUE, (PFNRT)pgmR3PhysUnmapChunk, 1, pVM); 4003 AssertRC(rc); 4025 switch (VMR3GetState(pVM)) 4026 { 4027 case VMSTATE_LOADING: 4028 case VMSTATE_SAVING: 4029 { 4030 PVMCPU pVCpu = VMMGetCpu(pVM); 4031 if ( pVCpu 4032 && pVM->pgm.s.cDeprecatedPageLocks == 0) 4033 { 4034 pgmR3PhysUnmapChunkRendezvous(pVM, pVCpu, NULL); 4035 break; 4036 } 4037 /* fall thru */ 4038 } 4039 default: 4040 rc = VMR3ReqCallNoWait(pVM, VMCPUID_ANY_QUEUE, (PFNRT)pgmR3PhysUnmapChunk, 1, pVM); 4041 AssertRC(rc); 4042 break; 4043 } 4004 4044 } 4005 4045 } -
trunk/src/VBox/VMM/VMMR3/PGMSavedState.cpp
r38707 r38953 1243 1243 static void pgmR3StateCalcCrc32ForRamPage(PVM pVM, PPGMRAMRANGE pCur, PPGMLIVESAVERAMPAGE paLSPages, uint32_t iPage) 1244 1244 { 1245 RTGCPHYS GCPhys = pCur->GCPhys + ((RTGCPHYS)iPage << PAGE_SHIFT); 1246 void const *pvPage; 1247 int rc = pgmPhysGCPhys2CCPtrInternalReadOnly(pVM, &pCur->aPages[iPage], GCPhys, &pvPage); 1245 RTGCPHYS GCPhys = pCur->GCPhys + ((RTGCPHYS)iPage << PAGE_SHIFT); 1246 PGMPAGEMAPLOCK PgMpLck; 1247 void const *pvPage; 1248 int rc = pgmPhysGCPhys2CCPtrInternalReadOnly(pVM, &pCur->aPages[iPage], GCPhys, &pvPage, &PgMpLck); 1248 1249 if (RT_SUCCESS(rc)) 1250 { 1249 1251 paLSPages[iPage].u32Crc = RTCrc32(pvPage, PAGE_SIZE); 1252 pgmPhysReleaseInternalPageMappingLock(pVM, &PgMpLck); 1253 } 1250 1254 else 1251 1255 paLSPages[iPage].u32Crc = UINT32_MAX; /* Invalid */ … … 1290 1294 if (paLSPages[iPage].u32Crc != UINT32_MAX) 1291 1295 { 1292 RTGCPHYS GCPhys = pCur->GCPhys + ((RTGCPHYS)iPage << PAGE_SHIFT); 1293 void const *pvPage; 1294 int rc = pgmPhysGCPhys2CCPtrInternalReadOnly(pVM, &pCur->aPages[iPage], GCPhys, &pvPage); 1296 RTGCPHYS GCPhys = pCur->GCPhys + ((RTGCPHYS)iPage << PAGE_SHIFT); 1297 PGMPAGEMAPLOCK PgMpLck; 1298 void const *pvPage; 1299 int rc = pgmPhysGCPhys2CCPtrInternalReadOnly(pVM, &pCur->aPages[iPage], GCPhys, &pvPage, &PgMpLck); 1295 1300 if (RT_SUCCESS(rc)) 1301 { 1296 1302 pgmR3StateVerifyCrc32ForPage(pvPage, pCur, paLSPages, iPage, pszWhere); 1303 pgmPhysReleaseInternalPageMappingLock(pVM, &PgMpLck); 1304 } 1297 1305 } 1298 1306 } … … 1333 1341 && (iPage & 0x7ff) == 0x100 1334 1342 #endif 1335 && PDMR3CritSectYield(&pVM->pgm.s.CritSect )1343 && PDMR3CritSectYield(&pVM->pgm.s.CritSectX) 1336 1344 && pVM->pgm.s.idRamRangesGen != idRamRangesGen) 1337 1345 { … … 1558 1566 if ( uPass != SSM_PASS_FINAL 1559 1567 && (iPage & 0x7ff) == 0x100 1560 && PDMR3CritSectYield(&pVM->pgm.s.CritSect )1568 && PDMR3CritSectYield(&pVM->pgm.s.CritSectX) 1561 1569 && pVM->pgm.s.idRamRangesGen != idRamRangesGen) 1562 1570 { … … 1622 1630 * SSM call may block). 1623 1631 */ 1624 uint8_t abPage[PAGE_SIZE]; 1625 void const *pvPage; 1626 rc = pgmPhysGCPhys2CCPtrInternalReadOnly(pVM, pCurPage, GCPhys, &pvPage); 1632 uint8_t abPage[PAGE_SIZE]; 1633 PGMPAGEMAPLOCK PgMpLck; 1634 void const *pvPage; 1635 rc = pgmPhysGCPhys2CCPtrInternalReadOnly(pVM, pCurPage, GCPhys, &pvPage, &PgMpLck); 1627 1636 if (RT_SUCCESS(rc)) 1628 1637 { … … 1632 1641 pgmR3StateVerifyCrc32ForPage(abPage, pCur, paLSPages, iPage, "save#3"); 1633 1642 #endif 1643 pgmPhysReleaseInternalPageMappingLock(pVM, &PgMpLck); 1634 1644 } 1635 1645 pgmUnlock(pVM); … … 2231 2241 * Load the page. 2232 2242 */ 2233 void *pvPage; 2234 int rc = pgmPhysGCPhys2CCPtrInternal(pVM, pPage, GCPhys, &pvPage); 2243 PGMPAGEMAPLOCK PgMpLck; 2244 void *pvPage; 2245 int rc = pgmPhysGCPhys2CCPtrInternal(pVM, pPage, GCPhys, &pvPage, &PgMpLck); 2235 2246 if (RT_SUCCESS(rc)) 2247 { 2236 2248 rc = SSMR3GetMem(pSSM, pvPage, PAGE_SIZE); 2249 pgmPhysReleaseInternalPageMappingLock(pVM, &PgMpLck); 2250 } 2237 2251 2238 2252 return rc; … … 2677 2691 || PGM_PAGE_GET_TYPE(pPage) == PGMPAGETYPE_ROM_SHADOW) 2678 2692 { 2679 void *pvDstPage; 2680 rc = pgmPhysGCPhys2CCPtrInternal(pVM, pPage, GCPhys, &pvDstPage); 2693 PGMPAGEMAPLOCK PgMpLck; 2694 void *pvDstPage; 2695 rc = pgmPhysGCPhys2CCPtrInternal(pVM, pPage, GCPhys, &pvDstPage, &PgMpLck); 2681 2696 AssertLogRelMsgRCReturn(rc, ("GCPhys=%RGp %R[pgmpage] rc=%Rrc\n", GCPhys, pPage, rc), rc); 2697 2682 2698 ASMMemZeroPage(pvDstPage); 2699 pgmPhysReleaseInternalPageMappingLock(pVM, &PgMpLck); 2683 2700 } 2684 2701 /* Free it only if it's not part of a previously … … 2719 2736 case PGM_STATE_REC_RAM_RAW: 2720 2737 { 2721 void *pvDstPage; 2722 rc = pgmPhysGCPhys2CCPtrInternal(pVM, pPage, GCPhys, &pvDstPage); 2738 PGMPAGEMAPLOCK PgMpLck; 2739 void *pvDstPage; 2740 rc = pgmPhysGCPhys2CCPtrInternal(pVM, pPage, GCPhys, &pvDstPage, &PgMpLck); 2723 2741 AssertLogRelMsgRCReturn(rc, ("GCPhys=%RGp %R[pgmpage] rc=%Rrc\n", GCPhys, pPage, rc), rc); 2724 2742 rc = SSMR3GetMem(pSSM, pvDstPage, PAGE_SIZE); 2743 pgmPhysReleaseInternalPageMappingLock(pVM, &PgMpLck); 2725 2744 if (RT_FAILURE(rc)) 2726 2745 return rc; -
trunk/src/VBox/VMM/VMMR3/PGMSharedPage.cpp
r36891 r38953 342 342 case PGM_PAGE_STATE_WRITE_MONITORED: 343 343 { 344 const void *pvPage;345 344 /* Check if the page was allocated, but completely zero. */ 346 int rc = pgmPhysGCPhys2CCPtrInternalReadOnly(pVM, pPage, GCPhys, &pvPage); 347 if ( rc == VINF_SUCCESS 345 PGMPAGEMAPLOCK PgMpLck; 346 const void *pvPage; 347 int rc = pgmPhysGCPhys2CCPtrInternalReadOnly(pVM, pPage, GCPhys, &pvPage, &PgMpLck); 348 if ( RT_SUCCESS(rc) 348 349 && ASMMemIsZeroPage(pvPage)) 349 {350 350 cAllocZero++; 351 } 352 else 353 if (GMMR3IsDuplicatePage(pVM, PGM_PAGE_GET_PAGEID(pPage))) 351 else if (GMMR3IsDuplicatePage(pVM, PGM_PAGE_GET_PAGEID(pPage))) 354 352 cDuplicate++; 355 353 else 356 354 cUnique++; 357 355 if (RT_SUCCESS(rc)) 356 pgmPhysReleaseInternalPageMappingLock(pVM, &PgMpLck); 358 357 break; 359 358 } -
trunk/src/VBox/VMM/include/PGMInternal.h
r38708 r38953 257 257 #else 258 258 # define PGM_GCPHYS_2_PTR_V2(pVM, pVCpu, GCPhys, ppv) \ 259 PGMPhysGCPhys2R3Ptr(pVM, GCPhys, 1 /* one page only */, (PRTR3PTR)(ppv)) /** @todo this isn't asserting, use PGMRamGCPhys2HCPtr! */259 pgmPhysGCPhys2R3Ptr(pVM, GCPhys, (PRTR3PTR)(ppv)) /** @todo this isn't asserting! */ 260 260 #endif 261 261 … … 305 305 #else 306 306 # define PGM_GCPHYS_2_PTR_EX(pVM, GCPhys, ppv) \ 307 PGMPhysGCPhys2R3Ptr(pVM, GCPhys, 1 /* one page only */, (PRTR3PTR)(ppv)) /** @todo this isn't asserting, use PGMRamGCPhys2HCPtr! */307 pgmPhysGCPhys2R3Ptr(pVM, GCPhys, (PRTR3PTR)(ppv)) /** @todo this isn't asserting! */ 308 308 #endif 309 309 … … 3146 3146 /** The address of the ring-0 mapping cache if we're making use of it. */ 3147 3147 RTR0PTR pvR0DynMapUsed; 3148 #if HC_ARCH_BITS == 32 3149 /** Alignment padding that makes the next member start on a 8 byte boundary. */ 3148 3149 /** Hack: Number of deprecated page mapping locks taken by the current lock 3150 * owner via pgmPhysGCPhys2CCPtrInternalDepr. */ 3151 uint32_t cDeprecatedPageLocks; 3152 #if HC_ARCH_BITS == 64 3153 /** Alignment padding. */ 3150 3154 uint32_t u32Alignment2; 3151 3155 #endif 3156 3152 3157 3153 3158 /** PGM critical section. … … 3155 3160 * and the page flag updating (some of it anyway). 3156 3161 */ 3157 PDMCRITSECT CritSect ;3162 PDMCRITSECT CritSectX; 3158 3163 3159 3164 /** … … 3341 3346 AssertCompileMemberAlignment(PGM, GCPtrMappingFixed, sizeof(RTGCPTR)); 3342 3347 AssertCompileMemberAlignment(PGM, HCPhysInterPD, 8); 3343 AssertCompileMemberAlignment(PGM, CritSect , 8);3348 AssertCompileMemberAlignment(PGM, CritSectX, 8); 3344 3349 AssertCompileMemberAlignment(PGM, ChunkR3Map, 8); 3345 3350 AssertCompileMemberAlignment(PGM, PhysTlbHC, 8); … … 3854 3859 * @param a_pVM The VM handle. 3855 3860 */ 3856 #define PGM_LOCK_ASSERT_OWNER(a_pVM) Assert(PDMCritSectIsOwner(&(a_pVM)->pgm.s.CritSect)) 3861 #define PGM_LOCK_ASSERT_OWNER(a_pVM) Assert(PDMCritSectIsOwner(&(a_pVM)->pgm.s.CritSectX)) 3862 /** 3863 * Asserts that the caller owns the PDM lock. 3864 * This is the internal variant of PGMIsLockOwner. 3865 * @param a_pVM The VM handle. 3866 * @param a_pVCpu The current CPU handle. 3867 */ 3868 #define PGM_LOCK_ASSERT_OWNER_EX(a_pVM, a_pVCpu) Assert(PDMCritSectIsOwnerEx(&(a_pVM)->pgm.s.CritSectX, pVCpu)) 3857 3869 3858 3870 int pgmR3MappingsFixInternal(PVM pVM, RTGCPTR GCPtrBase, uint32_t cb); … … 3887 3899 int pgmPhysPageMapReadOnly(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys, void const **ppv); 3888 3900 int pgmPhysPageMapByPageID(PVM pVM, uint32_t idPage, RTHCPHYS HCPhys, void **ppv); 3889 int pgmPhysGCPhys2CCPtrInternal(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys, void **ppv); 3890 int pgmPhysGCPhys2CCPtrInternalReadOnly(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys, const void **ppv); 3901 int pgmPhysGCPhys2R3Ptr(PVM pVM, RTGCPHYS GCPhys, PRTR3PTR pR3Ptr); 3902 int pgmPhysGCPhys2CCPtrInternalDepr(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys, void **ppv); 3903 int pgmPhysGCPhys2CCPtrInternal(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys, void **ppv, PPGMPAGEMAPLOCK pLock); 3904 int pgmPhysGCPhys2CCPtrInternalReadOnly(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys, const void **ppv, PPGMPAGEMAPLOCK pLock); 3905 void pgmPhysReleaseInternalPageMappingLock(PVM pVM, PPGMPAGEMAPLOCK pLock); 3891 3906 VMMDECL(int) pgmPhysHandlerRedirectToHC(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPHYS GCPhysFault, void *pvUser); 3892 3907 VMMDECL(int) pgmPhysRomWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPHYS GCPhysFault, void *pvUser); -
trunk/src/VBox/VMM/include/internal/pgm.h
r35346 r38953 65 65 VMMDECL(int) PGMPhysGCPtr2CCPtr(PVMCPU pVCpu, RTGCPTR GCPtr, void **ppv, PPGMPAGEMAPLOCK pLock); 66 66 VMMDECL(int) PGMPhysGCPtr2CCPtrReadOnly(PVMCPU pVCpu, RTGCPTR GCPtr, void const **ppv, PPGMPAGEMAPLOCK pLock); 67 VMMDECL(int) PGMPhysGCPhys2R3Ptr(PVM pVM, RTGCPHYS GCPhys, RTUINT cbRange, PRTR3PTR pR3Ptr);68 #ifdef VBOX_STRICT69 VMMDECL(RTR3PTR) PGMPhysGCPhys2R3PtrAssert(PVM pVM, RTGCPHYS GCPhys, RTUINT cbRange);70 #endif71 67 VMMR3DECL(void) PGMR3ResetNoMorePhysWritesFlag(PVM pVM); 72 68 -
trunk/src/VBox/VMM/testcase/tstVMStructRC.cpp
r38837 r38953 599 599 GEN_CHECK_OFF(PGMCPU, fA20Enabled); 600 600 GEN_CHECK_OFF(PGMCPU, fSyncFlags); 601 GEN_CHECK_OFF(PGM, CritSect );601 GEN_CHECK_OFF(PGM, CritSectX); 602 602 GEN_CHECK_OFF(PGM, pPoolR3); 603 603 GEN_CHECK_OFF(PGM, pPoolR0); -
trunk/src/VBox/VMM/testcase/tstVMStructSize.cpp
r38489 r38953 203 203 CHECK_PADDING_VM(64, vmm); 204 204 PRINT_OFFSET(VM, pgm); 205 PRINT_OFFSET(VM, pgm.s.CritSect );205 PRINT_OFFSET(VM, pgm.s.CritSectX); 206 206 CHECK_PADDING_VM(64, pgm); 207 207 PRINT_OFFSET(VM, hwaccm); … … 383 383 CHECK_MEMBER_ALIGNMENT(IOM, CritSect, sizeof(uintptr_t)); 384 384 CHECK_MEMBER_ALIGNMENT(EM, CritSectREM, sizeof(uintptr_t)); 385 CHECK_MEMBER_ALIGNMENT(PGM, CritSect , sizeof(uintptr_t));385 CHECK_MEMBER_ALIGNMENT(PGM, CritSectX, sizeof(uintptr_t)); 386 386 CHECK_MEMBER_ALIGNMENT(PDM, CritSect, sizeof(uintptr_t)); 387 387 CHECK_MEMBER_ALIGNMENT(MMHYPERHEAP, Lock, sizeof(uintptr_t));
Note:
See TracChangeset
for help on using the changeset viewer.