Changeset 80163 in vbox for trunk/src/VBox/VMM/VMMAll/PGMAllGst.h
- Timestamp:
- Aug 6, 2019 8:28:12 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/PGMAllGst.h
r76553 r80163 29 29 PGM_GST_DECL(int, ModifyPage)(PVMCPU pVCpu, RTGCPTR GCPtr, size_t cb, uint64_t fFlags, uint64_t fMask); 30 30 PGM_GST_DECL(int, GetPDE)(PVMCPU pVCpu, RTGCPTR GCPtr, PX86PDEPAE pPDE); 31 PGM_GST_DECL(bool, HandlerVirtualUpdate)(PVM pVM, uint32_t cr4);32 31 33 32 #ifdef IN_RING3 /* r3 only for now. */ … … 507 506 508 507 509 #if ( PGM_GST_TYPE == PGM_TYPE_32BIT \510 || PGM_GST_TYPE == PGM_TYPE_PAE \511 || PGM_GST_TYPE == PGM_TYPE_AMD64) \512 && defined(VBOX_WITH_RAW_MODE)513 /**514 * Updates one virtual handler range.515 *516 * @returns 0517 * @param pNode Pointer to a PGMVIRTHANDLER.518 * @param pvUser Pointer to a PGMVHUARGS structure (see PGM.cpp).519 */520 static DECLCALLBACK(int) PGM_GST_NAME(VirtHandlerUpdateOne)(PAVLROGCPTRNODECORE pNode, void *pvUser)521 {522 PPGMHVUSTATE pState = (PPGMHVUSTATE)pvUser;523 PVM pVM = pState->pVM;524 PVMCPU pVCpu = pState->pVCpu;525 PPGMVIRTHANDLER pCur = (PPGMVIRTHANDLER)pNode;526 PPGMVIRTHANDLERTYPEINT pCurType = PGMVIRTANDLER_GET_TYPE(pVM, pCur);527 528 Assert(pCurType->enmKind != PGMVIRTHANDLERKIND_HYPERVISOR); NOREF(pCurType);529 530 # if PGM_GST_TYPE == PGM_TYPE_32BIT531 PX86PD pPDSrc = pgmGstGet32bitPDPtr(pVCpu);532 # endif533 534 RTGCPTR GCPtr = pCur->Core.Key;535 # if PGM_GST_TYPE != PGM_TYPE_AMD64536 /* skip all stuff above 4GB if not AMD64 mode. */537 if (RT_UNLIKELY(GCPtr >= _4G))538 return 0;539 # endif540 541 unsigned offPage = GCPtr & PAGE_OFFSET_MASK;542 unsigned iPage = 0;543 while (iPage < pCur->cPages)544 {545 # if PGM_GST_TYPE == PGM_TYPE_32BIT546 X86PDE Pde = pPDSrc->a[GCPtr >> X86_PD_SHIFT];547 # elif PGM_GST_TYPE == PGM_TYPE_PAE548 X86PDEPAE Pde = pgmGstGetPaePDE(pVCpu, GCPtr);549 # elif PGM_GST_TYPE == PGM_TYPE_AMD64550 X86PDEPAE Pde = pgmGstGetLongModePDE(pVCpu, GCPtr);551 # endif552 # if PGM_GST_TYPE == PGM_TYPE_32BIT553 bool const fBigPage = Pde.b.u1Size && (pState->cr4 & X86_CR4_PSE);554 # else555 bool const fBigPage = Pde.b.u1Size;556 # endif557 if ( Pde.n.u1Present558 && ( !fBigPage559 ? GST_IS_PDE_VALID(pVCpu, Pde)560 : GST_IS_BIG_PDE_VALID(pVCpu, Pde)) )561 {562 if (!fBigPage)563 {564 /*565 * Normal page table.566 */567 PGSTPT pPT;568 int rc = PGM_GCPHYS_2_PTR_V2(pVM, pVCpu, GST_GET_PDE_GCPHYS(Pde), &pPT);569 if (RT_SUCCESS(rc))570 {571 for (unsigned iPTE = (GCPtr >> GST_PT_SHIFT) & GST_PT_MASK;572 iPTE < RT_ELEMENTS(pPT->a) && iPage < pCur->cPages;573 iPTE++, iPage++, GCPtr += PAGE_SIZE, offPage = 0)574 {575 GSTPTE Pte = pPT->a[iPTE];576 RTGCPHYS GCPhysNew;577 if (Pte.n.u1Present)578 GCPhysNew = PGM_A20_APPLY(pVCpu, (RTGCPHYS)(pPT->a[iPTE].u & GST_PTE_PG_MASK) + offPage);579 else580 GCPhysNew = NIL_RTGCPHYS;581 if (pCur->aPhysToVirt[iPage].Core.Key != GCPhysNew)582 {583 if (pCur->aPhysToVirt[iPage].Core.Key != NIL_RTGCPHYS)584 pgmHandlerVirtualClearPage(pVM, pCur, iPage);585 #ifdef VBOX_STRICT_PGM_HANDLER_VIRTUAL586 AssertReleaseMsg(!pCur->aPhysToVirt[iPage].offNextAlias,587 ("{.Core.Key=%RGp, .Core.KeyLast=%RGp, .offVirtHandler=%#RX32, .offNextAlias=%#RX32} GCPhysNew=%RGp\n",588 pCur->aPhysToVirt[iPage].Core.Key, pCur->aPhysToVirt[iPage].Core.KeyLast,589 pCur->aPhysToVirt[iPage].offVirtHandler, pCur->aPhysToVirt[iPage].offNextAlias, GCPhysNew));590 #endif591 pCur->aPhysToVirt[iPage].Core.Key = GCPhysNew;592 pState->fTodo |= PGM_SYNC_UPDATE_PAGE_BIT_VIRTUAL;593 }594 }595 }596 else597 {598 /* not-present. */599 offPage = 0;600 AssertRC(rc);601 for (unsigned iPTE = (GCPtr >> GST_PT_SHIFT) & GST_PT_MASK;602 iPTE < RT_ELEMENTS(pPT->a) && iPage < pCur->cPages;603 iPTE++, iPage++, GCPtr += PAGE_SIZE)604 {605 if (pCur->aPhysToVirt[iPage].Core.Key != NIL_RTGCPHYS)606 {607 pgmHandlerVirtualClearPage(pVM, pCur, iPage);608 #ifdef VBOX_STRICT_PGM_HANDLER_VIRTUAL609 AssertReleaseMsg(!pCur->aPhysToVirt[iPage].offNextAlias,610 ("{.Core.Key=%RGp, .Core.KeyLast=%RGp, .offVirtHandler=%#RX32, .offNextAlias=%#RX32}\n",611 pCur->aPhysToVirt[iPage].Core.Key, pCur->aPhysToVirt[iPage].Core.KeyLast,612 pCur->aPhysToVirt[iPage].offVirtHandler, pCur->aPhysToVirt[iPage].offNextAlias));613 #endif614 pCur->aPhysToVirt[iPage].Core.Key = NIL_RTGCPHYS;615 pState->fTodo |= PGM_SYNC_UPDATE_PAGE_BIT_VIRTUAL;616 }617 }618 }619 }620 else621 {622 /*623 * 2/4MB page.624 */625 RTGCPHYS GCPhys = (RTGCPHYS)GST_GET_PDE_GCPHYS(Pde);626 for (unsigned i4KB = (GCPtr >> GST_PT_SHIFT) & GST_PT_MASK;627 i4KB < PAGE_SIZE / sizeof(GSTPDE) && iPage < pCur->cPages;628 i4KB++, iPage++, GCPtr += PAGE_SIZE, offPage = 0)629 {630 RTGCPHYS GCPhysNew = PGM_A20_APPLY(pVCpu, GCPhys + (i4KB << PAGE_SHIFT) + offPage);631 if (pCur->aPhysToVirt[iPage].Core.Key != GCPhysNew)632 {633 if (pCur->aPhysToVirt[iPage].Core.Key != NIL_RTGCPHYS)634 pgmHandlerVirtualClearPage(pVM, pCur, iPage);635 #ifdef VBOX_STRICT_PGM_HANDLER_VIRTUAL636 AssertReleaseMsg(!pCur->aPhysToVirt[iPage].offNextAlias,637 ("{.Core.Key=%RGp, .Core.KeyLast=%RGp, .offVirtHandler=%#RX32, .offNextAlias=%#RX32} GCPhysNew=%RGp\n",638 pCur->aPhysToVirt[iPage].Core.Key, pCur->aPhysToVirt[iPage].Core.KeyLast,639 pCur->aPhysToVirt[iPage].offVirtHandler, pCur->aPhysToVirt[iPage].offNextAlias, GCPhysNew));640 #endif641 pCur->aPhysToVirt[iPage].Core.Key = GCPhysNew;642 pState->fTodo |= PGM_SYNC_UPDATE_PAGE_BIT_VIRTUAL;643 }644 }645 } /* pde type */646 }647 else648 {649 /* not-present / invalid. */650 Log(("VirtHandler: Not present / invalid Pde=%RX64\n", (uint64_t)Pde.u));651 for (unsigned cPages = (GST_PT_MASK + 1) - ((GCPtr >> GST_PT_SHIFT) & GST_PT_MASK);652 cPages && iPage < pCur->cPages;653 iPage++, GCPtr += PAGE_SIZE)654 {655 if (pCur->aPhysToVirt[iPage].Core.Key != NIL_RTGCPHYS)656 {657 pgmHandlerVirtualClearPage(pVM, pCur, iPage);658 pCur->aPhysToVirt[iPage].Core.Key = NIL_RTGCPHYS;659 pState->fTodo |= PGM_SYNC_UPDATE_PAGE_BIT_VIRTUAL;660 }661 }662 offPage = 0;663 }664 } /* for pages in virtual mapping. */665 666 return 0;667 }668 #endif /* 32BIT, PAE and AMD64 + VBOX_WITH_RAW_MODE */669 670 671 /**672 * Updates the virtual page access handlers.673 *674 * @returns true if bits were flushed.675 * @returns false if bits weren't flushed.676 * @param pVM The cross context VM structure.677 * @param cr4 The cr4 register value.678 */679 PGM_GST_DECL(bool, HandlerVirtualUpdate)(PVM pVM, uint32_t cr4)680 {681 #if ( PGM_GST_TYPE == PGM_TYPE_32BIT \682 || PGM_GST_TYPE == PGM_TYPE_PAE \683 || PGM_GST_TYPE == PGM_TYPE_AMD64) \684 && defined(VBOX_WITH_RAW_MODE)685 686 /** @todo687 * In theory this is not sufficient: the guest can change a single page in a range with invlpg688 */689 690 /*691 * Resolve any virtual address based access handlers to GC physical addresses.692 * This should be fairly quick.693 */694 RTUINT fTodo = 0;695 696 pgmLock(pVM);697 STAM_PROFILE_START(&pVM->pgm.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,SyncCR3HandlerVirtualUpdate), a);698 699 for (VMCPUID i = 0; i < pVM->cCpus; i++)700 {701 PGMHVUSTATE State;702 PVMCPU pVCpu = &pVM->aCpus[i];703 704 State.pVM = pVM;705 State.pVCpu = pVCpu;706 State.fTodo = pVCpu->pgm.s.fSyncFlags;707 State.cr4 = cr4;708 RTAvlroGCPtrDoWithAll(&pVM->pgm.s.CTX_SUFF(pTrees)->VirtHandlers, true, PGM_GST_NAME(VirtHandlerUpdateOne), &State);709 710 fTodo |= State.fTodo;711 }712 STAM_PROFILE_STOP(&pVM->pgm.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,SyncCR3HandlerVirtualUpdate), a);713 714 715 /*716 * Set / reset bits?717 */718 if (fTodo & PGM_SYNC_UPDATE_PAGE_BIT_VIRTUAL)719 {720 STAM_PROFILE_START(&pVM->pgm.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,SyncCR3HandlerVirtualReset), b);721 Log(("HandlerVirtualUpdate: resets bits\n"));722 RTAvlroGCPtrDoWithAll(&pVM->pgm.s.CTX_SUFF(pTrees)->VirtHandlers, true, pgmHandlerVirtualResetOne, pVM);723 724 for (VMCPUID i = 0; i < pVM->cCpus; i++)725 {726 PVMCPU pVCpu = &pVM->aCpus[i];727 pVCpu->pgm.s.fSyncFlags &= ~PGM_SYNC_UPDATE_PAGE_BIT_VIRTUAL;728 }729 730 STAM_PROFILE_STOP(&pVM->pgm.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,SyncCR3HandlerVirtualReset), b);731 }732 pgmUnlock(pVM);733 734 return !!(fTodo & PGM_SYNC_UPDATE_PAGE_BIT_VIRTUAL);735 736 #else /* real / protected */737 NOREF(pVM); NOREF(cr4);738 return false;739 #endif740 }741 742 743 508 #ifdef IN_RING3 744 509 /**
Note:
See TracChangeset
for help on using the changeset viewer.