VirtualBox

Changeset 47718 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Aug 14, 2013 10:33:22 AM (11 years ago)
Author:
vboxsync
Message:

More single stepping work.

Location:
trunk/src/VBox/VMM
Files:
3 edited

Legend:

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

    r47684 r47718  
    9898
    9999
    100 /** @name Macro for checking and returning from the using function for
    101  *        #VMEXIT intercepts that maybe caused during delivering of another
    102  *        event in the guest. */
     100/** Macro for checking and returning from the using function for
     101 * \#VMEXIT intercepts that maybe caused during delivering of another
     102 * event in the guest. */
    103103#define HMSVM_CHECK_EXIT_DUE_TO_EVENT_DELIVERY() \
    104104    do \
     
    110110            return rc; \
    111111    } while (0)
    112 /** @} */
    113 
    114 
    115 /**
    116  * @name Exception bitmap mask for all contributory exceptions.
     112
     113/** Macro for upgrading a @a a_rc to VINF_EM_DBG_STEPPED after emulating an
     114 * instruction that exited. */
     115#define HMSVM_CHECK_SINGLE_STEP(a_pVCpu, a_rc) \
     116    do { \
     117        if ((a_pVCpu)->hm.s.fSingleInstruction && (a_rc) == VINF_SUCCESS) \
     118            (a_rc) = VINF_EM_DBG_STEPPED; \
     119    } while (0)
     120
     121
     122/** Exception bitmap mask for all contributory exceptions.
    117123 *
    118124 * Page fault is deliberately excluded here as it's conditional as to whether
     
    121127#define HMSVM_CONTRIBUTORY_XCPT_MASK  (  RT_BIT(X86_XCPT_GP) | RT_BIT(X86_XCPT_NP) | RT_BIT(X86_XCPT_SS) | RT_BIT(X86_XCPT_TS) \
    122128                                       | RT_BIT(X86_XCPT_DE))
    123 /** @} */
    124129
    125130
     
    13351340    if (fStepping)
    13361341    {
     1342        pVCpu->hm.s.fClearTrapFlag = true;
    13371343        pVmcb->guest.u64RFlags |= X86_EFL_TF;
    13381344        fInterceptDB = true;
     
    16501656              pVM, pVCpu, pVCpu->hm.s.fContextUseFlags));
    16511657
    1652     Log4(("Load: CS:RIP=%04x:%#RX64\n", pCtx->cs.Sel, pCtx->rip));
     1658    Log4(("Load: CS:RIP=%04x:%RX64 EFL=%#x SS:RSP=%04x:%RX64\n", pCtx->cs.Sel, pCtx->rip, pCtx->eflags.u, pCtx->ss, pCtx->rsp));
    16531659
    16541660    STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatLoadGuestState, x);
     
    18951901
    18961902/**
     1903 * Take necessary actions before going back to ring-3.
     1904 *
    18971905 * An action requires us to go back to ring-3. This function does the necessary
    18981906 * steps before we can safely return to ring-3. This is not the same as longjmps
     
    19471955    else
    19481956        pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_HOST_CONTEXT | HM_CHANGED_ALL_GUEST;
     1957
     1958    /* Make sure we've undo the trap flag if we tried to single step something. */
     1959    if (pVCpu->hm.s.fClearTrapFlag)
     1960    {
     1961        pVCpu->hm.s.fClearTrapFlag = false;
     1962        pCtx->eflags.Bits.u1TF = 0;
     1963    }
    19491964
    19501965    STAM_COUNTER_INC(&pVCpu->hm.s.StatSwitchExitToR3);
     
    36253640    hmR0SvmUpdateRip(pVCpu, pCtx, 2);
    36263641    STAM_COUNTER_INC(&pVCpu->hm.s.StatExitWbinvd);
    3627     return VINF_SUCCESS;
     3642    int rc = VINF_SUCCESS;
     3643    HMSVM_CHECK_SINGLE_STEP(pVCpu, rc);
     3644    return rc;
    36283645}
    36293646
     
    36383655    hmR0SvmUpdateRip(pVCpu, pCtx, 2);
    36393656    STAM_COUNTER_INC(&pVCpu->hm.s.StatExitInvd);
    3640     return VINF_SUCCESS;
     3657    int rc = VINF_SUCCESS;
     3658    HMSVM_CHECK_SINGLE_STEP(pVCpu, rc);
     3659    return rc;
    36413660}
    36423661
     
    36513670    int rc = EMInterpretCpuId(pVM, pVCpu, CPUMCTX2CORE(pCtx));
    36523671    if (RT_LIKELY(rc == VINF_SUCCESS))
     3672    {
    36533673        hmR0SvmUpdateRip(pVCpu, pCtx, 2);
     3674        HMSVM_CHECK_SINGLE_STEP(pVCpu, rc);
     3675    }
    36543676    else
    36553677    {
     
    36743696        hmR0SvmUpdateRip(pVCpu, pCtx, 2);
    36753697        pSvmTransient->fUpdateTscOffsetting = true;
     3698
     3699        /* Single step check. */
     3700        HMSVM_CHECK_SINGLE_STEP(pVCpu, rc);
    36763701    }
    36773702    else
     
    36963721        hmR0SvmUpdateRip(pVCpu, pCtx, 3);
    36973722        pSvmTransient->fUpdateTscOffsetting = true;
     3723        HMSVM_CHECK_SINGLE_STEP(pVCpu, rc);
    36983724    }
    36993725    else
     
    37153741    int rc = EMInterpretRdpmc(pVCpu->CTX_SUFF(pVM), pVCpu, CPUMCTX2CORE(pCtx));
    37163742    if (RT_LIKELY(rc == VINF_SUCCESS))
     3743    {
    37173744        hmR0SvmUpdateRip(pVCpu, pCtx, 2);
     3745        HMSVM_CHECK_SINGLE_STEP(pVCpu, rc);
     3746    }
    37183747    else
    37193748    {
     
    37393768    STAM_COUNTER_INC(&pVCpu->hm.s.StatExitInvlpg);
    37403769    Assert(rc == VINF_SUCCESS || rc == VERR_EM_INTERPRETER);
     3770    HMSVM_CHECK_SINGLE_STEP(pVCpu, rc);
    37413771    return rc;
    37423772}
     
    37513781    hmR0SvmUpdateRip(pVCpu, pCtx, 1);
    37523782    int rc = EMShouldContinueAfterHalt(pVCpu, pCtx) ? VINF_SUCCESS : VINF_EM_HALT;
     3783    HMSVM_CHECK_SINGLE_STEP(pVCpu, rc);
    37533784    STAM_COUNTER_INC(&pVCpu->hm.s.StatExitHlt);
    37543785    return rc;
     
    37643795    int rc = EMInterpretMonitor(pVCpu->CTX_SUFF(pVM), pVCpu, CPUMCTX2CORE(pCtx));
    37653796    if (RT_LIKELY(rc == VINF_SUCCESS))
     3797    {
    37663798        hmR0SvmUpdateRip(pVCpu, pCtx, 3);
     3799        HMSVM_CHECK_SINGLE_STEP(pVCpu, rc);
     3800    }
    37673801    else
    37683802    {
     
    37933827            rc = VINF_SUCCESS;
    37943828        }
     3829        HMSVM_CHECK_SINGLE_STEP(pVCpu, rc);
    37953830    }
    37963831    else
     
    38333868    Assert((pSvmTransient->u64ExitCode - SVM_EXIT_READ_CR0) <= 15);
    38343869    STAM_COUNTER_INC(&pVCpu->hm.s.StatExitCRxRead[pSvmTransient->u64ExitCode - SVM_EXIT_READ_CR0]);
     3870    HMSVM_CHECK_SINGLE_STEP(pVCpu, rc);
    38353871    return rc;
    38363872}
     
    38743910                break;
    38753911        }
     3912        HMSVM_CHECK_SINGLE_STEP(pVCpu, rc);
    38763913    }
    38773914    else
     
    39193956            }
    39203957            hmR0SvmUpdateRip(pVCpu, pCtx, 2);
    3921             return VINF_SUCCESS;
     3958            rc = VINF_SUCCESS;
     3959            HMSVM_CHECK_SINGLE_STEP(pVCpu, rc);
     3960            return rc;
    39223961        }
    39233962
     
    39263965            rc = EMInterpretWrmsr(pVM, pVCpu, CPUMCTX2CORE(pCtx));
    39273966            if (RT_LIKELY(rc == VINF_SUCCESS))
     3967            {
    39283968                pCtx->rip = pVmcb->ctrl.u64NextRIP;
     3969                HMSVM_CHECK_SINGLE_STEP(pVCpu, rc);
     3970            }
    39293971            else
    39303972                AssertMsg(rc == VERR_EM_INTERPRETER, ("hmR0SvmExitMsr: EMInterpretWrmsr failed rc=%Rrc\n", rc));
     
    39323974        else
    39333975        {
    3934             VBOXSTRICTRC rcStrict = EMInterpretInstruction(pVCpu, CPUMCTX2CORE(pCtx), 0 /* pvFault */);
    3935             rc = VBOXSTRICTRC_VAL(rcStrict);
     3976            rc = VBOXSTRICTRC_TODO(EMInterpretInstruction(pVCpu, CPUMCTX2CORE(pCtx), 0 /* pvFault */));
    39363977            if (RT_UNLIKELY(rc != VINF_SUCCESS))
    39373978                AssertMsg(rc == VERR_EM_INTERPRETER, ("hmR0SvmExitMsr: WrMsr. EMInterpretInstruction failed rc=%Rrc\n", rc));
    39383979            /* RIP updated by EMInterpretInstruction(). */
     3980            HMSVM_CHECK_SINGLE_STEP(pVCpu, rc);
    39393981        }
    39403982
     
    39634005            rc = EMInterpretRdmsr(pVM, pVCpu, CPUMCTX2CORE(pCtx));
    39644006            if (RT_LIKELY(rc == VINF_SUCCESS))
     4007            {
    39654008                pCtx->rip = pVmcb->ctrl.u64NextRIP;
     4009                HMSVM_CHECK_SINGLE_STEP(pVCpu, rc);
     4010            }
    39664011            else
    39674012                AssertMsg(rc == VERR_EM_INTERPRETER, ("hmR0SvmExitMsr: EMInterpretRdmsr failed rc=%Rrc\n", rc));
     
    39694014        else
    39704015        {
    3971             VBOXSTRICTRC rcStrict = EMInterpretInstruction(pVCpu, CPUMCTX2CORE(pCtx), 0);
    3972             rc = VBOXSTRICTRC_VAL(rcStrict);
     4016            rc = VBOXSTRICTRC_TODO(EMInterpretInstruction(pVCpu, CPUMCTX2CORE(pCtx), 0));
    39734017            if (RT_UNLIKELY(rc != VINF_SUCCESS))
    39744018                AssertMsg(rc == VERR_EM_INTERPRETER, ("hmR0SvmExitMsr: RdMsr. EMInterpretInstruction failed rc=%Rrc\n", rc));
    39754019            /* RIP updated by EMInterpretInstruction(). */
     4020            HMSVM_CHECK_SINGLE_STEP(pVCpu, rc);
    39764021        }
    39774022    }
     
    40284073        /** @todo CPUM should set this flag! */
    40294074        pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_GUEST_DEBUG;
     4075        HMSVM_CHECK_SINGLE_STEP(pVCpu, rc);
    40304076    }
    40314077    else
     
    41714217                rcStrict = rcStrict2;
    41724218        }
     4219
     4220        HMSVM_CHECK_SINGLE_STEP(pVCpu, rcStrict);
    41734221    }
    41744222
     
    43674415
    43684416    int rc = hmR0SvmEmulateMovTpr(pVCpu->CTX_SUFF(pVM), pVCpu, pCtx);
    4369     if (RT_UNLIKELY(rc != VINF_SUCCESS))
     4417    if (RT_LIKELY(rc == VINF_SUCCESS))
     4418        HMSVM_CHECK_SINGLE_STEP(pVCpu, rc);
     4419    else
    43704420        hmR0SvmSetPendingXcptUD(pVCpu);
    43714421    return VINF_SUCCESS;
     
    45544604
    45554605    /* If we set the trap flag above, we have to clear it. */
    4556     /** @todo HM should remember what it does and possibly do this elsewhere! */
    4557     if (pVCpu->hm.s.fSingleInstruction || DBGFIsStepping(pVCpu))
     4606    if (pVCpu->hm.s.fClearTrapFlag)
     4607    {
     4608        pVCpu->hm.s.fClearTrapFlag = false;
    45584609        pCtx->eflags.Bits.u1TF = 0;
     4610    }
    45594611
    45604612    /* This can be a fault-type #DB (instruction breakpoint) or a trap-type #DB (data breakpoint). However, for both cases
  • trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp

    r47687 r47718  
    33363336        else
    33373337        {
     3338            pMixedCtx->eflags.u32 |= X86_EFL_TF;
     3339            pVCpu->hm.s.fClearTrapFlag = true;
     3340            pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_GUEST_RFLAGS;
    33383341            fInterceptDB = true;
    3339             pMixedCtx->eflags.u32 |= X86_EFL_TF;
    3340             pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_GUEST_RFLAGS;
    33413342        }
    33423343    }
     
    60816082
    60826083/**
     6084 * Take necessary actions before going back to ring-3.
     6085 *
    60836086 * An action requires us to go back to ring-3. This function does the necessary
    60846087 * steps before we can safely return to ring-3. This is not the same as longjmps
     
    61516154    else
    61526155        pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_HOST_CONTEXT | HM_CHANGED_ALL_GUEST;
     6156
     6157    /* Make sure we've undo the trap flag if we tried to single step something. */
     6158    if (pVCpu->hm.s.fClearTrapFlag)
     6159    {
     6160        pVCpu->hm.s.fClearTrapFlag = false;
     6161        pMixedCtx->eflags.Bits.u1TF = 0;
     6162    }
    61536163
    61546164    STAM_COUNTER_INC(&pVCpu->hm.s.StatSwitchExitToR3);
     
    96539663    AssertRCReturn(rc, rc);
    96549664
    9655     /* If we sat the trap flag above, we have to clear it. */ /** @todo HM should remember what it does and possibly do this elsewhere! */
    9656     if (   (pVCpu->hm.s.fSingleInstruction || DBGFIsStepping(pVCpu))
    9657         && !(pVCpu->CTX_SUFF(pVM)->hm.s.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_MONITOR_TRAP_FLAG))
     9665    /* If we sat the trap flag above, we have to clear it. */
     9666    if (pVCpu->hm.s.fClearTrapFlag)
     9667    {
     9668        pVCpu->hm.s.fClearTrapFlag = false;
    96589669        pMixedCtx->eflags.Bits.u1TF = 0;
     9670    }
    96599671
    96609672    /* Refer Intel spec. Table 27-1. "Exit Qualifications for debug exceptions" for the format. */
  • trunk/src/VBox/VMM/include/HMInternal.h

    r47652 r47718  
    524524    /** Whether we're executing a single instruction. */
    525525    bool                        fSingleInstruction;
    526     uint8_t                     abAlignment[3];
     526    /** Set if we need to clear the trap flag because of single stepping. */
     527    bool                        fClearTrapFlag;
     528    uint8_t                     abAlignment[2];
    527529
    528530    /** World switch exit counter. */
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