VirtualBox

Changeset 66750 in vbox for trunk


Ignore:
Timestamp:
May 2, 2017 3:53:18 PM (7 years ago)
Author:
vboxsync
Message:

VMM/HMSVMR0: Use IEM event reflection logic (disabled).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp

    r66581 r66750  
    4141# define HMSVM_ALWAYS_TRAP_PF
    4242# define HMSVM_ALWAYS_TRAP_TASK_SWITCH
     43# define HMSVM_USE_IEM_EVENT_REFLECTION
    4344#endif
    4445
     
    39253926}
    39263927
    3927 
     3928#ifdef HMSVM_USE_IEM_EVENT_REFLECTION
     3929/**
     3930 * Gets the IEM exception flags for the specified SVM event.
     3931 *
     3932 * @returns The IEM exception flags.
     3933 * @param   pEvent      Pointer to the SVM event.
     3934 *
     3935 * @remarks This function currently only constructs flags required for
     3936 *          IEMEvaluateRecursiveXcpt and not the complete flags (e.g. error-code
     3937 *          and CR2 aspects of an exception are not included).
     3938 */
     3939static uint32_t hmR0SvmGetIemXcptFlags(PCSVMEVENT pEvent)
     3940{
     3941    uint8_t const uEventType = pEvent->n.u3Type;
     3942    uint32_t      fIemXcptFlags;
     3943    switch (uEventType)
     3944    {
     3945        case SVM_EVENT_EXCEPTION:
     3946            if (pEvent->n.u8Vector == X86_XCPT_BP)
     3947            {
     3948                fIemXcptFlags = IEM_XCPT_FLAGS_T_SOFT_INT | IEM_XCPT_FLAGS_BP_INSTR;
     3949                break;
     3950            }
     3951            if (pEvent->n.u8Vector == X86_XCPT_OF)
     3952            {
     3953                fIemXcptFlags = IEM_XCPT_FLAGS_T_SOFT_INT | IEM_XCPT_FLAGS_OF_INSTR;
     3954                break;
     3955            }
     3956            /** @todo How do we distinguish ICEBP \#DB from the regular one? */
     3957            /* fall thru */
     3958        case SVM_EVENT_NMI:
     3959            fIemXcptFlags = IEM_XCPT_FLAGS_T_CPU_XCPT;
     3960            break;
     3961
     3962        case SVM_EVENT_EXTERNAL_IRQ:
     3963            fIemXcptFlags = IEM_XCPT_FLAGS_T_EXT_INT;
     3964            break;
     3965
     3966        case SVM_EVENT_SOFTWARE_INT:
     3967            fIemXcptFlags = IEM_XCPT_FLAGS_T_SOFT_INT;
     3968            break;
     3969
     3970        default:
     3971            fIemXcptFlags = 0;
     3972            AssertMsgFailed(("Unexpected event type! uEventType=%#x uVector=%#x", uEventType, pEvent->n.u8Vector));
     3973            break;
     3974    }
     3975    return fIemXcptFlags;
     3976}
     3977
     3978#else
    39283979/**
    39293980 * Determines if an exception is a contributory exception.
     
    39514002    return false;
    39524003}
     4004#endif /* HMSVM_USE_IEM_EVENT_REFLECTION */
    39534005
    39544006
     
    39834035    if (pVmcb->ctrl.ExitIntInfo.n.u1Valid)
    39844036    {
     4037#ifdef HMSVM_USE_IEM_EVENT_REFLECTION
     4038        IEMXCPTRAISE     enmRaise;
     4039        IEMXCPTRAISEINFO fRaiseInfo;
     4040        bool             fReflectingNmi = false;
     4041        bool const       fExitIsHwXcpt  = pSvmTransient->u64ExitCode - SVM_EXIT_EXCEPTION_0 <= SVM_EXIT_EXCEPTION_31;
     4042        if (fExitIsHwXcpt)
     4043        {
     4044            uint8_t  const uIdtVector       = pVmcb->ctrl.ExitIntInfo.n.u8Vector;
     4045            uint8_t  const uExitVector      = pSvmTransient->u64ExitCode - SVM_EXIT_EXCEPTION_0;
     4046            uint32_t const fIdtVectorFlags  = hmR0SvmGetIemXcptFlags(&pVmcb->ctrl.ExitIntInfo);
     4047            uint32_t const fExitVectorFlags = IEM_XCPT_FLAGS_T_CPU_XCPT;
     4048            enmRaise = IEMEvaluateRecursiveXcpt(pVCpu, fIdtVectorFlags, uIdtVector, fExitVectorFlags, uExitVector, &fRaiseInfo);
     4049
     4050            if (fRaiseInfo & (IEMXCPTRAISEINFO_EXT_INT_PF | IEMXCPTRAISEINFO_NMI_PF))
     4051            {
     4052                if (fRaiseInfo & IEMXCPTRAISEINFO_NMI_XCPT)
     4053                    fReflectingNmi = true;
     4054                pSvmTransient->fVectoringPF = true;
     4055            }
     4056            else if (fRaiseInfo & IEMXCPTRAISEINFO_PF_PF)
     4057                pSvmTransient->fVectoringDoublePF = true;
     4058        }
     4059        else
     4060        {
     4061            /*
     4062             * If event delivery caused an #VMEXIT that is not an exception (e.g. #NPF) then reflect the original
     4063             * exception to the guest after handling the #VMEXIT.
     4064             */
     4065            enmRaise   = IEMXCPTRAISE_PREV_EVENT;
     4066            fRaiseInfo = IEMXCPTRAISEINFO_NONE;
     4067        }
     4068
     4069        switch (enmRaise)
     4070        {
     4071            case IEMXCPTRAISE_CURRENT_XCPT:
     4072            case IEMXCPTRAISE_PREV_EVENT:
     4073            {
     4074                /* For software interrupts, we shall re-execute the instruction. */
     4075                if (!(fRaiseInfo & IEMXCPTRAISEINFO_SOFT_INT_XCPT))
     4076                {
     4077                    /* If we are re-injecting the NMI, clear NMI blocking. */
     4078                    if (fReflectingNmi)
     4079                        VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_BLOCK_NMIS);
     4080
     4081                    Assert(pVmcb->ctrl.ExitIntInfo.n.u3Type != SVM_EVENT_SOFTWARE_INT);
     4082                    STAM_COUNTER_INC(&pVCpu->hm.s.StatInjectPendingReflect);
     4083                    hmR0SvmSetPendingEvent(pVCpu, &pVmcb->ctrl.ExitIntInfo, 0 /* GCPtrFaultAddress */);
     4084
     4085                    /* If uExitVector is #PF, CR2 value will be updated from the VMCB if it's a guest #PF. See hmR0SvmExitXcptPF(). */
     4086                    Log4(("IDT: Pending vectoring event %#RX64 ErrValid=%RTbool Err=%#RX32\n", pVmcb->ctrl.ExitIntInfo.u,
     4087                          !!pVmcb->ctrl.ExitIntInfo.n.u1ErrorCodeValid, pVmcb->ctrl.ExitIntInfo.n.u32ErrorCode));
     4088                }
     4089                break;
     4090            }
     4091
     4092            case IEMXCPTRAISE_DOUBLE_FAULT:
     4093            {
     4094                STAM_COUNTER_INC(&pVCpu->hm.s.StatInjectPendingReflect);
     4095                hmR0SvmSetPendingXcptDF(pVCpu);
     4096                rc = VINF_HM_DOUBLE_FAULT;
     4097                break;
     4098            }
     4099
     4100            case IEMXCPTRAISE_TRIPLE_FAULT:
     4101            {
     4102                rc = VINF_EM_RESET;
     4103                break;
     4104            }
     4105
     4106            case IEMXCPTRAISE_CPU_HANG:
     4107            {
     4108                rc = VERR_EM_GUEST_CPU_HANG;
     4109                break;
     4110            }
     4111
     4112            default:
     4113            {
     4114                AssertMsgFailed(("hmR0SvmExitCpuid: EMInterpretCpuId failed with %Rrc\n", rc));
     4115                rc = VERR_SVM_IPE_2;
     4116                break;
     4117            }
     4118        }
     4119#else
    39854120        uint8_t uIdtVector  = pVmcb->ctrl.ExitIntInfo.n.u8Vector;
    39864121
     
    41144249                break;
    41154250        }
     4251#endif  /* HMSVM_USE_IEM_EVENT_REFLECTION */
    41164252    }
    41174253    Assert(rc == VINF_SUCCESS || rc == VINF_HM_DOUBLE_FAULT || rc == VINF_EM_RESET || rc == VERR_EM_GUEST_CPU_HANG);
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