VirtualBox

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


Ignore:
Timestamp:
May 3, 2013 9:30:33 AM (12 years ago)
Author:
vboxsync
Message:

VMM/HMVMXR0: Avoid syncing TRPM and Pending HM events back and forth when teasing to enter VT-x but we keep returning to ring-3 for one reason or another. Now do the actual conversion later during event injection when, currently, it's too late to go back to ring-3.

File:
1 edited

Legend:

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

    r45887 r45888  
    54965496 *
    54975497 * @param   pVCpu           Pointer to the VMCPU.
    5498  * @param   pCtx            Pointer to the guest-CPU context.
    5499  */
    5500 static void hmR0VmxUpdatePendingEvent(PVMCPU pVCpu, PCPUMCTX pCtx)
    5501 {
    5502     if (!TRPMHasTrap(pVCpu))
    5503     {
    5504         Assert(!pVCpu->hm.s.Event.fPending);
    5505         return;
    5506     }
     5498 */
     5499static void hmR0VmxTRPMTrapToPendingEvent(PVMCPU pVCpu)
     5500{
     5501    Assert(TRPMHasTrap(pVCpu));
     5502    Assert(!pVCpu->hm.s.Event.fPending);
    55075503
    55085504    uint8_t     uVector;
     
    55705566 * @param   pvCpu           Pointer to the VMCPU.
    55715567 */
    5572 static void hmR0VmxUpdateTRPM(PVMCPU pVCpu)
    5573 {
    5574     if (pVCpu->hm.s.Event.fPending)
    5575     {
    5576         uint32_t uVectorType     = VMX_IDT_VECTORING_INFO_TYPE(pVCpu->hm.s.Event.u64IntrInfo);
    5577         uint32_t uVector         = VMX_IDT_VECTORING_INFO_VECTOR(pVCpu->hm.s.Event.u64IntrInfo);
    5578         bool     fErrorCodeValid = !!VMX_IDT_VECTORING_INFO_ERROR_CODE_IS_VALID(pVCpu->hm.s.Event.u64IntrInfo);
    5579         uint32_t uErrorCode      = pVCpu->hm.s.Event.u32ErrCode;
    5580 
    5581         /* If a trap was already pending, we did something wrong! */
    5582         Assert(TRPMQueryTrap(pVCpu, NULL /* pu8TrapNo */, NULL /* pEnmType */) == VERR_TRPM_NO_ACTIVE_TRAP);
    5583 
    5584         TRPMEVENT enmTrapType;
    5585         switch (uVectorType)
    5586         {
    5587             case VMX_IDT_VECTORING_INFO_TYPE_EXT_INT:
    5588             case VMX_IDT_VECTORING_INFO_TYPE_NMI:
    5589                enmTrapType = TRPM_HARDWARE_INT;
    5590                break;
    5591             case VMX_IDT_VECTORING_INFO_TYPE_SW_INT:
    5592                 enmTrapType = TRPM_SOFTWARE_INT;
    5593                 break;
    5594             case VMX_IDT_VECTORING_INFO_TYPE_PRIV_SW_XCPT:
    5595             case VMX_IDT_VECTORING_INFO_TYPE_SW_XCPT:      /* #BP and #OF */
    5596             case VMX_IDT_VECTORING_INFO_TYPE_HW_XCPT:
    5597                 enmTrapType = TRPM_TRAP;
    5598                 break;
    5599             default:
    5600                 AssertMsgFailed(("Invalid trap type %#x\n", uVectorType));
    5601                 enmTrapType = TRPM_32BIT_HACK;
    5602                 break;
    5603         }
    5604 
    5605         Log(("Converting pending HM event to TRPM trap uVector=%#x enmTrapType=%d\n", uVector, enmTrapType));
    5606         int rc = TRPMAssertTrap(pVCpu, uVector, enmTrapType);
    5607         AssertRC(rc);
    5608 
    5609         if (fErrorCodeValid)
    5610             TRPMSetErrorCode(pVCpu, uErrorCode);
    5611         if (   uVectorType == VMX_IDT_VECTORING_INFO_TYPE_HW_XCPT
    5612             && uVector == X86_XCPT_PF)
    5613         {
    5614             TRPMSetFaultAddress(pVCpu, pVCpu->hm.s.Event.GCPtrFaultAddress);
    5615         }
    5616         else if (   uVectorType == VMX_IDT_VECTORING_INFO_TYPE_SW_INT
    5617                  || uVectorType == VMX_IDT_VECTORING_INFO_TYPE_SW_XCPT
    5618                  || uVectorType == VMX_IDT_VECTORING_INFO_TYPE_PRIV_SW_XCPT)
    5619         {
    5620             AssertMsg(   uVectorType == VMX_IDT_VECTORING_INFO_TYPE_SW_INT
    5621                       || (uVector == X86_XCPT_BP || uVector == X86_XCPT_OF),
    5622                       ("Invalid vector: uVector=%#x uVectorType=%#x\n", uVector, uVectorType));
    5623             TRPMSetInstrLength(pVCpu, pVCpu->hm.s.Event.cbInstr);
    5624         }
    5625         pVCpu->hm.s.Event.fPending = false;
    5626     }
     5568static void hmR0VmxPendingEventToTRPMTrap(PVMCPU pVCpu)
     5569{
     5570    Assert(pVCpu->hm.s.Event.fPending);
     5571
     5572    uint32_t uVectorType     = VMX_IDT_VECTORING_INFO_TYPE(pVCpu->hm.s.Event.u64IntrInfo);
     5573    uint32_t uVector         = VMX_IDT_VECTORING_INFO_VECTOR(pVCpu->hm.s.Event.u64IntrInfo);
     5574    bool     fErrorCodeValid = !!VMX_IDT_VECTORING_INFO_ERROR_CODE_IS_VALID(pVCpu->hm.s.Event.u64IntrInfo);
     5575    uint32_t uErrorCode      = pVCpu->hm.s.Event.u32ErrCode;
     5576
     5577    /* If a trap was already pending, we did something wrong! */
     5578    Assert(TRPMQueryTrap(pVCpu, NULL /* pu8TrapNo */, NULL /* pEnmType */) == VERR_TRPM_NO_ACTIVE_TRAP);
     5579
     5580    TRPMEVENT enmTrapType;
     5581    switch (uVectorType)
     5582    {
     5583        case VMX_IDT_VECTORING_INFO_TYPE_EXT_INT:
     5584        case VMX_IDT_VECTORING_INFO_TYPE_NMI:
     5585           enmTrapType = TRPM_HARDWARE_INT;
     5586           break;
     5587        case VMX_IDT_VECTORING_INFO_TYPE_SW_INT:
     5588            enmTrapType = TRPM_SOFTWARE_INT;
     5589            break;
     5590        case VMX_IDT_VECTORING_INFO_TYPE_PRIV_SW_XCPT:
     5591        case VMX_IDT_VECTORING_INFO_TYPE_SW_XCPT:      /* #BP and #OF */
     5592        case VMX_IDT_VECTORING_INFO_TYPE_HW_XCPT:
     5593            enmTrapType = TRPM_TRAP;
     5594            break;
     5595        default:
     5596            AssertMsgFailed(("Invalid trap type %#x\n", uVectorType));
     5597            enmTrapType = TRPM_32BIT_HACK;
     5598            break;
     5599    }
     5600
     5601    Log(("Converting pending HM event to TRPM trap uVector=%#x enmTrapType=%d\n", uVector, enmTrapType));
     5602    int rc = TRPMAssertTrap(pVCpu, uVector, enmTrapType);
     5603    AssertRC(rc);
     5604
     5605    if (fErrorCodeValid)
     5606        TRPMSetErrorCode(pVCpu, uErrorCode);
     5607    if (   uVectorType == VMX_IDT_VECTORING_INFO_TYPE_HW_XCPT
     5608        && uVector == X86_XCPT_PF)
     5609    {
     5610        TRPMSetFaultAddress(pVCpu, pVCpu->hm.s.Event.GCPtrFaultAddress);
     5611    }
     5612    else if (   uVectorType == VMX_IDT_VECTORING_INFO_TYPE_SW_INT
     5613             || uVectorType == VMX_IDT_VECTORING_INFO_TYPE_SW_XCPT
     5614             || uVectorType == VMX_IDT_VECTORING_INFO_TYPE_PRIV_SW_XCPT)
     5615    {
     5616        AssertMsg(   uVectorType == VMX_IDT_VECTORING_INFO_TYPE_SW_INT
     5617                  || (uVector == X86_XCPT_BP || uVector == X86_XCPT_OF),
     5618                  ("Invalid vector: uVector=%#x uVectorType=%#x\n", uVector, uVectorType));
     5619        TRPMSetInstrLength(pVCpu, pVCpu->hm.s.Event.cbInstr);
     5620    }
     5621    pVCpu->hm.s.Event.fPending = false;
    56275622}
    56285623
     
    57205715
    57215716    /* We need to do this only while truly exiting the "inner loop" back to ring-3 and -not- for any longjmp to ring3. */
    5722     hmR0VmxUpdateTRPM(pVCpu);
     5717    if (pVCpu->hm.s.Event.fPending)
     5718    {
     5719        hmR0VmxPendingEventToTRPMTrap(pVCpu);
     5720        Assert(!pVCpu->hm.s.Event.fPending);
     5721    }
    57235722
    57245723    /* Sync. the guest state. */
     
    65286527     */
    65296528    /** @todo Rework event evaluation and injection to be complete separate. */
     6529    if (TRPMHasTrap(pVCpu))
     6530        hmR0VmxTRPMTrapToPendingEvent(pVCpu);
     6531
    65306532    rc = hmR0VmxInjectPendingEvent(pVCpu, pMixedCtx);
    65316533    AssertRCReturn(rc, rc);
     
    67516753    int          rc     = VERR_INTERNAL_ERROR_5;
    67526754    uint32_t     cLoops = 0;
    6753     hmR0VmxUpdatePendingEvent(pVCpu, pCtx);
    67546755
    67556756    for (;; cLoops++)
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