VirtualBox

Ignore:
Timestamp:
Oct 6, 2021 7:22:04 AM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
147289
Message:

VMM: Nested VMX: bugref:10092 Made changes to PGM++ to handle invalid PAE PDPEs being loaded.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImplSvmInstr.cpp.h

    r91291 r91580  
    8282 *
    8383 * @returns Strict VBox status code.
    84  * @param   pVCpu       The cross context virtual CPU structure.
    85  */
    86 DECLINLINE(VBOXSTRICTRC) iemSvmWorldSwitch(PVMCPUCC pVCpu)
     84 * @param   pVCpu           The cross context virtual CPU structure.
     85 * @param   fPdpesMapped    Whether the PAE PDPEs (and PDPT) have been mapped.
     86 */
     87DECLINLINE(VBOXSTRICTRC) iemSvmWorldSwitch(PVMCPUCC pVCpu, bool fPdpesMapped)
    8788{
    8889    /*
     
    106107    if (rc == VINF_SUCCESS)
    107108    {
    108         rc = PGMFlushTLB(pVCpu, pVCpu->cpum.GstCtx.cr3, true);
     109        rc = PGMFlushTLB(pVCpu, pVCpu->cpum.GstCtx.cr3, true /* fGlobal */, fPdpesMapped);
    109110        AssertRCReturn(rc, rc);
    110111    }
     
    307308
    308309            /*
    309              * Reload the guest's "host state".
     310             * If we are switching to PAE mode host, validate the PDPEs first.
     311             * Any invalid PDPEs here causes a VCPU shutdown.
    310312             */
    311             CPUMSvmVmExitRestoreHostState(pVCpu, IEM_GET_CTX(pVCpu));
    312 
    313             /*
    314              * Update PGM, IEM and others of a world-switch.
    315              */
    316             rcStrict = iemSvmWorldSwitch(pVCpu);
    317             if (rcStrict == VINF_SUCCESS)
    318                 rcStrict = VINF_SVM_VMEXIT;
    319             else if (RT_SUCCESS(rcStrict))
     313            PCSVMHOSTSTATE pHostState = &pVCpu->cpum.GstCtx.hwvirt.svm.HostState;
     314            bool const fHostInPaeMode = CPUMIsPaePagingEnabled(pHostState->uCr0, pHostState->uCr4, pHostState->uEferMsr);
     315            if (fHostInPaeMode)
     316                rcStrict = PGMGstMapPaePdpesAtCr3(pVCpu, pHostState->uCr3);
     317            if (RT_LIKELY(rcStrict == VINF_SUCCESS))
    320318            {
    321                 LogFlow(("iemSvmVmexit: Setting passup status from iemSvmWorldSwitch %Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
    322                 iemSetPassUpStatus(pVCpu, rcStrict);
    323                 rcStrict = VINF_SVM_VMEXIT;
     319                /*
     320                 * Reload the host state.
     321                 */
     322                CPUMSvmVmExitRestoreHostState(pVCpu, IEM_GET_CTX(pVCpu));
     323
     324                /*
     325                 * Update PGM, IEM and others of a world-switch.
     326                 */
     327                rcStrict = iemSvmWorldSwitch(pVCpu, fHostInPaeMode);
     328                if (rcStrict == VINF_SUCCESS)
     329                    rcStrict = VINF_SVM_VMEXIT;
     330                else if (RT_SUCCESS(rcStrict))
     331                {
     332                    LogFlow(("iemSvmVmexit: Setting passup status from iemSvmWorldSwitch %Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
     333                    iemSetPassUpStatus(pVCpu, rcStrict);
     334                    rcStrict = VINF_SVM_VMEXIT;
     335                }
     336                else
     337                    LogFlow(("iemSvmVmexit: iemSvmWorldSwitch unexpected failure. rc=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
    324338            }
    325339            else
    326                 LogFlow(("iemSvmVmexit: iemSvmWorldSwitch unexpected failure. rc=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
     340            {
     341                Log(("iemSvmVmexit: PAE PDPEs invalid while restoring host state. rc=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
     342                rcStrict = VINF_EM_TRIPLE_FAULT;
     343            }
    327344        }
    328345        else
    329346        {
    330347            AssertMsgFailed(("iemSvmVmexit: Mapping VMCB at %#RGp failed. rc=%Rrc\n", pVCpu->cpum.GstCtx.hwvirt.svm.GCPhysVmcb, VBOXSTRICTRC_VAL(rcStrict)));
    331             rcStrict = VERR_SVM_VMEXIT_FAILED;
     348            rcStrict = VINF_EM_TRIPLE_FAULT;
    332349        }
    333350    }
     
    705722
    706723        /*
     724         * Validate and map PAE PDPEs if the guest will be using PAE paging.
     725         * Invalid PAE PDPEs here causes a #VMEXIT.
     726         */
     727        bool fPdpesMapped;
     728        if (   !pVmcbCtrl->NestedPagingCtrl.n.u1NestedPaging
     729            && CPUMIsPaePagingEnabled(pVmcbNstGst->u64CR0, pVmcbNstGst->u64CR4, uValidEfer))
     730        {
     731            rc = PGMGstMapPaePdpesAtCr3(pVCpu, pVmcbNstGst->u64CR3);
     732            if (RT_SUCCESS(rc))
     733                fPdpesMapped = true;
     734            else
     735            {
     736                Log(("iemSvmVmrun: PAE PDPEs invalid -> #VMEXIT\n"));
     737                return iemSvmVmexit(pVCpu, SVM_EXIT_INVALID, 0 /* uExitInfo1 */, 0 /* uExitInfo2 */);
     738            }
     739        }
     740        else
     741            fPdpesMapped = false;
     742
     743        /*
    707744         * Copy the remaining guest state from the VMCB to the guest-CPU context.
    708745         */
     
    742779         * Update PGM, IEM and others of a world-switch.
    743780         */
    744         VBOXSTRICTRC rcStrict = iemSvmWorldSwitch(pVCpu);
     781        VBOXSTRICTRC rcStrict = iemSvmWorldSwitch(pVCpu, fPdpesMapped);
    745782        if (rcStrict == VINF_SUCCESS)
    746783        { /* likely */ }
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette