VirtualBox

Changeset 50275 in vbox for trunk


Ignore:
Timestamp:
Jan 29, 2014 5:27:37 PM (11 years ago)
Author:
vboxsync
Message:

VMM/HMVMXR0: Fix single-stepping in real-on-v86 mode for certain emulated instructions. Added todo for the rest.

File:
1 edited

Legend:

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

    r50271 r50275  
    70157015
    70167016/**
     7017 * Sets a pending-debug exception to be delivered to the guest if the guest is
     7018 * single-stepping.
     7019 *
     7020 * @param   pVCpu           Pointer to the VMCPU.
     7021 * @param   pMixedCtx       Pointer to the guest-CPU context. The data may be
     7022 *                          out-of-sync. Make sure to update the required fields
     7023 *                          before using them.
     7024 */
     7025DECLINLINE(void) hmR0VmxSetPendingDebugXcpt(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
     7026{
     7027    HMVMXCPU_GST_IS_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_RFLAGS);
     7028    if (pMixedCtx->eflags.Bits.u1TF)    /* We don't have any IA32_DEBUGCTL MSR for guests. Treat as all bits 0. */
     7029    {
     7030        int rc = VMXWriteVmcs32(VMX_VMCS_GUEST_PENDING_DEBUG_EXCEPTIONS, VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_BS);
     7031        AssertRC(rc);
     7032    }
     7033}
     7034
     7035
     7036/**
    70177037 * Injects any pending events into the guest if the guest is in a state to
    70187038 * receive them.
     
    70857105            && !DBGFIsStepping(pVCpu))
    70867106        {
     7107            /*
     7108             * The pending-debug exceptions field is cleared on all VM-exits except VMX_EXIT_TPR_BELOW_THRESHOLD,
     7109             * VMX_EXIT_MTF, VMX_EXIT_APIC_WRITE and VMX_EXIT_VIRTUALIZED_EOI.
     7110             * See Intel spec. 27.3.4 "Saving Non-Register State".
     7111             */
    70877112            int rc2 = hmR0VmxSaveGuestRflags(pVCpu, pMixedCtx);
    70887113            AssertRCReturn(rc2, rc2);
    7089             if (pMixedCtx->eflags.Bits.u1TF)    /* We don't have any IA32_DEBUGCTL MSR for guests. Treat as all bits 0. */
    7090             {
    7091                 /*
    7092                  * The pending-debug exceptions field is cleared on all VM-exits except VMX_EXIT_TPR_BELOW_THRESHOLD,
    7093                  * VMX_EXIT_MTF, VMX_EXIT_APIC_WRITE and VMX_EXIT_VIRTUALIZED_EOI.
    7094                  * See Intel spec. 27.3.4 "Saving Non-Register State".
    7095                  */
    7096                 rc2 = VMXWriteVmcs32(VMX_VMCS_GUEST_PENDING_DEBUG_EXCEPTIONS, VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_BS);
    7097                 AssertRCReturn(rc2, rc2);
    7098             }
     7114            hmR0VmxSetPendingDebugXcpt(pVCpu, pMixedCtx);
    70997115        }
    71007116        else if (pMixedCtx->eflags.Bits.u1TF)
     
    86198635     * See Intel spec. 32.2.1 "Debug Exceptions".
    86208636     */
    8621     if (pMixedCtx->eflags.Bits.u1TF)
    8622     {
    8623         rc = VMXWriteVmcs32(VMX_VMCS_GUEST_PENDING_DEBUG_EXCEPTIONS, VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_BS);
    8624         AssertRCReturn(rc, rc);
    8625     }
     8637    hmR0VmxSetPendingDebugXcpt(pVCpu, pMixedCtx);
    86268638
    86278639    return rc;
     
    1113211144                pMixedCtx->rip += pDis->cbInstr;
    1113311145                HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_RIP | HM_CHANGED_GUEST_RFLAGS);
     11146                hmR0VmxSetPendingDebugXcpt(pVCpu, pMixedCtx);
    1113411147                STAM_COUNTER_INC(&pVCpu->hm.s.StatExitCli);
    1113511148                break;
     
    1114311156                Assert(VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS));
    1114411157                HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_RIP | HM_CHANGED_GUEST_RFLAGS);
     11158                hmR0VmxSetPendingDebugXcpt(pVCpu, pMixedCtx);
    1114511159                STAM_COUNTER_INC(&pVCpu->hm.s.StatExitSti);
    1114611160                break;
     
    1116111175                uint32_t cbParm = 0;
    1116211176                uint32_t uMask  = 0;
     11177                bool     fAlreadyStepping = RT_BOOL(pMixedCtx->eflags.Bits.u1TF);
    1116311178                if (pDis->fPrefix & DISPREFIX_OPSIZE)
    1116411179                {
     
    1119511210                pMixedCtx->esp              &= uMask;
    1119611211                pMixedCtx->rip              += pDis->cbInstr;
    11197 
    1119811212                HMCPU_CF_SET(pVCpu,   HM_CHANGED_GUEST_RIP
    1119911213                                      | HM_CHANGED_GUEST_RSP
    1120011214                                      | HM_CHANGED_GUEST_RFLAGS);
     11215
     11216                /* Only generate a debug execption after POPF if the guest is already stepping over POPF and
     11217                   POPF restores EFLAGS.TF. The CPU looks at the EFLAGS.TF after the instruction is done manipulating it. */
     11218                if (   fAlreadyStepping
     11219                    && pMixedCtx->eflags.Bits.u1TF)
     11220                {
     11221                    hmR0VmxSetPendingDebugXcpt(pVCpu, pMixedCtx);
     11222                }
     11223
    1120111224                STAM_COUNTER_INC(&pVCpu->hm.s.StatExitPopf);
    1120211225                break;
     
    1124311266                pMixedCtx->rip               += pDis->cbInstr;
    1124411267                HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_RIP | HM_CHANGED_GUEST_RSP);
     11268                hmR0VmxSetPendingDebugXcpt(pVCpu, pMixedCtx);
    1124511269                STAM_COUNTER_INC(&pVCpu->hm.s.StatExitPushf);
    1124611270                break;
     
    1125411278                uint32_t uMask      = 0xffff;
    1125511279                uint16_t aIretFrame[3];
     11280                bool     fAlreadyStepping = RT_BOOL(pMixedCtx->eflags.Bits.u1TF);
    1125611281                if (pDis->fPrefix & (DISPREFIX_OPSIZE | DISPREFIX_ADDRSIZE))
    1125711282                {
     
    1128011305                                    | HM_CHANGED_GUEST_RSP
    1128111306                                    | HM_CHANGED_GUEST_RFLAGS);
     11307
     11308                /* Only generate a debug execption after IRET if the guest is already stepping over IRET and
     11309                   IRET restores EFLAGS.TF. The CPU looks at the EFLAGS.TF after the instruction is done manipulating it. */
     11310                if (   fAlreadyStepping
     11311                    && pMixedCtx->eflags.Bits.u1TF)
     11312                {
     11313                    hmR0VmxSetPendingDebugXcpt(pVCpu, pMixedCtx);
     11314                }
     11315
    1128211316                Log4(("IRET %#RX32 to %04x:%x\n", GCPtrStack, pMixedCtx->cs.Sel, pMixedCtx->ip));
    1128311317                STAM_COUNTER_INC(&pVCpu->hm.s.StatExitIret);
     
    1128911323                uint16_t uVector = pDis->Param1.uValue & 0xff;
    1129011324                hmR0VmxSetPendingIntN(pVCpu, pMixedCtx, uVector, pDis->cbInstr);
     11325                /* INT clears EFLAGS.TF, we mustn't set any pending debug exceptions here. */
    1129111326                STAM_COUNTER_INC(&pVCpu->hm.s.StatExitInt);
    1129211327                break;
     
    1129811333                {
    1129911334                    hmR0VmxSetPendingXcptOF(pVCpu, pMixedCtx, pDis->cbInstr);
     11335                    /* INTO clears EFLAGS.TF, we mustn't set any pending debug exceptions here. */
    1130011336                    STAM_COUNTER_INC(&pVCpu->hm.s.StatExitInt);
    1130111337                }
     
    1130911345                rc = VBOXSTRICTRC_VAL(rc2);
    1131011346                HMCPU_CF_SET(pVCpu, HM_CHANGED_ALL_GUEST);
     11347                /** @todo We have to set pending-debug exceptions here when the guest is
     11348                 *        single-stepping depending on the instruction that was interpreted. */
    1131111349                Log4(("#GP rc=%Rrc\n", rc));
    1131211350                break;
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