VirtualBox

Changeset 77169 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Feb 6, 2019 4:52:01 AM (6 years ago)
Author:
vboxsync
Message:

VMM/IEM: Nested VMX: bugref:9180 Clear IDT-vectoring info fields for double-fault intercepted (using the exception bitmap) during delivery of an event.

Location:
trunk/src/VBox/VMM/VMMAll
Files:
2 edited

Legend:

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

    r77094 r77169  
    980980IEM_STATIC VBOXSTRICTRC     iemVmxVmexitTaskSwitch(PVMCPU pVCpu, IEMTASKSWITCH enmTaskSwitch, RTSEL SelNewTss, uint8_t cbInstr);
    981981IEM_STATIC VBOXSTRICTRC     iemVmxVmexitEvent(PVMCPU pVCpu, uint8_t uVector, uint32_t fFlags, uint32_t uErrCode, uint64_t uCr2, uint8_t cbInstr);
     982IEM_STATIC VBOXSTRICTRC     iemVmxVmexitEventDoubleFault(PVMCPU pVCpu);
    982983IEM_STATIC VBOXSTRICTRC     iemVmxVmexitTripleFault(PVMCPU pVCpu);
    983984IEM_STATIC VBOXSTRICTRC     iemVmxVmexitPreemptTimer(PVMCPU pVCpu);
     
    56045605            u8Vector = X86_XCPT_DF;
    56055606            uErr     = 0;
    5606             /** @todo NSTVMX: Do we need to do something here for VMX? */
     5607#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
     5608            /* VMX nested-guest #DF intercept needs to be checked here. */
     5609            if (IEM_VMX_IS_NON_ROOT_MODE(pVCpu))
     5610            {
     5611                VBOXSTRICTRC rcStrict0 = iemVmxVmexitEventDoubleFault(pVCpu);
     5612                if (rcStrict0 != VINF_VMX_INTERCEPT_NOT_ACTIVE)
     5613                    return rcStrict0;
     5614            }
     5615#endif
    56075616            /* SVM nested-guest #DF intercepts need to be checked now. See AMD spec. 15.12 "Exception Intercepts". */
    56085617            if (IEM_SVM_IS_XCPT_INTERCEPT_SET(pVCpu, X86_XCPT_DF))
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h

    r77168 r77169  
    39263926
    39273927/**
     3928 * VMX VM-exit handler for VM-exits due to a double fault caused during delivery of
     3929 * an event.
     3930 *
     3931 * @returns VBox strict status code.
     3932 * @param   pVCpu       The cross context virtual CPU structure.
     3933 */
     3934IEM_STATIC VBOXSTRICTRC iemVmxVmexitEventDoubleFault(PVMCPU pVCpu)
     3935{
     3936    PCVMXVVMCS pVmcs = pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs);
     3937    Assert(pVmcs);
     3938
     3939    uint32_t const fXcptBitmap = pVmcs->u32XcptBitmap;
     3940    if (fXcptBitmap & RT_BIT(X86_XCPT_DF))
     3941    {
     3942        uint8_t  const fNmiUnblocking = pVCpu->cpum.GstCtx.hwvirt.vmx.fNmiUnblockingIret;
     3943        uint32_t const uExitIntInfo   = RT_BF_MAKE(VMX_BF_EXIT_INT_INFO_VECTOR,           X86_XCPT_DF)
     3944                                      | RT_BF_MAKE(VMX_BF_EXIT_INT_INFO_TYPE,             VMX_EXIT_INT_INFO_TYPE_HW_XCPT)
     3945                                      | RT_BF_MAKE(VMX_BF_EXIT_INT_INFO_ERR_CODE_VALID,   1)
     3946                                      | RT_BF_MAKE(VMX_BF_EXIT_INT_INFO_NMI_UNBLOCK_IRET, fNmiUnblocking)
     3947                                      | RT_BF_MAKE(VMX_BF_EXIT_INT_INFO_VALID,            1);
     3948        iemVmxVmcsSetExitIntInfo(pVCpu, uExitIntInfo);
     3949        iemVmxVmcsSetExitIntErrCode(pVCpu, 0);
     3950        iemVmxVmcsSetExitQual(pVCpu, 0);
     3951        iemVmxVmcsSetExitInstrLen(pVCpu, 0);
     3952
     3953        /*
     3954         * A VM-exit is not considered to occur during event delivery when the original
     3955         * event results in a double-fault that causes a VM-exit directly (i.e. intercepted
     3956         * using the exception bitmap).
     3957         *
     3958         * Therefore, we must clear the original event from the IDT-vectoring fields which
     3959         * would've been recorded before causing the VM-exit.
     3960         *
     3961         * 27.2.3 "Information for VM Exits During Event Delivery"
     3962         */
     3963        iemVmxVmcsSetIdtVectoringInfo(pVCpu, 0);
     3964        iemVmxVmcsSetIdtVectoringErrCode(pVCpu, 0);
     3965
     3966        return iemVmxVmexit(pVCpu, VMX_EXIT_XCPT_OR_NMI);
     3967    }
     3968
     3969    return VINF_VMX_INTERCEPT_NOT_ACTIVE;
     3970}
     3971
     3972
     3973/**
    39283974 * VMX VM-exit handler for VM-exits due to delivery of an event.
    39293975 *
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