VirtualBox

Changeset 74303 in vbox for trunk/src/VBox/VMM/VMMAll


Ignore:
Timestamp:
Sep 17, 2018 9:33:58 AM (6 years ago)
Author:
vboxsync
Message:

VMM/CPUM, IEM: Nested VMX: bugref:9180 vmlaunch/vmresume bits.

File:
1 edited

Legend:

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

    r74287 r74303  
    40704070
    40714071/**
     4072 * Loads the guest-state non-register state as part of VM-entry.
     4073 *
     4074 * @returns VBox status code.
     4075 * @param   pVCpu           The cross context virtual CPU structure.
     4076 *
     4077 * @remarks This must be called only after loading the nested-guest register state
     4078 *          (especially nested-guest RIP).
     4079 */
     4080IEM_STATIC void iemVmxVmentryLoadGuestNonRegState(PVMCPU pVCpu)
     4081{
     4082    /*
     4083     * Load guest non-register state.
     4084     * See Intel spec. 26.6 "Special Features of VM Entry"
     4085     */
     4086    PCVMXVVMCS pVmcs = pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs);
     4087    uint32_t const uEntryIntInfo = pVmcs->u32EntryIntInfo;
     4088    if (VMX_ENTRY_INT_INFO_IS_VALID(uEntryIntInfo))
     4089    {
     4090        /** @todo NSTVMX: Pending debug exceptions. */
     4091        Assert(!(pVmcs->u64GuestPendingDbgXcpt.u));
     4092
     4093        if (pVmcs->u32GuestIntrState == VMX_VMCS_GUEST_INT_STATE_BLOCK_NMI)
     4094        {
     4095            /** @todo NSTVMX: Virtual-NMIs doesn't affect NMI blocking in the normal sense.
     4096             *        We probably need a different force flag for virtual-NMI
     4097             *        pending/blocking. */
     4098            Assert(!(pVmcs->u32PinCtls & VMX_PIN_CTLS_VIRT_NMI));
     4099            VMCPU_FF_SET(pVCpu, VMCPU_FF_BLOCK_NMIS);
     4100        }
     4101        else if (   pVmcs->u32GuestIntrState == VMX_VMCS_GUEST_INT_STATE_BLOCK_STI
     4102                 || pVmcs->u32GuestIntrState == VMX_VMCS_GUEST_INT_STATE_BLOCK_MOVSS)
     4103        {
     4104            EMSetInhibitInterruptsPC(pVCpu, pVCpu->cpum.GstCtx.rip);
     4105        }
     4106
     4107        /* SMI blocking is irrelevant. We don't support SMIs yet. */
     4108    }
     4109
     4110    /* Loading PDPTEs will be taken care when we switch modes. We don't support EPT yet. */
     4111    Assert(!(pVmcs->u32ProcCtls2 & VMX_PROC_CTLS2_EPT));
     4112
     4113    /* VPID is irrelevant. We don't support VPID yet. */
     4114
     4115    /* Clear address-range monitoring. */
     4116    EMMonitorWaitClear(pVCpu);
     4117}
     4118
     4119
     4120/**
     4121 * Saves the guest force-flags in prepartion of entering the nested-guest.
     4122 *
     4123 * @param   pVCpu       The cross context virtual CPU structure.
     4124 */
     4125IEM_STATIC void iemVmxVmentrySaveForceFlags(PVMCPU pVCpu)
     4126{
     4127    /* Assert that we are not called multiple times during VM-entry. */
     4128    Assert(pVCpu->cpum.GstCtx.hwvirt.fLocalForcedActions == 0);
     4129
     4130    /*
     4131     * Preserve the required force-flags.
     4132     *
     4133     * We only preserve the force-flags that would affect the execution of the
     4134     * nested-guest (or the guest).
     4135     *
     4136     *   - VMCPU_FF_INHIBIT_INTERRUPTS and RIP needs be preserved as there is no
     4137     *     implicit Global Interrupt Flag (GIF) handling as with AMD-V's VMRUN
     4138     *     instruction and the interrupt inhibition is in effect until the
     4139     *     completion of this VMLAUNCH/VMRESUME instruction.
     4140     *
     4141     *   - VMCPU_FF_BLOCK_NMIS needs to be preserved as it blocks NMI until the
     4142     *     execution of a subsequent IRET instruction in the guest.
     4143     *
     4144     *   - MTF needs to be preserved as it's for a single instruction boundary
     4145     *     which follows the return from VMLAUNCH/VMRESUME instruction.
     4146     *
     4147     * The remaining FFs (e.g. timers) can stay in place so that we will be able to
     4148     * generate interrupts that should cause #VMEXITs for the nested-guest.
     4149     */
     4150    if (VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS))
     4151        pVCpu->cpum.GstCtx.hwvirt.uInhibitRip = EMGetInhibitInterruptsPC(pVCpu);
     4152
     4153    uint32_t const fGuestFFMask = VMCPU_FF_INHIBIT_INTERRUPTS | VMCPU_FF_BLOCK_NMIS | VMCPU_FF_MTF;
     4154    pVCpu->cpum.GstCtx.hwvirt.fLocalForcedActions = pVCpu->fLocalForcedActions & fGuestFFMask;
     4155    VMCPU_FF_CLEAR(pVCpu, fGuestFFMask);
     4156}
     4157
     4158
     4159#if 0
     4160/**
     4161 * Restores the guest force-flags in prepartion of exiting the nested-guest.
     4162 *
     4163 * @param   pVCpu       The cross context virtual CPU structure.
     4164 */
     4165IEM_STATIC void iemVmxVmexitRestoreForceFlags(PVMCPU pVCpu)
     4166{
     4167    if (pVCpu->cpum.GstCtx.hwvirt.fLocalForcedActions)
     4168    {
     4169        VMCPU_FF_SET(pVCpu, pVCpu->cpum.GstCtx.hwvirt.fLocalForcedActions);
     4170        pVCpu->cpum.GstCtx.hwvirt.fLocalForcedActions = 0;
     4171    }
     4172}
     4173#endif
     4174
     4175
     4176/**
    40724177 * Loads the guest-state as part of VM-entry.
    40734178 *
     
    40964201    pVCpu->cpum.GstCtx.rflags.u = pVmcs->u64GuestRFlags.u;
    40974202
    4098     /* Loading PDPTEs will be taken care when we switch modes. We don't support EPT yet. */
    4099     Assert(!(pVmcs->u32ProcCtls2 & VMX_PROC_CTLS2_EPT));
    4100 
    4101     /* Nothing to do for VPID. */
    4102 
    4103     /* Clear address-range monitoring. */
    4104     EMMonitorWaitClear(pVCpu);
     4203    /* Load guest non-register state. */
     4204    iemVmxVmentryLoadGuestNonRegState(pVCpu);
    41054205
    41064206    NOREF(pszInstr);
     
    41254225    if (VMX_ENTRY_INT_INFO_IS_VALID(uEntryIntInfo))
    41264226    {
     4227        /*
     4228         * The event that is going to be made pending for injection is not subject to VMX intercepts,
     4229         * thus we flag ignoring of intercepts. However, recursive exceptions if any during delivery
     4230         * of the current event -are- subject to intercepts, hence this flag will be flipped during
     4231         * the actually delivery of this event.
     4232         */
     4233        pVCpu->cpum.GstCtx.hwvirt.vmx.fInterceptEvents = false;
     4234
    41274235        uint8_t const uType = VMX_ENTRY_INT_INFO_TYPE(uEntryIntInfo);
    41284236        if (uType == VMX_ENTRY_INT_INFO_TYPE_OTHER_EVENT)
     
    41334241        }
    41344242
    4135         /** @todo NSTVMX: Is it safe to update IDT-vectoring information in the VMCS
    4136          *        here? */
    4137 
    4138         pVCpu->cpum.GstCtx.hwvirt.vmx.fInterceptEvents = false;
    41394243        int rc = HMVmxEntryIntInfoInjectTrpmEvent(pVCpu, uEntryIntInfo, pVmcs->u32EntryXcptErrCode, pVmcs->u32EntryInstrLen,
    41404244                                                  pVCpu->cpum.GstCtx.cr2);
     
    42984402                if (RT_SUCCESS(rc))
    42994403                {
     4404                    /* Save the (outer) guest force-flags as VM-exits can occur from this point on. */
     4405                    iemVmxVmentrySaveForceFlags(pVCpu);
     4406
    43004407                    /* Check guest-state fields. */
    43014408                    rc = iemVmxVmentryCheckGuestState(pVCpu, pszInstr);
     
    43424449                                return VINF_SUCCESS;
    43434450                            }
    4344 
    43454451                            /** @todo NSTVMX: VMExit with VMX_EXIT_ERR_MSR_LOAD and set
    43464452                             *        VMX_BF_EXIT_REASON_ENTRY_FAILED. */
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