Changeset 73260 in vbox for trunk/src/VBox/VMM/VMMR3/PGM.cpp
- Timestamp:
- Jul 20, 2018 10:50:55 AM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/PGM.cpp
r73252 r73260 681 681 static FNVMATSTATE pgmR3ResetNoMorePhysWritesFlag; 682 682 #endif 683 static void pgmR3ModeDataSwitch(PVMCPU pVCpu, PGMMODE enmShw, PGMMODE enmGst);684 683 static PGMMODE pgmR3CalcShadowMode(PVM pVM, PGMMODE enmGuestMode, SUPPAGINGMODE enmHostMode, PGMMODE enmShadowMode, VMMSWITCHER *penmSwitcher); 685 684 … … 2590 2589 PVMCPU pVCpu = &pVM->aCpus[i]; 2591 2590 2592 pgmR3ModeDataSwitch(pVCpu, pVCpu->pgm.s.enmShadowMode, pVCpu->pgm.s.enmGuestMode);2593 2594 2591 uintptr_t idxShw = pVCpu->pgm.s.idxShadowModeData; 2595 2592 if ( idxShw < RT_ELEMENTS(g_aPgmShadowModeData) 2596 2593 && g_aPgmShadowModeData[idxShw].pfnRelocate) 2597 2594 g_aPgmShadowModeData[idxShw].pfnRelocate(pVCpu, offDelta); 2595 else 2596 AssertFailed(); 2598 2597 2599 2598 uintptr_t const idxGst = pVCpu->pgm.s.idxGuestModeData; … … 2601 2600 && g_aPgmGuestModeData[idxGst].pfnRelocate) 2602 2601 g_aPgmGuestModeData[idxGst].pfnRelocate(pVCpu, offDelta); 2602 else 2603 AssertFailed(); 2603 2604 2604 2605 uintptr_t idxBth = pVCpu->pgm.s.idxBothModeData; … … 2606 2607 && g_aPgmBothModeData[idxBth].pfnRelocate) 2607 2608 g_aPgmBothModeData[idxBth].pfnRelocate(pVCpu, offDelta); 2609 else 2610 AssertFailed(); 2608 2611 } 2609 2612 … … 3255 3258 3256 3259 /** 3257 * Switch to different (or relocated in the relocate case) mode data.3258 *3259 * @param pVCpu The cross context virtual CPU structure.3260 * @param enmShw The shadow paging mode.3261 * @param enmGst The guest paging mode.3262 */3263 static void pgmR3ModeDataSwitch(PVMCPU pVCpu, PGMMODE enmShw, PGMMODE enmGst)3264 {3265 /*3266 * Update the indexes.3267 */3268 uintptr_t idxGst = pVCpu->pgm.s.idxGuestModeData = pgmModeToType(enmGst);3269 Assert(g_aPgmGuestModeData[idxGst].uType == idxGst);3270 AssertPtr(g_aPgmGuestModeData[idxGst].pfnGetPage);3271 AssertPtr(g_aPgmGuestModeData[idxGst].pfnModifyPage);3272 AssertPtr(g_aPgmGuestModeData[idxGst].pfnGetPDE);3273 AssertPtr(g_aPgmGuestModeData[idxGst].pfnExit);3274 AssertPtr(g_aPgmGuestModeData[idxGst].pfnEnter);3275 AssertPtr(g_aPgmGuestModeData[idxGst].pfnRelocate);3276 NOREF(idxGst);3277 3278 uintptr_t idxShw = pVCpu->pgm.s.idxShadowModeData = pgmModeToType(enmShw);3279 Assert(g_aPgmShadowModeData[idxShw].uType == idxShw);3280 AssertPtr(g_aPgmShadowModeData[idxShw].pfnGetPage);3281 AssertPtr(g_aPgmShadowModeData[idxShw].pfnModifyPage);3282 AssertPtr(g_aPgmShadowModeData[idxShw].pfnExit);3283 AssertPtr(g_aPgmShadowModeData[idxShw].pfnEnter);3284 AssertPtr(g_aPgmShadowModeData[idxShw].pfnRelocate);3285 NOREF(idxShw);3286 3287 uintptr_t idxBth = pVCpu->pgm.s.idxBothModeData = (idxShw - PGM_TYPE_FIRST_SHADOW) * PGM_TYPE_END + idxGst;3288 Assert(g_aPgmBothModeData[idxBth].uShwType == idxShw);3289 Assert(g_aPgmBothModeData[idxBth].uGstType == idxGst);3290 AssertPtr(g_aPgmBothModeData[idxBth].pfnInvalidatePage);3291 AssertPtr(g_aPgmBothModeData[idxBth].pfnSyncCR3);3292 AssertPtr(g_aPgmBothModeData[idxBth].pfnPrefetchPage);3293 AssertPtr(g_aPgmBothModeData[idxBth].pfnVerifyAccessSyncPage);3294 AssertPtr(g_aPgmBothModeData[idxBth].pfnMapCR3);3295 AssertPtr(g_aPgmBothModeData[idxBth].pfnUnmapCR3);3296 AssertPtr(g_aPgmBothModeData[idxBth].pfnEnter);3297 AssertPtr(g_aPgmBothModeData[idxBth].pfnRelocate);3298 #ifdef VBOX_STRICT3299 AssertPtr(g_aPgmBothModeData[idxBth].pfnAssertCR3);3300 #endif3301 NOREF(idxBth);3302 }3303 3304 3305 /**3306 3260 * Calculates the shadow paging mode. 3307 3261 * … … 3480 3434 3481 3435 default: 3482 Assert ReleaseMsgFailed(("enmGuestMode=%d\n", enmGuestMode));3436 AssertLogRelMsgFailed(("enmGuestMode=%d\n", enmGuestMode)); 3483 3437 *penmSwitcher = VMMSWITCHER_INVALID; 3484 3438 return PGMMODE_INVALID; … … 3575 3529 */ 3576 3530 int rc = VMMR3SelectSwitcher(pVM, enmSwitcher); 3577 if (RT_FAILURE(rc)) 3578 { 3579 AssertReleaseMsgFailed(("VMMR3SelectSwitcher(%d) -> %Rrc\n", enmSwitcher, rc)); 3580 return rc; 3581 } 3531 AssertLogRelMsgRCReturn(rc,("VMMR3SelectSwitcher(%d) -> %Rrc\n", enmSwitcher, rc), rc); 3582 3532 } 3583 3533 #endif … … 3612 3562 3613 3563 /* 3614 * Load new paging mode data. 3615 */ 3616 pgmR3ModeDataSwitch(pVCpu, enmShadowMode, enmGuestMode); 3564 * Change the paging mode data indexes. 3565 */ 3566 uintptr_t idxNewGst = pVCpu->pgm.s.idxGuestModeData = pgmModeToType(enmGuestMode); 3567 AssertReturn(idxNewGst < RT_ELEMENTS(g_aPgmGuestModeData), VERR_PGM_MODE_IPE); 3568 AssertReturn(g_aPgmGuestModeData[idxNewGst].uType == idxNewGst, VERR_PGM_MODE_IPE); 3569 AssertPtrReturn(g_aPgmGuestModeData[idxNewGst].pfnGetPage, VERR_PGM_MODE_IPE); 3570 AssertPtrReturn(g_aPgmGuestModeData[idxNewGst].pfnModifyPage, VERR_PGM_MODE_IPE); 3571 AssertPtrReturn(g_aPgmGuestModeData[idxNewGst].pfnGetPDE, VERR_PGM_MODE_IPE); 3572 AssertPtrReturn(g_aPgmGuestModeData[idxNewGst].pfnExit, VERR_PGM_MODE_IPE); 3573 AssertPtrReturn(g_aPgmGuestModeData[idxNewGst].pfnEnter, VERR_PGM_MODE_IPE); 3574 #ifdef IN_RING3 3575 AssertPtrReturn(g_aPgmGuestModeData[idxNewGst].pfnRelocate, VERR_PGM_MODE_IPE); 3576 #endif 3577 3578 uintptr_t const idxNewShw = pVCpu->pgm.s.idxShadowModeData = pgmModeToType(enmShadowMode); 3579 AssertReturn(idxNewShw < RT_ELEMENTS(g_aPgmShadowModeData), VERR_PGM_MODE_IPE); 3580 AssertReturn(g_aPgmShadowModeData[idxNewShw].uType == idxNewShw, VERR_PGM_MODE_IPE); 3581 AssertPtrReturn(g_aPgmShadowModeData[idxNewShw].pfnGetPage, VERR_PGM_MODE_IPE); 3582 AssertPtrReturn(g_aPgmShadowModeData[idxNewShw].pfnModifyPage, VERR_PGM_MODE_IPE); 3583 AssertPtrReturn(g_aPgmShadowModeData[idxNewShw].pfnExit, VERR_PGM_MODE_IPE); 3584 AssertPtrReturn(g_aPgmShadowModeData[idxNewShw].pfnEnter, VERR_PGM_MODE_IPE); 3585 #ifdef IN_RING3 3586 AssertPtrReturn(g_aPgmShadowModeData[idxNewShw].pfnRelocate, VERR_PGM_MODE_IPE); 3587 #endif 3588 3589 uintptr_t const idxNewBth = pVCpu->pgm.s.idxBothModeData = (idxNewShw - PGM_TYPE_FIRST_SHADOW) * PGM_TYPE_END + idxNewGst; 3590 AssertReturn(g_aPgmBothModeData[idxNewBth].uShwType == idxNewShw, VERR_PGM_MODE_IPE); 3591 AssertReturn(g_aPgmBothModeData[idxNewBth].uGstType == idxNewGst, VERR_PGM_MODE_IPE); 3592 AssertPtrReturn(g_aPgmBothModeData[idxNewBth].pfnInvalidatePage, VERR_PGM_MODE_IPE); 3593 AssertPtrReturn(g_aPgmBothModeData[idxNewBth].pfnSyncCR3, VERR_PGM_MODE_IPE); 3594 AssertPtrReturn(g_aPgmBothModeData[idxNewBth].pfnPrefetchPage, VERR_PGM_MODE_IPE); 3595 AssertPtrReturn(g_aPgmBothModeData[idxNewBth].pfnVerifyAccessSyncPage, VERR_PGM_MODE_IPE); 3596 AssertPtrReturn(g_aPgmBothModeData[idxNewBth].pfnMapCR3, VERR_PGM_MODE_IPE); 3597 AssertPtrReturn(g_aPgmBothModeData[idxNewBth].pfnUnmapCR3, VERR_PGM_MODE_IPE); 3598 AssertPtrReturn(g_aPgmBothModeData[idxNewBth].pfnEnter, VERR_PGM_MODE_IPE); 3599 #ifdef IN_RING3 3600 AssertPtrReturn(g_aPgmBothModeData[idxNewBth].pfnRelocate, VERR_PGM_MODE_IPE); 3601 #endif 3602 #ifdef VBOX_STRICT 3603 AssertPtrReturn(g_aPgmBothModeData[idxNewBth].pfnAssertCR3, VERR_PGM_MODE_IPE); 3604 #endif 3617 3605 3618 3606 /* … … 3621 3609 if (enmShadowMode != pVCpu->pgm.s.enmShadowMode) 3622 3610 { 3623 int rc;3624 bool const fIsNewGuestPagingMode64Bits = enmGuestMode >= PGMMODE_AMD64;3625 3611 pVCpu->pgm.s.enmShadowMode = enmShadowMode; 3626 switch (enmShadowMode) 3627 { 3628 case PGMMODE_32_BIT: 3629 rc = PGM_SHW_NAME_32BIT(Enter)(pVCpu, false); 3630 break; 3631 case PGMMODE_PAE: 3632 case PGMMODE_PAE_NX: 3633 rc = PGM_SHW_NAME_PAE(Enter)(pVCpu, false); 3634 break; 3635 case PGMMODE_AMD64: 3636 case PGMMODE_AMD64_NX: 3637 rc = PGM_SHW_NAME_AMD64(Enter)(pVCpu, fIsNewGuestPagingMode64Bits); 3638 break; 3639 case PGMMODE_NESTED_32BIT: 3640 rc = PGM_SHW_NAME_NESTED_32BIT(Enter)(pVCpu, fIsNewGuestPagingMode64Bits); 3641 break; 3642 case PGMMODE_NESTED_PAE: 3643 rc = PGM_SHW_NAME_NESTED_PAE(Enter)(pVCpu, fIsNewGuestPagingMode64Bits); 3644 break; 3645 case PGMMODE_NESTED_AMD64: 3646 rc = PGM_SHW_NAME_NESTED_AMD64(Enter)(pVCpu, fIsNewGuestPagingMode64Bits); 3647 break; 3648 case PGMMODE_EPT: 3649 rc = PGM_SHW_NAME_EPT(Enter)(pVCpu, fIsNewGuestPagingMode64Bits); 3650 break; 3651 case PGMMODE_REAL: 3652 case PGMMODE_PROTECTED: 3653 default: 3654 AssertReleaseMsgFailed(("enmShadowMode=%d\n", enmShadowMode)); 3655 return VERR_INTERNAL_ERROR; 3656 } 3657 if (RT_FAILURE(rc)) 3658 { 3659 AssertReleaseMsgFailed(("Entering enmShadowMode=%d failed: %Rrc\n", enmShadowMode, rc)); 3660 pVCpu->pgm.s.enmShadowMode = PGMMODE_INVALID; 3661 return rc; 3662 } 3612 int rc = g_aPgmShadowModeData[idxNewShw].pfnEnter(pVCpu, enmGuestMode >= PGMMODE_AMD64); 3613 AssertLogRelMsgRCReturnStmt(rc, ("Entering enmShadowMode=%s failed: %Rrc\n", PGMGetModeName(enmShadowMode), rc), 3614 pVCpu->pgm.s.enmShadowMode = PGMMODE_INVALID, rc); 3663 3615 } 3664 3616 … … 3671 3623 * Enter the new guest and shadow+guest modes. 3672 3624 */ 3673 int rc = -1; 3674 int rc2 = -1; 3675 RTGCPHYS GCPhysCR3 = NIL_RTGCPHYS; 3676 pVCpu->pgm.s.enmGuestMode = enmGuestMode; 3625 RTGCPHYS GCPhysCR3; 3677 3626 switch (enmGuestMode) 3678 3627 { 3679 3628 case PGMMODE_REAL: 3680 rc = PGM_GST_NAME_REAL(Enter)(pVCpu, NIL_RTGCPHYS);3681 switch (pVCpu->pgm.s.enmShadowMode)3682 {3683 case PGMMODE_32_BIT:3684 rc2 = PGM_BTH_NAME_32BIT_REAL(Enter)(pVCpu, NIL_RTGCPHYS);3685 break;3686 case PGMMODE_PAE:3687 case PGMMODE_PAE_NX:3688 rc2 = PGM_BTH_NAME_PAE_REAL(Enter)(pVCpu, NIL_RTGCPHYS);3689 break;3690 case PGMMODE_NESTED_32BIT:3691 rc2 = PGM_BTH_NAME_NESTED_32BIT_REAL(Enter)(pVCpu, NIL_RTGCPHYS);3692 break;3693 case PGMMODE_NESTED_PAE:3694 rc2 = PGM_BTH_NAME_NESTED_PAE_REAL(Enter)(pVCpu, NIL_RTGCPHYS);3695 break;3696 case PGMMODE_NESTED_AMD64:3697 rc2 = PGM_BTH_NAME_NESTED_AMD64_REAL(Enter)(pVCpu, NIL_RTGCPHYS);3698 break;3699 case PGMMODE_EPT:3700 rc2 = PGM_BTH_NAME_EPT_REAL(Enter)(pVCpu, NIL_RTGCPHYS);3701 break;3702 case PGMMODE_AMD64:3703 case PGMMODE_AMD64_NX:3704 AssertMsgFailedBreak(("Should use PAE shadow mode!\n"));3705 default: AssertFailedBreak();3706 }3707 break;3708 3709 3629 case PGMMODE_PROTECTED: 3710 rc = PGM_GST_NAME_PROT(Enter)(pVCpu, NIL_RTGCPHYS); 3711 switch (pVCpu->pgm.s.enmShadowMode) 3712 { 3713 case PGMMODE_32_BIT: 3714 rc2 = PGM_BTH_NAME_32BIT_PROT(Enter)(pVCpu, NIL_RTGCPHYS); 3715 break; 3716 case PGMMODE_PAE: 3717 case PGMMODE_PAE_NX: 3718 rc2 = PGM_BTH_NAME_PAE_PROT(Enter)(pVCpu, NIL_RTGCPHYS); 3719 break; 3720 case PGMMODE_NESTED_32BIT: 3721 rc2 = PGM_BTH_NAME_NESTED_32BIT_PROT(Enter)(pVCpu, NIL_RTGCPHYS); 3722 break; 3723 case PGMMODE_NESTED_PAE: 3724 rc2 = PGM_BTH_NAME_NESTED_PAE_PROT(Enter)(pVCpu, NIL_RTGCPHYS); 3725 break; 3726 case PGMMODE_NESTED_AMD64: 3727 rc2 = PGM_BTH_NAME_NESTED_AMD64_PROT(Enter)(pVCpu, NIL_RTGCPHYS); 3728 break; 3729 case PGMMODE_EPT: 3730 rc2 = PGM_BTH_NAME_EPT_PROT(Enter)(pVCpu, NIL_RTGCPHYS); 3731 break; 3732 case PGMMODE_AMD64: 3733 case PGMMODE_AMD64_NX: 3734 AssertMsgFailedBreak(("Should use PAE shadow mode!\n")); 3735 default: AssertFailedBreak(); 3736 } 3630 GCPhysCR3 = NIL_RTGCPHYS; 3737 3631 break; 3738 3632 3739 3633 case PGMMODE_32_BIT: 3740 3634 GCPhysCR3 = CPUMGetGuestCR3(pVCpu) & X86_CR3_PAGE_MASK; 3741 rc = PGM_GST_NAME_32BIT(Enter)(pVCpu, GCPhysCR3);3742 switch (pVCpu->pgm.s.enmShadowMode)3743 {3744 case PGMMODE_32_BIT:3745 rc2 = PGM_BTH_NAME_32BIT_32BIT(Enter)(pVCpu, GCPhysCR3);3746 break;3747 case PGMMODE_PAE:3748 case PGMMODE_PAE_NX:3749 rc2 = PGM_BTH_NAME_PAE_32BIT(Enter)(pVCpu, GCPhysCR3);3750 break;3751 case PGMMODE_NESTED_32BIT:3752 rc2 = PGM_BTH_NAME_NESTED_32BIT_32BIT(Enter)(pVCpu, GCPhysCR3);3753 break;3754 case PGMMODE_NESTED_PAE:3755 rc2 = PGM_BTH_NAME_NESTED_PAE_32BIT(Enter)(pVCpu, GCPhysCR3);3756 break;3757 case PGMMODE_NESTED_AMD64:3758 rc2 = PGM_BTH_NAME_NESTED_AMD64_32BIT(Enter)(pVCpu, GCPhysCR3);3759 break;3760 case PGMMODE_EPT:3761 rc2 = PGM_BTH_NAME_EPT_32BIT(Enter)(pVCpu, GCPhysCR3);3762 break;3763 case PGMMODE_AMD64:3764 case PGMMODE_AMD64_NX:3765 AssertMsgFailedBreak(("Should use PAE shadow mode!\n"));3766 default: AssertFailedBreak();3767 }3768 3635 break; 3769 3636 3770 3637 case PGMMODE_PAE_NX: 3771 3638 case PGMMODE_PAE: 3772 { 3773 uint32_t u32Dummy, u32Features; 3774 3775 CPUMGetGuestCpuId(pVCpu, 1, 0, &u32Dummy, &u32Dummy, &u32Dummy, &u32Features); 3776 if (!(u32Features & X86_CPUID_FEATURE_EDX_PAE)) 3639 if (!pVM->cpum.ro.GuestFeatures.fPae) 3777 3640 return VMSetRuntimeError(pVM, VMSETRTERR_FLAGS_FATAL, "PAEmode", 3778 3641 N_("The guest is trying to switch to the PAE mode which is currently disabled by default in VirtualBox. PAE support can be enabled using the VM settings (System/Processor)")); 3779 3780 3642 GCPhysCR3 = CPUMGetGuestCR3(pVCpu) & X86_CR3_PAE_PAGE_MASK; 3781 rc = PGM_GST_NAME_PAE(Enter)(pVCpu, GCPhysCR3);3782 switch (pVCpu->pgm.s.enmShadowMode)3783 {3784 case PGMMODE_PAE:3785 case PGMMODE_PAE_NX:3786 rc2 = PGM_BTH_NAME_PAE_PAE(Enter)(pVCpu, GCPhysCR3);3787 break;3788 case PGMMODE_NESTED_32BIT:3789 rc2 = PGM_BTH_NAME_NESTED_32BIT_PAE(Enter)(pVCpu, GCPhysCR3);3790 break;3791 case PGMMODE_NESTED_PAE:3792 rc2 = PGM_BTH_NAME_NESTED_PAE_PAE(Enter)(pVCpu, GCPhysCR3);3793 break;3794 case PGMMODE_NESTED_AMD64:3795 rc2 = PGM_BTH_NAME_NESTED_AMD64_PAE(Enter)(pVCpu, GCPhysCR3);3796 break;3797 case PGMMODE_EPT:3798 rc2 = PGM_BTH_NAME_EPT_PAE(Enter)(pVCpu, GCPhysCR3);3799 break;3800 case PGMMODE_32_BIT:3801 case PGMMODE_AMD64:3802 case PGMMODE_AMD64_NX:3803 AssertMsgFailedBreak(("Should use PAE shadow mode!\n"));3804 default: AssertFailedBreak();3805 }3806 3643 break; 3807 }3808 3644 3809 3645 #ifdef VBOX_WITH_64_BITS_GUESTS … … 3811 3647 case PGMMODE_AMD64: 3812 3648 GCPhysCR3 = CPUMGetGuestCR3(pVCpu) & X86_CR3_AMD64_PAGE_MASK; 3813 rc = PGM_GST_NAME_AMD64(Enter)(pVCpu, GCPhysCR3);3814 switch (pVCpu->pgm.s.enmShadowMode)3815 {3816 case PGMMODE_AMD64:3817 case PGMMODE_AMD64_NX:3818 rc2 = PGM_BTH_NAME_AMD64_AMD64(Enter)(pVCpu, GCPhysCR3);3819 break;3820 case PGMMODE_NESTED_32BIT:3821 rc2 = PGM_BTH_NAME_NESTED_32BIT_AMD64(Enter)(pVCpu, GCPhysCR3);3822 break;3823 case PGMMODE_NESTED_PAE:3824 rc2 = PGM_BTH_NAME_NESTED_PAE_AMD64(Enter)(pVCpu, GCPhysCR3);3825 break;3826 case PGMMODE_NESTED_AMD64:3827 rc2 = PGM_BTH_NAME_NESTED_AMD64_AMD64(Enter)(pVCpu, GCPhysCR3);3828 break;3829 case PGMMODE_EPT:3830 rc2 = PGM_BTH_NAME_EPT_AMD64(Enter)(pVCpu, GCPhysCR3);3831 break;3832 case PGMMODE_32_BIT:3833 case PGMMODE_PAE:3834 case PGMMODE_PAE_NX:3835 AssertMsgFailedBreak(("Should use AMD64 shadow mode!\n"));3836 default: AssertFailedBreak();3837 }3838 3649 break; 3839 3650 #endif 3840 3841 3651 default: 3842 AssertReleaseMsgFailed(("enmGuestMode=%d\n", enmGuestMode)); 3843 rc = VERR_NOT_IMPLEMENTED; 3844 break; 3845 } 3652 AssertLogRelMsgFailedReturn(("enmGuestMode=%d\n", enmGuestMode), VERR_NOT_IMPLEMENTED); 3653 } 3654 3655 pVCpu->pgm.s.enmGuestMode = enmGuestMode; 3656 3657 int rc = g_aPgmGuestModeData[idxNewGst].pfnEnter(pVCpu, GCPhysCR3); 3658 int rc2 = g_aPgmBothModeData[idxNewBth].pfnEnter(pVCpu, GCPhysCR3); 3846 3659 3847 3660 /* Set the new guest CR3. */ … … 3858 3671 } 3859 3672 3860 /* Notify HM as well. */ 3673 /* 3674 * Notify HM. 3675 */ 3861 3676 HMR3PagingModeChanged(pVM, pVCpu, pVCpu->pgm.s.enmShadowMode, pVCpu->pgm.s.enmGuestMode); 3862 3677 return rc;
Note:
See TracChangeset
for help on using the changeset viewer.