VirtualBox

Changeset 46655 in vbox


Ignore:
Timestamp:
Jun 19, 2013 12:46:36 PM (11 years ago)
Author:
vboxsync
Message:

VMM/HMVMXR0: Reflect any exception to the guest if event delivery of that exception caused an EPT violation/misconfig. of APIC-access VM-exit.

In this case the VM-exit interruption-information field won't be valid because the resulting VM-exit is -not- an exception.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/err.h

    r46508 r46655  
    19071907/** Undefined VM exit code. */
    19081908#define VERR_VMX_UNDEFINED_EXIT_CODE                (-4019)
    1909 /** Resume guest execution after injecting a double-fault. */
    1910 #define VINF_VMX_DOUBLE_FAULT                       4020
    19111909/** VMPTRLD failed; possibly because of invalid VMCS launch-state. */
    19121910#define VERR_VMX_VMPTRLD_FAILED                     (-4021)
     
    19791977/** Invalid HM64ON32OP value.  */
    19801978#define VERR_HM_INVALID_HM64ON32OP                  (-4116)
     1979/** Resume guest execution after injecting a double-fault. */
     1980#define VINF_HM_DOUBLE_FAULT                        4117
    19811981/** @} */
    19821982
  • trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp

    r46596 r46655  
    47504750 * @returns VBox status code (informational error codes included).
    47514751 * @retval VINF_SUCCESS if we should continue handling the VM-exit.
    4752  * @retval VINF_VMX_DOUBLE_FAULT if a #DF condition was detected and we ought to
     4752 * @retval VINF_HM_DOUBLE_FAULT if a #DF condition was detected and we ought to
    47534753 *         continue execution of the guest which will delivery the #DF.
    47544754 * @retval VINF_EM_RESET if we detected a triple-fault condition.
     
    47854785        /* See Intel spec. 30.7.1.1 "Reflecting Exceptions to Guest Software". */
    47864786        VMXREFLECTXCPT enmReflect = VMXREFLECTXCPT_NONE;
    4787         if (uIntType == VMX_IDT_VECTORING_INFO_TYPE_HW_XCPT)
    4788         {
    4789             enmReflect = VMXREFLECTXCPT_XCPT;
     4787        if (VMX_EXIT_INTERRUPTION_INFO_IS_VALID(pVmxTransient->uExitIntrInfo))
     4788        {
     4789            if (uIntType == VMX_IDT_VECTORING_INFO_TYPE_HW_XCPT)
     4790            {
     4791                enmReflect = VMXREFLECTXCPT_XCPT;
    47904792#ifdef VBOX_STRICT
    4791             if (   hmR0VmxIsContributoryXcpt(uIdtVector)
    4792                 && uExitVector == X86_XCPT_PF)
     4793                if (   hmR0VmxIsContributoryXcpt(uIdtVector)
     4794                    && uExitVector == X86_XCPT_PF)
     4795                {
     4796                    Log4(("IDT: Contributory #PF uCR2=%#RX64\n", pMixedCtx->cr2));
     4797                }
     4798#endif
     4799                if (   uExitVector == X86_XCPT_PF
     4800                    && uIdtVector == X86_XCPT_PF)
     4801                {
     4802                    pVmxTransient->fVectoringPF = true;
     4803                    Log4(("IDT: Vectoring #PF uCR2=%#RX64\n", pMixedCtx->cr2));
     4804                }
     4805                else if (   (pVCpu->hm.s.vmx.u32XcptBitmap & HMVMX_CONTRIBUTORY_XCPT_MASK)
     4806                         && hmR0VmxIsContributoryXcpt(uExitVector)
     4807                         && (   hmR0VmxIsContributoryXcpt(uIdtVector)
     4808                             || uIdtVector == X86_XCPT_PF))
     4809                {
     4810                    enmReflect = VMXREFLECTXCPT_DF;
     4811                }
     4812                else if (uIdtVector == X86_XCPT_DF)
     4813                    enmReflect = VMXREFLECTXCPT_TF;
     4814            }
     4815            else if (   uIntType != VMX_IDT_VECTORING_INFO_TYPE_SW_INT
     4816                     && uIntType != VMX_IDT_VECTORING_INFO_TYPE_SW_XCPT
     4817                     && uIntType != VMX_IDT_VECTORING_INFO_TYPE_PRIV_SW_XCPT)
    47934818            {
    4794                 Log4(("IDT: Contributory #PF uCR2=%#RX64\n", pMixedCtx->cr2));
     4819                /*
     4820                 * Ignore software interrupts (INT n), software exceptions (#BP, #OF) and privileged software exception
     4821                 * (whatever they are) as they reoccur when restarting the instruction.
     4822                 */
     4823                enmReflect = VMXREFLECTXCPT_XCPT;
    47954824            }
    4796 #endif
    4797             if (   uExitVector == X86_XCPT_PF
    4798                 && uIdtVector == X86_XCPT_PF)
    4799             {
    4800                 pVmxTransient->fVectoringPF = true;
    4801                 Log4(("IDT: Vectoring #PF uCR2=%#RX64\n", pMixedCtx->cr2));
    4802             }
    4803             else if (   (pVCpu->hm.s.vmx.u32XcptBitmap & HMVMX_CONTRIBUTORY_XCPT_MASK)
    4804                      && hmR0VmxIsContributoryXcpt(uExitVector)
    4805                      && (   hmR0VmxIsContributoryXcpt(uIdtVector)
    4806                          || uIdtVector == X86_XCPT_PF))
    4807             {
    4808                 enmReflect = VMXREFLECTXCPT_DF;
    4809             }
    4810             else if (uIdtVector == X86_XCPT_DF)
    4811                 enmReflect = VMXREFLECTXCPT_TF;
    4812         }
    4813         else if (   uIntType != VMX_IDT_VECTORING_INFO_TYPE_SW_INT
    4814                  && uIntType != VMX_IDT_VECTORING_INFO_TYPE_SW_XCPT
    4815                  && uIntType != VMX_IDT_VECTORING_INFO_TYPE_PRIV_SW_XCPT)
     4825        }
     4826        else
    48164827        {
    48174828            /*
    4818              * Ignore software interrupts (INT n), software exceptions (#BP, #OF) and privileged software exception
    4819              * (whatever they are) as they reoccur when restarting the instruction.
     4829             * If event delivery caused an EPT violation/misconfig or APIC access VM-exit, then the VM-exit
     4830             * interruption-information will not be valid and we end up here. In such cases, it is sufficient to reflect the
     4831             * original exception to the guest after handling the VM-exit.
    48204832             */
    48214833            enmReflect = VMXREFLECTXCPT_XCPT;
     
    48394851                rc = VINF_SUCCESS;
    48404852                Log4(("IDT: Pending vectoring event %#RX64 Err=%#RX32\n", pVCpu->hm.s.Event.u64IntrInfo,
    4841                      pVCpu->hm.s.Event.u32ErrCode));
     4853                      pVCpu->hm.s.Event.u32ErrCode));
    48424854                break;
    48434855            }
     
    48464858            {
    48474859                hmR0VmxSetPendingXcptDF(pVCpu, pMixedCtx);
    4848                 rc = VINF_VMX_DOUBLE_FAULT;
     4860                rc = VINF_HM_DOUBLE_FAULT;
    48494861                Log4(("IDT: Pending vectoring #DF %#RX64 uIdtVector=%#x uExitVector=%#x\n", pVCpu->hm.s.Event.u64IntrInfo,
    4850                      uIdtVector, uExitVector));
     4862                      uIdtVector, uExitVector));
    48514863                break;
    48524864            }
     
    48544866            case VMXREFLECTXCPT_TF:
    48554867            {
     4868                rc = VINF_EM_RESET;
    48564869                Log4(("IDT: Pending vectoring triple-fault uIdt=%#x uExit=%#x\n", uIdtVector, uExitVector));
    4857                 rc = VINF_EM_RESET;
    48584870                break;
    48594871            }
     
    48644876        }
    48654877    }
    4866     Assert(rc == VINF_SUCCESS || rc == VINF_VMX_DOUBLE_FAULT || rc == VINF_EM_RESET);
     4878    Assert(rc == VINF_SUCCESS || rc == VINF_HM_DOUBLE_FAULT || rc == VINF_EM_RESET);
    48674879    return rc;
    48684880}
     
    72377249    /* If this VM-exit occurred while delivering an event through the guest IDT, handle it accordingly. */
    72387250    rc = hmR0VmxCheckExitDueToEventDelivery(pVCpu, pMixedCtx, pVmxTransient);
    7239     if (RT_UNLIKELY(rc == VINF_VMX_DOUBLE_FAULT))
     7251    if (RT_UNLIKELY(rc == VINF_HM_DOUBLE_FAULT))
    72407252    {
    72417253        STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatExitXcptNmi, y3);
     
    84008412    /* If this VM-exit occurred while delivering an event through the guest IDT, handle it accordingly. */
    84018413    int rc = hmR0VmxCheckExitDueToEventDelivery(pVCpu, pMixedCtx, pVmxTransient);
    8402     if (RT_UNLIKELY(rc == VINF_VMX_DOUBLE_FAULT))
     8414    if (RT_UNLIKELY(rc == VINF_HM_DOUBLE_FAULT))
    84038415        return VINF_SUCCESS;
    84048416    else if (RT_UNLIKELY(rc == VINF_EM_RESET))
     
    85548566    /* If this VM-exit occurred while delivering an event through the guest IDT, handle it accordingly. */
    85558567    int rc = hmR0VmxCheckExitDueToEventDelivery(pVCpu, pMixedCtx, pVmxTransient);
    8556     if (RT_UNLIKELY(rc == VINF_VMX_DOUBLE_FAULT))
     8568    if (RT_UNLIKELY(rc == VINF_HM_DOUBLE_FAULT))
    85578569        return VINF_SUCCESS;
    85588570    else if (RT_UNLIKELY(rc == VINF_EM_RESET))
     
    86078619    /* If this VM-exit occurred while delivering an event through the guest IDT, handle it accordingly. */
    86088620    int rc = hmR0VmxCheckExitDueToEventDelivery(pVCpu, pMixedCtx, pVmxTransient);
    8609     if (RT_UNLIKELY(rc == VINF_VMX_DOUBLE_FAULT))
     8621    if (RT_UNLIKELY(rc == VINF_HM_DOUBLE_FAULT))
    86108622        return VINF_SUCCESS;
    86118623    else if (RT_UNLIKELY(rc == VINF_EM_RESET))
     
    90899101    if (pVM->hm.s.fNestedPaging)
    90909102    {
     9103        pVCpu->hm.s.Event.fPending = false;                  /* In case it's a contributory or vectoring #PF. */
    90919104        if (RT_LIKELY(!pVmxTransient->fVectoringPF))
    90929105        {
    9093             pVCpu->hm.s.Event.fPending = false;                  /* In case it's a contributory #PF. */
    90949106            pMixedCtx->cr2 = pVmxTransient->uExitQualification;  /* Update here in case we go back to ring-3 before injection. */
    90959107            hmR0VmxSetPendingEvent(pVCpu, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(pVmxTransient->uExitIntrInfo),
    90969108                                   0 /* cbInstr */, pVmxTransient->uExitIntrErrorCode, pVmxTransient->uExitQualification);
    9097             STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestPF);
    90989109        }
    90999110        else
    91009111        {
    91019112            /* A guest page-fault occurred during delivery of a page-fault. Inject #DF. */
    9102             pVCpu->hm.s.Event.fPending = false;     /* A vectoring #PF. */
    91039113            hmR0VmxSetPendingXcptDF(pVCpu, pMixedCtx);
    91049114            Log4(("Pending #DF due to vectoring #PF. NP\n"));
     
    91499159            /* A guest page-fault occurred during delivery of a page-fault. Inject #DF. */
    91509160            TRPMResetTrap(pVCpu);
    9151             pVCpu->hm.s.Event.fPending = false;     /* Clear pending #PF for replace it with #DF. */
     9161            pVCpu->hm.s.Event.fPending = false;     /* Clear pending #PF to replace it with #DF. */
    91529162            hmR0VmxSetPendingXcptDF(pVCpu, pMixedCtx);
    91539163            Log4(("#PF: Pending #DF due to vectoring #PF\n"));
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