VirtualBox

Changeset 68150 in vbox


Ignore:
Timestamp:
Jul 28, 2017 8:32:26 AM (7 years ago)
Author:
vboxsync
Message:

VMM/IEM: Nested Hw.virt: Fixes.

File:
1 edited

Legend:

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

    r67945 r68150  
    5252
    5353/**
    54  * Helper for handling a SVM world-switch (VMRUN, \#VMEXIT).
     54 * Performs an SVM world-switch (VMRUN, \#VMEXIT) updating PGM and IEM internals.
    5555 *
    5656 * @returns Strict VBox status code.
    5757 * @param   pVCpu       The cross context virtual CPU structure.
    58  * @param   uOldEfer    EFER MSR prior to the world-switch.
    59  * @param   uOldCr0     CR0 prior to the world-switch.
    60  */
    61 DECLINLINE(VBOXSTRICTRC) iemSvmHandleWorldSwitch(PVMCPU pVCpu, uint64_t uOldEfer, uint64_t uOldCr0)
    62 {
    63     RT_NOREF(uOldEfer); RT_NOREF(uOldCr0);
    64 
    65     PCPUMCTX pCtx = IEM_GET_CTX(pVCpu);
     58 * @param   pCtx        The guest-CPU context.
     59 */
     60DECLINLINE(VBOXSTRICTRC) iemSvmWorldSwitch(PVMCPU pVCpu, PCPUMCTX pCtx)
     61{
     62    /* Flush the TLB with new CR3. */
     63    PGMFlushTLB(pVCpu, pCtx->cr3, true);
    6664
    6765    /*
    68      * Inform PGM.
     66     * Inform PGM about paging mode changes.
    6967     * We include X86_CR0_PE because PGM doesn't handle paged-real mode yet,
    7068     * see comment in iemMemPageTranslateAndCheckAccess().
    7169     */
    72     PGMFlushTLB(pVCpu, pCtx->cr3, true);
    7370    int rc = PGMChangeMode(pVCpu, pCtx->cr0 | X86_CR0_PE, pCtx->cr4, pCtx->msrEFER);
    7471    AssertRCReturn(rc, rc);
    7572
    76     /* Inform CPUM (recompiler). */
     73    /* Inform CPUM (recompiler), can later be removed. */
    7774    CPUMSetChangedFlags(pVCpu, CPUM_CHANGED_ALL);
    7875
     
    227224                /** @todo ASID. */
    228225
    229                 uint64_t const uOldCr0  = pCtx->cr0;
    230                 uint64_t const uOldEfer = pCtx->msrEFER;
    231 
    232226                /*
    233227                 * Reload the guest's "host state".
     
    260254                /* Restore guest's force-flags. */
    261255                if (pCtx->hwvirt.fLocalForcedActions)
     256                {
    262257                    VMCPU_FF_SET(pVCpu, pCtx->hwvirt.fLocalForcedActions);
     258                    pCtx->hwvirt.fLocalForcedActions = 0;
     259                }
    263260
    264261                /*
    265                  * Inform PGM and others of the world-switch.
     262                 * Update PGM, IEM and others of a world-switch.
    266263                 */
    267                 rcStrict = iemSvmHandleWorldSwitch(pVCpu, uOldEfer, uOldCr0);
     264                rcStrict = iemSvmWorldSwitch(pVCpu, pCtx);
    268265                if (rcStrict == VINF_SUCCESS)
    269266                    return VINF_SVM_VMEXIT;
     
    271268                if (RT_SUCCESS(rcStrict))
    272269                {
    273                     LogFlow(("iemSvmVmexit: Setting passup status from iemSvmHandleWorldSwitch %Rrc\n", rcStrict));
     270                    LogFlow(("iemSvmVmexit: Setting passup status from iemSvmWorldSwitch %Rrc\n", rcStrict));
    274271                    iemSetPassUpStatus(pVCpu, rcStrict);
    275272                    return VINF_SVM_VMEXIT;
    276273                }
    277274
    278                 LogFlow(("iemSvmVmexit: iemSvmHandleWorldSwitch unexpected failure. rc=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
     275                LogFlow(("iemSvmVmexit: iemSvmWorldSwitch unexpected failure. rc=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
    279276            }
    280277            else
     
    327324
    328325    /*
     326     * Save the host state.
     327     */
     328    PSVMHOSTSTATE pHostState = &pCtx->hwvirt.svm.HostState;
     329    pHostState->es       = pCtx->es;
     330    pHostState->cs       = pCtx->cs;
     331    pHostState->ss       = pCtx->ss;
     332    pHostState->ds       = pCtx->ds;
     333    pHostState->gdtr     = pCtx->gdtr;
     334    pHostState->idtr     = pCtx->idtr;
     335    pHostState->uEferMsr = pCtx->msrEFER;
     336    pHostState->uCr0     = pCtx->cr0;
     337    pHostState->uCr3     = pCtx->cr3;
     338    pHostState->uCr4     = pCtx->cr4;
     339    pHostState->rflags   = pCtx->rflags;
     340    pHostState->uRip     = pCtx->rip + cbInstr;
     341    pHostState->uRsp     = pCtx->rsp;
     342    pHostState->uRax     = pCtx->rax;
     343
     344    /*
    329345     * Read the guest VMCB state.
    330346     */
     
    336352
    337353        /*
    338          * Save the host state.
    339          */
    340         PSVMHOSTSTATE pHostState = &pCtx->hwvirt.svm.HostState;
    341         pHostState->es         = pCtx->es;
    342         pHostState->cs         = pCtx->cs;
    343         pHostState->ss         = pCtx->ss;
    344         pHostState->ds         = pCtx->ds;
    345         pHostState->gdtr       = pCtx->gdtr;
    346         pHostState->idtr       = pCtx->idtr;
    347         pHostState->uEferMsr   = pCtx->msrEFER;
    348         pHostState->uCr0       = pCtx->cr0;
    349         pHostState->uCr3       = pCtx->cr3;
    350         pHostState->uCr4       = pCtx->cr4;
    351         pHostState->rflags     = pCtx->rflags;
    352         pHostState->uRip       = pCtx->rip + cbInstr;
    353         pHostState->uRsp       = pCtx->rsp;
    354         pHostState->uRax       = pCtx->rax;
    355 
    356         /*
    357354         * Validate guest-state and controls.
    358355         */
    359         /* VMRUN must always be iHMSntercepted. */
     356        /* VMRUN must always be intercepted. */
    360357        if (!CPUMIsGuestSvmCtrlInterceptSet(pCtx, SVM_CTRL_INTERCEPT_VMRUN))
    361358        {
     
    552549        if (pVmcbCtrl->u64IntShadow & SVM_INTERRUPT_SHADOW_ACTIVE)
    553550        {
    554             LogFlow(("iemSvmVmrun: setting inerrupt shadow. inhibit PC=%#RX64\n", pVmcbNstGst->u64RIP));
     551            LogFlow(("iemSvmVmrun: setting interrupt shadow. inhibit PC=%#RX64\n", pVmcbNstGst->u64RIP));
    555552            /** @todo will this cause trouble if the nested-guest is 64-bit but the guest is 32-bit? */
    556553            EMSetInhibitInterruptsPC(pVCpu, pVmcbNstGst->u64RIP);
     
    560557         * TLB flush control.
    561558         * Currently disabled since it's redundant as we unconditionally flush the TLB
    562          * in iemSvmHandleWorldSwitch() below.
     559         * in iemSvmWorldSwitch() below.
    563560         */
    564561#if 0
     
    571568
    572569        /** @todo @bugref{7243}: SVM TSC offset, see tmCpuTickGetInternal. */
    573 
    574         uint64_t const uOldEfer = pCtx->msrEFER;
    575         uint64_t const uOldCr0  = pCtx->cr0;
    576570
    577571        /*
     
    609603
    610604        /*
    611          * Clear global interrupt flags to allow interrupts in the guest.
    612          */
    613         pCtx->hwvirt.svm.fGif = 1;
    614 
    615         /*
    616          * Inform PGM and others of the world-switch.
    617          */
    618         VBOXSTRICTRC rcStrict = iemSvmHandleWorldSwitch(pVCpu, uOldEfer, uOldCr0);
     605         * Update PGM, IEM and others of a world-switch.
     606         */
     607        VBOXSTRICTRC rcStrict = iemSvmWorldSwitch(pVCpu, pCtx);
    619608        if (rcStrict == VINF_SUCCESS)
    620609        { /* likely */ }
     
    623612        else
    624613        {
    625             LogFlow(("iemSvmVmrun: iemSvmHandleWorldSwitch unexpected failure. rc=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
     614            LogFlow(("iemSvmVmrun: iemSvmWorldSwitch unexpected failure. rc=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
    626615            return rcStrict;
    627616        }
     617
     618        /*
     619         * Clear global interrupt flags to allow interrupts in the guest.
     620         */
     621        pCtx->hwvirt.svm.fGif = 1;
    628622
    629623        /*
     
    11281122    {
    11291123        Assert(!CPUMIsGuestInSvmNestedHwVirtMode(pCtx));
    1130         rcStrict = iemInitiateCpuShutdown(pVCpu);
     1124        rcStrict = VINF_EM_TRIPLE_FAULT;
    11311125    }
    11321126    return rcStrict;
Note: See TracChangeset for help on using the changeset viewer.

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