Changeset 15410 in vbox
- Timestamp:
- Dec 13, 2008 1:04:17 AM (16 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/PGMInternal.h
r15404 r15410 2871 2871 /** Check monitoring on next CR3 (re)load and invalidate page. */ 2872 2872 #define PGM_SYNC_MONITOR_CR3 RT_BIT(2) 2873 /** Check guest mapping in SyncCR3. */ 2874 #define PGM_SYNC_MAP_CR3 RT_BIT(3) 2873 2875 /** Clear the page pool (a light weight flush). */ 2874 2876 #define PGM_SYNC_CLEAR_PGM_POOL RT_BIT(8) -
trunk/src/VBox/VMM/PGMMap.cpp
r14979 r15410 482 482 /* Remap CR3 as we have just flushed the CR3 shadow PML4 in case we're in long mode. */ 483 483 int rc = PGM_GST_PFN(MapCR3, pVM)(pVM, pVM->pgm.s.GCPhysCR3); 484 AssertRC (rc);484 AssertRCSuccess(rc); 485 485 486 486 #ifndef VBOX_WITH_PGMPOOL_PAGING_ONLY 487 487 rc = PGM_GST_PFN(MonitorCR3, pVM)(pVM, pVM->pgm.s.GCPhysCR3); 488 AssertRC (rc);488 AssertRCSuccess(rc); 489 489 #endif 490 490 return VINF_SUCCESS; -
trunk/src/VBox/VMM/VMMAll/PGMAll.cpp
r15344 r15410 1466 1466 * Always flag the necessary updates; necessary for hardware acceleration 1467 1467 */ 1468 /** @todo optimize this, it shouldn't always be necessary. */ 1468 1469 VM_FF_SET(pVM, VM_FF_PGM_SYNC_CR3_NON_GLOBAL); 1469 1470 if (fGlobal) … … 1485 1486 if (pVM->pgm.s.GCPhysCR3 != GCPhysCR3) 1486 1487 { 1487 pVM->pgm.s.GCPhysCR3 = GCPhysCR3; 1488 RTGCPHYS GCPhysOldCR3 = pVM->pgm.s.GCPhysCR3; 1489 pVM->pgm.s.GCPhysCR3 = GCPhysCR3; 1488 1490 rc = PGM_GST_PFN(MapCR3, pVM)(pVM, GCPhysCR3); 1489 if (RT_ SUCCESS(rc) && !pVM->pgm.s.fMappingsFixed)1491 if (RT_LIKELY(rc == VINF_SUCCESS)) 1490 1492 { 1491 pVM->pgm.s.fSyncFlags &= ~PGM_SYNC_MONITOR_CR3; 1492 rc = PGM_GST_PFN(MonitorCR3, pVM)(pVM, GCPhysCR3); 1493 if (!pVM->pgm.s.fMappingsFixed) 1494 { 1495 pVM->pgm.s.fSyncFlags &= ~PGM_SYNC_MONITOR_CR3; 1496 rc = PGM_GST_PFN(MonitorCR3, pVM)(pVM, GCPhysCR3); 1497 } 1493 1498 } 1499 else 1500 { 1501 AssertMsg(rc == VINF_PGM_SYNC_CR3, ("%Rrc\n", rc)); 1502 Assert(VM_FF_ISPENDING(pVM, VM_FF_PGM_SYNC_CR3_NON_GLOBAL | VM_FF_PGM_SYNC_CR3)); 1503 pVM->pgm.s.GCPhysCR3 = GCPhysOldCR3; 1504 pVM->pgm.s.fSyncFlags |= PGM_SYNC_MAP_CR3; 1505 if (!pVM->pgm.s.fMappingsFixed) 1506 pVM->pgm.s.fSyncFlags |= PGM_SYNC_MONITOR_CR3; 1507 } 1508 1494 1509 if (fGlobal) 1495 1510 STAM_COUNTER_INC(&pVM->pgm.s.CTX_MID_Z(Stat,FlushTLBNewCR3Global)); … … 1529 1544 * 1530 1545 * @returns VBox status code. 1531 * @retval VINF_PGM_SYNC_CR3 if monitoring requires a CR3 sync. This can 1532 * safely be ignored and overridden since the FF will be set too then. 1546 * @retval VINF_SUCCESS. 1547 * @retval (If applied when not in nested mode: VINF_PGM_SYNC_CR3 if monitoring 1548 * requires a CR3 sync. This can safely be ignored and overridden since 1549 * the FF will be set too then.) 1533 1550 * @param pVM VM handle. 1534 1551 * @param cr3 The new cr3. … … 1559 1576 pVM->pgm.s.GCPhysCR3 = GCPhysCR3; 1560 1577 rc = PGM_GST_PFN(MapCR3, pVM)(pVM, GCPhysCR3); 1561 }1562 AssertRC(rc);1578 AssertRCSuccess(rc); /* Assumes VINF_PGM_SYNC_CR3 doesn't apply to nested paging. */ 1579 } 1563 1580 return rc; 1564 1581 } … … 1581 1598 VMMDECL(int) PGMSyncCR3(PVM pVM, uint64_t cr0, uint64_t cr3, uint64_t cr4, bool fGlobal) 1582 1599 { 1600 int rc; 1601 1583 1602 /* 1584 1603 * We might be called when we shouldn't. … … 1597 1616 } 1598 1617 1599 /* If global pages are not supported, then all flushes are global */1618 /* If global pages are not supported, then all flushes are global. */ 1600 1619 if (!(cr4 & X86_CR4_PGE)) 1601 1620 fGlobal = true; … … 1603 1622 VM_FF_ISSET(pVM, VM_FF_PGM_SYNC_CR3), VM_FF_ISSET(pVM, VM_FF_PGM_SYNC_CR3_NON_GLOBAL))); 1604 1623 1624 #ifdef PGMPOOL_WITH_MONITORING 1625 /* 1626 * The pool may have pending stuff and even require a return to ring-3 to 1627 * clear the whole thing. 1628 */ 1629 rc = pgmPoolSyncCR3(pVM); 1630 if (rc != VINF_SUCCESS) 1631 return rc; 1632 #endif 1633 1634 /* 1635 * Check if we need to finish an aborted MapCR3 call (see PGMFlushTLB). 1636 * This should be done before SyncCR3. 1637 */ 1638 if (pVM->pgm.s.fSyncFlags & PGM_SYNC_MAP_CR3) 1639 { 1640 pVM->pgm.s.fSyncFlags &= ~PGM_SYNC_MAP_CR3; 1641 1642 RTGCPHYS GCPhysCR3Old = pVM->pgm.s.GCPhysCR3; 1643 RTGCPHYS GCPhysCR3; 1644 if ( pVM->pgm.s.enmGuestMode == PGMMODE_PAE 1645 || pVM->pgm.s.enmGuestMode == PGMMODE_PAE_NX 1646 || pVM->pgm.s.enmGuestMode == PGMMODE_AMD64 1647 || pVM->pgm.s.enmGuestMode == PGMMODE_AMD64_NX) 1648 GCPhysCR3 = (RTGCPHYS)(cr3 & X86_CR3_PAE_PAGE_MASK); 1649 else 1650 GCPhysCR3 = (RTGCPHYS)(cr3 & X86_CR3_PAGE_MASK); 1651 pVM->pgm.s.GCPhysCR3 = GCPhysCR3; 1652 rc = PGM_GST_PFN(MapCR3, pVM)(pVM, GCPhysCR3); 1653 #ifdef IN_RING3 1654 if (rc == VINF_PGM_SYNC_CR3) 1655 rc = pgmPoolSyncCR3(pVM); 1656 #else 1657 if (rc == VINF_PGM_SYNC_CR3) 1658 { 1659 pVM->pgm.s.GCPhysCR3 = GCPhysCR3Old; 1660 return rc; 1661 } 1662 #endif 1663 AssertRCReturn(rc, rc); 1664 AssertRCSuccessReturn(rc, VERR_INTERNAL_ERROR); 1665 } 1666 1605 1667 /* 1606 1668 * Let the 'Bth' function do the work and we'll just keep track of the flags. 1607 1669 */ 1608 1670 STAM_PROFILE_START(&pVM->pgm.s.CTX_MID_Z(Stat,SyncCR3), a); 1609 intrc = PGM_BTH_PFN(SyncCR3, pVM)(pVM, cr0, cr3, cr4, fGlobal);1671 rc = PGM_BTH_PFN(SyncCR3, pVM)(pVM, cr0, cr3, cr4, fGlobal); 1610 1672 STAM_PROFILE_STOP(&pVM->pgm.s.CTX_MID_Z(Stat,SyncCR3), a); 1611 1673 AssertMsg(rc == VINF_SUCCESS || rc == VINF_PGM_SYNC_CR3 || RT_FAILURE(rc), ("rc=%Rrc\n", rc)); -
trunk/src/VBox/VMM/VMMAll/PGMAllBth.h
r15228 r15410 3120 3120 #endif 3121 3121 3122 #ifdef PGMPOOL_WITH_MONITORING3123 int rc = pgmPoolSyncCR3(pVM);3124 if (rc != VINF_SUCCESS)3125 return rc;3126 #endif3127 3128 3122 #if PGM_SHW_TYPE == PGM_TYPE_NESTED || PGM_SHW_TYPE == PGM_TYPE_EPT 3129 3123 /* 3130 3124 * Nested / EPT - almost no work. 3131 3125 */ 3132 /** @todo check if this is really necessary */3126 /** @todo check if this is really necessary; the call does it as well... */ 3133 3127 HWACCMFlushTLB(pVM); 3134 3128 return VINF_SUCCESS; -
trunk/src/VBox/VMM/VMMAll/PGMAllGst.h
r15404 r15410 423 423 * CR3 is updated we simply call MapCR3 again. 424 424 * 425 * @returns VBox status, no specials. 425 * @returns Strict VBox status code. 426 * @retval VINF_SUCCESS. 427 * @retval VINF_PGM_SYNC_CR3 if the shadow page pool overflowed. 428 * 426 429 * @param pVM VM handle. 427 430 * @param GCPhysCR3 The physical address in the CR3 register. … … 509 512 if (!HWACCMIsNestedPagingActive(pVM)) 510 513 { 514 /* 515 * Update the shadow root page as well since that's not fixed. 516 */ 517 /** @todo Move this into PGMAllBth.h. */ 511 518 PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool); 512 519 if (pVM->pgm.s.CTX_SUFF(pShwAmd64CR3)) 513 520 { 514 521 /* It might have been freed already by a pool flush (see e.g. PGMR3MappingsUnfix). */ 522 /** @todo Coordinate this better with the pool. */ 515 523 if (pVM->pgm.s.CTX_SUFF(pShwAmd64CR3)->enmKind != PGMPOOLKIND_FREE) 516 524 pgmPoolFreeByPage(pPool, pVM->pgm.s.CTX_SUFF(pShwAmd64CR3), PGMPOOL_IDX_AMD64_CR3, pVM->pgm.s.CTX_SUFF(pShwAmd64CR3)->GCPhys >> PAGE_SHIFT); 517 pVM->pgm.s.CTX_SUFF(pShwAmd64CR3) = 0; 518 pVM->pgm.s.pShwPaePml4R3 = 0; 525 pVM->pgm.s.pShwAmd64CR3R3 = 0; 526 pVM->pgm.s.pShwAmd64CR3R0 = 0; 527 pVM->pgm.s.pShwPaePml4R3 = 0; 519 528 # ifndef VBOX_WITH_2X_4GB_ADDR_SPACE 520 pVM->pgm.s.pShwPaePml4R0 529 pVM->pgm.s.pShwPaePml4R0 = 0; 521 530 # endif 522 pVM->pgm.s.HCPhysShwPaePml4 531 pVM->pgm.s.HCPhysShwPaePml4 = 0; 523 532 } 524 533 525 534 Assert(!(GCPhysCR3 >> (PAGE_SHIFT + 32))); 526 l_try_again:527 535 rc = pgmPoolAlloc(pVM, GCPhysCR3, PGMPOOLKIND_64BIT_PML4_FOR_64BIT_PML4, PGMPOOL_IDX_AMD64_CR3, GCPhysCR3 >> PAGE_SHIFT, &pVM->pgm.s.CTX_SUFF(pShwAmd64CR3)); 528 536 if (rc == VERR_PGM_POOL_FLUSHED) 529 537 { 530 Log(("MapCR3: Flush pool and try again\n")); 531 Assert(pVM->pgm.s.fSyncFlags & PGM_SYNC_CLEAR_PGM_POOL); 532 rc = pgmPoolSyncCR3(pVM); 533 AssertRC(rc); 534 goto l_try_again; 538 Log(("MapCR3: PGM pool flushed -> signal sync cr3\n")); 539 Assert(VM_FF_ISSET(pVM, VM_FF_PGM_SYNC_CR3)); 540 return VINF_PGM_SYNC_CR3; 535 541 } 542 AssertRCReturn(rc, rc); 536 543 # ifdef IN_RING0 537 544 pVM->pgm.s.pShwAmd64CR3R3 = MMHyperCCToR3(pVM, pVM->pgm.s.CTX_SUFF(pShwAmd64CR3)); … … 545 552 # endif 546 553 pVM->pgm.s.HCPhysShwPaePml4 = pVM->pgm.s.CTX_SUFF(pShwAmd64CR3)->Core.Key; 554 rc = VINF_SUCCESS; /* clear it - pgmPoolAlloc returns hints. */ 547 555 } 548 556 # endif -
trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp
r15406 r15410 146 146 HCPhys = pPGM->HCPhysShwPaePdpt; 147 147 break; 148 case PGMPOOL_IDX_NESTED_ROOT: 149 HCPhys = pPGM->HCPhysShwNestedRoot; 150 break; 148 151 case PGMPOOL_IDX_PAE_PD: 149 152 AssertReleaseMsgFailed(("PGMPOOL_IDX_PAE_PD is not usable in VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0 context\n")); … … 153 156 return NULL; 154 157 } 158 AssertMsg(HCPhys && HCPhys != NIL_RTHCPHYS && !(PAGE_OFFSET_MASK & HCPhys), ("%RHp\n", HCPhys)); 159 155 160 void *pv; 156 161 int rc = pgmR0DynMapHCPageInlined(pPGM, HCPhys, &pv); … … 2071 2076 else 2072 2077 { 2073 # if ndef IN_RC //def IN_RING3 - fixing properly in a bit...2078 # ifdef IN_RING3 /* Don't flush in ring-0 or raw mode, it's taking too long. */ 2074 2079 pVM->pgm.s.fSyncFlags &= ~PGM_SYNC_CLEAR_PGM_POOL; 2075 2080 pgmPoolClearAll(pVM); … … 3810 3815 } 3811 3816 3817 /* 3818 * Finally, assert the FF. 3819 */ 3820 VM_FF_SET(pPool->CTX_SUFF(pVM), VM_FF_PGM_SYNC_CR3); 3821 3812 3822 STAM_PROFILE_STOP(&pPool->StatFlushAllInt, a); 3813 3823 } … … 3967 3977 /* 3968 3978 * Flush the pool. 3979 * 3969 3980 * If we have tracking enabled, it should be possible to come up with 3970 3981 * a cheap replacement strategy... … … 4003 4014 LogFlow(("pgmPoolAlloc: GCPhys=%RGp enmKind=%d iUser=%#x iUserTable=%#x\n", GCPhys, enmKind, iUser, iUserTable)); 4004 4015 *ppPage = NULL; 4016 Assert(!(pVM->pgm.s.fSyncFlags & PGM_SYNC_CLEAR_PGM_POOL)); 4005 4017 4006 4018 #ifdef PGMPOOL_WITH_CACHE -
trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp
r15404 r15410 678 678 { 679 679 pVMCB->guest.u64CR3 = PGMGetHyperCR3(pVM); 680 Assert(pVMCB->guest.u64CR3 );680 Assert(pVMCB->guest.u64CR3 || VM_FF_ISPENDING(pVM, VM_FF_PGM_SYNC_CR3 | VM_FF_PGM_SYNC_CR3_NON_GLOBAL)); 681 681 } 682 682 } -
trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp
r15404 r15410 1426 1426 if (pVM->hwaccm.s.fNestedPaging) 1427 1427 { 1428 AssertMsg(PGMGetEPTCR3(pVM) == PGMGetHyperCR3(pVM), ("%RHp vs %RHp\n", PGMGetEPTCR3(pVM), PGMGetHyperCR3(pVM))); 1428 AssertMsg( PGMGetEPTCR3(pVM) == PGMGetHyperCR3(pVM) 1429 || VM_FF_ISPENDING(pVM, VM_FF_PGM_SYNC_CR3 | VM_FF_PGM_SYNC_CR3_NON_GLOBAL), 1430 ("%RHp vs %RHp\n", PGMGetEPTCR3(pVM), PGMGetHyperCR3(pVM))); 1429 1431 pVCpu->hwaccm.s.vmx.GCPhysEPTP = PGMGetEPTCR3(pVM); 1430 1432 … … 1461 1463 { 1462 1464 val = PGMGetHyperCR3(pVM); 1463 Assert(val );1465 Assert(val || VM_FF_ISPENDING(pVM, VM_FF_PGM_SYNC_CR3 | VM_FF_PGM_SYNC_CR3_NON_GLOBAL)); 1464 1466 } 1465 1467
Note:
See TracChangeset
for help on using the changeset viewer.