VirtualBox

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


Ignore:
Timestamp:
Dec 4, 2018 10:42:07 AM (6 years ago)
Author:
vboxsync
Message:

VMM: Nested VMX: bugref:9180 Pending guest debug exception injection.

File:
1 edited

Legend:

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

    r75916 r75940  
    68646864     */
    68656865    PCVMXVVMCS pVmcs = pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs);
    6866     uint32_t const uEntryIntInfo = pVmcs->u32EntryIntInfo;
    6867     if (!HMVmxIsVmentryVectoring(uEntryIntInfo))
     6866    bool const fEntryVectoring = HMVmxIsVmentryVectoring(pVmcs->u32EntryIntInfo, NULL /* puEntryIntInfoType */);
     6867    if (!fEntryVectoring)
    68686868    {
    68696869        if (pVmcs->u32GuestIntrState & (VMX_VMCS_GUEST_INT_STATE_BLOCK_STI | VMX_VMCS_GUEST_INT_STATE_BLOCK_MOVSS))
     
    68866886        VMCPU_FF_SET(pVCpu, VMCPU_FF_BLOCK_NMIS);
    68876887
    6888     /** @todo NSTVMX: Pending debug exceptions. */
    6889     Assert(!(pVmcs->u64GuestPendingDbgXcpt.u));
    6890 
    68916888    /* Loading PDPTEs will be taken care when we switch modes. We don't support EPT yet. */
    68926889    Assert(!(pVmcs->u32ProcCtls2 & VMX_PROC_CTLS2_EPT));
     
    69316928    NOREF(pszInstr);
    69326929    return VINF_SUCCESS;
     6930}
     6931
     6932
     6933/**
     6934 * Returns whether there are is a pending debug exception on VM-entry.
     6935 *
     6936 * @param   pVCpu       The cross context virtual CPU structure.
     6937 * @param   pszInstr    The VMX instruction name (for logging purposes).
     6938 */
     6939IEM_STATIC bool iemVmxVmentryIsPendingDebugXcpt(PVMCPU pVCpu, const char *pszInstr)
     6940{
     6941    /*
     6942     * Pending debug exceptions.
     6943     * See Intel spec. 26.6.3 "Delivery of Pending Debug Exceptions after VM Entry".
     6944     */
     6945    PCVMXVVMCS pVmcs = pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs);
     6946    Assert(pVmcs);
     6947
     6948    bool fPendingDbgXcpt = RT_BOOL(pVmcs->u64GuestPendingDbgXcpt.u & (  VMX_VMCS_GUEST_PENDING_DEBUG_XCPT_BS
     6949                                                                      | VMX_VMCS_GUEST_PENDING_DEBUG_XCPT_EN_BP));
     6950    if (fPendingDbgXcpt)
     6951    {
     6952        uint8_t uEntryIntInfoType;
     6953        bool const fEntryVectoring = HMVmxIsVmentryVectoring(pVmcs->u32EntryIntInfo, &uEntryIntInfoType);
     6954        if (fEntryVectoring)
     6955        {
     6956            switch (uEntryIntInfoType)
     6957            {
     6958                case VMX_ENTRY_INT_INFO_TYPE_EXT_INT:
     6959                case VMX_ENTRY_INT_INFO_TYPE_NMI:
     6960                case VMX_ENTRY_INT_INFO_TYPE_HW_XCPT:
     6961                case VMX_ENTRY_INT_INFO_TYPE_PRIV_SW_XCPT:
     6962                    fPendingDbgXcpt = false;
     6963                    break;
     6964
     6965                case VMX_ENTRY_INT_INFO_TYPE_SW_XCPT:
     6966                {
     6967                    /*
     6968                     * Whether the pending debug exception for software exceptions other than
     6969                     * #BP and #OF is delivered after injecting the exception or is discard
     6970                     * is CPU implementation specific. We will discard them (easier).
     6971                     */
     6972                    uint8_t const uVector = VMX_ENTRY_INT_INFO_VECTOR(pVmcs->u32EntryIntInfo);
     6973                    if (   uVector != X86_XCPT_BP
     6974                        && uVector != X86_XCPT_OF)
     6975                        fPendingDbgXcpt = false;
     6976                    RT_FALL_THRU();
     6977                }
     6978                case VMX_ENTRY_INT_INFO_TYPE_SW_INT:
     6979                {
     6980                    if (!(pVmcs->u32GuestIntrState & VMX_VMCS_GUEST_INT_STATE_BLOCK_MOVSS))
     6981                        fPendingDbgXcpt = false;
     6982                    break;
     6983                }
     6984            }
     6985        }
     6986        else
     6987        {
     6988            /*
     6989             * When the VM-entry is not vectoring but there is blocking-by-MovSS, whether the
     6990             * pending debug exception is held pending or is discarded is CPU implementation
     6991             * specific. We will discard them (easier).
     6992             */
     6993            if (pVmcs->u32GuestIntrState & VMX_VMCS_GUEST_INT_STATE_BLOCK_MOVSS)
     6994                fPendingDbgXcpt = false;
     6995
     6996            /* There's no pending debug exception in the shutdown or wait-for-SIPI state. */
     6997            if (pVmcs->u32GuestActivityState & (VMX_VMCS_GUEST_ACTIVITY_SHUTDOWN | VMX_VMCS_GUEST_ACTIVITY_SIPI_WAIT))
     6998                fPendingDbgXcpt = false;
     6999        }
     7000    }
     7001
     7002    NOREF(pszInstr);
     7003    return fPendingDbgXcpt;
    69337004}
    69347005
     
    69917062        }
    69927063
    6993         int rc = HMVmxEntryIntInfoInjectTrpmEvent(pVCpu, uEntryIntInfo, pVmcs->u32EntryXcptErrCode, pVmcs->u32EntryInstrLen,
    6994                                                   pVCpu->cpum.GstCtx.cr2);
    6995         AssertRCReturn(rc, rc);
     7064        return HMVmxEntryIntInfoInjectTrpmEvent(pVCpu, uEntryIntInfo, pVmcs->u32EntryXcptErrCode, pVmcs->u32EntryInstrLen,
     7065                                                pVCpu->cpum.GstCtx.cr2);
     7066    }
     7067
     7068    /*
     7069     * Inject any pending guest debug exception.
     7070     * Unlike injecting events, this #DB injection on VM-entry is subject to #DB VMX intercept.
     7071     * See Intel spec. 26.6.3 "Delivery of Pending Debug Exceptions after VM Entry".
     7072     */
     7073    bool const fPendingDbgXcpt = iemVmxVmentryIsPendingDebugXcpt(pVCpu, pszInstr);
     7074    if (fPendingDbgXcpt)
     7075    {
     7076        pVCpu->cpum.GstCtx.hwvirt.vmx.fInterceptEvents = true;
     7077
     7078        uint32_t const uEntryIntInfo = RT_BF_MAKE(VMX_BF_ENTRY_INT_INFO_VECTOR, X86_XCPT_DB)
     7079                                     | RT_BF_MAKE(VMX_BF_ENTRY_INT_INFO_TYPE, VMX_ENTRY_INT_INFO_TYPE_HW_XCPT)
     7080                                     | RT_BF_MAKE(VMX_BF_ENTRY_INT_INFO_VALID, 1);
     7081
     7082        return HMVmxEntryIntInfoInjectTrpmEvent(pVCpu, uEntryIntInfo, 0 /* uErrCode */, pVmcs->u32EntryInstrLen,
     7083                                                  0 /* GCPtrFaultAddress */);
    69967084    }
    69977085
     
    71797267                                 * 3.  TPR below threshold / APIC-write.
    71807268                                 * 4.  SMI, INIT.
    7181                                  * 6.  MTF exit.
    7182                                  * 7.  Debug-trap exceptions, pending debug exceptions.
    7183                                  * 10. VMX-preemption timer.
    7184                                  * 11. NMI-window exit.
    7185                                  * 12. NMI injection.
    7186                                  * 13. Interrupt-window exit.
    7187                                  * 14. Virtual-interrupt injection.
    7188                                  * 15. Interrupt injection.
    7189                                  * 16. Process next instruction (fetch, decode, execute).
     7269                                 * 5.  MTF exit.
     7270                                 * 6.  Debug-trap exceptions, pending debug exceptions.
     7271                                 * 7. VMX-preemption timer.
     7272                                 * 9. NMI-window exit.
     7273                                 * 10. NMI injection.
     7274                                 * 11. Interrupt-window exit.
     7275                                 * 12. Virtual-interrupt injection.
     7276                                 * 13. Interrupt injection.
     7277                                 * 14. Process next instruction (fetch, decode, execute).
    71907278                                 */
    71917279
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