VirtualBox

Changeset 97694 in vbox for trunk/src/VBox/VMM/VMMAll


Ignore:
Timestamp:
Nov 28, 2022 10:08:14 PM (2 years ago)
Author:
vboxsync
Message:

VMM/IEM: Added support for hardware instruction breakpoints (DRx). Corrected some DR6 updating for single stepping. bugref:9898

Location:
trunk/src/VBox/VMM/VMMAll
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAll.cpp

    r97662 r97694  
    175175
    176176/**
     177 * Slow path of iemInitDecoder() and iemInitExec() that checks what kind of
     178 * breakpoints are enabled.
     179 *
     180 * @param   pVCpu               The cross context virtual CPU structure of the
     181 *                              calling thread.
     182 */
     183void iemInitPendingBreakpointsSlow(PVMCPUCC pVCpu)
     184{
     185    /*
     186     * Process guest breakpoints.
     187     */
     188#define PROCESS_ONE_BP(a_fDr7, a_iBp) do { \
     189        if (a_fDr7 & X86_DR7_L_G(a_iBp)) \
     190        { \
     191            switch (X86_DR7_GET_RW(a_fDr7, a_iBp)) \
     192            { \
     193                case X86_DR7_RW_EO: \
     194                    pVCpu->iem.s.fPendingInstructionBreakpoints = true; \
     195                    break; \
     196                case X86_DR7_RW_WO: \
     197                case X86_DR7_RW_RW: \
     198                    pVCpu->iem.s.fPendingDataBreakpoints = true; \
     199                    break; \
     200                case X86_DR7_RW_IO: \
     201                    pVCpu->iem.s.fPendingIoBreakpoints = true; \
     202                    break; \
     203            } \
     204        } \
     205    } while (0)
     206    uint32_t const fGstDr7 = (uint32_t)pVCpu->cpum.GstCtx.dr[7];
     207    if (fGstDr7 & X86_DR7_ENABLED_MASK)
     208    {
     209        PROCESS_ONE_BP(fGstDr7, 0);
     210        PROCESS_ONE_BP(fGstDr7, 1);
     211        PROCESS_ONE_BP(fGstDr7, 2);
     212        PROCESS_ONE_BP(fGstDr7, 3);
     213    }
     214
     215    /*
     216     * Process hypervisor breakpoints.
     217     */
     218    uint32_t const fHyperDr7 = DBGFBpGetDR7(pVCpu->CTX_SUFF(pVM));
     219    if (fHyperDr7 & X86_DR7_ENABLED_MASK)
     220    {
     221        PROCESS_ONE_BP(fHyperDr7, 0);
     222        PROCESS_ONE_BP(fHyperDr7, 1);
     223        PROCESS_ONE_BP(fHyperDr7, 2);
     224        PROCESS_ONE_BP(fHyperDr7, 3);
     225    }
     226}
     227
     228
     229/**
    177230 * Initializes the decoder state.
    178231 *
     
    240293    pVCpu->iem.s.fBypassHandlers    = fBypassHandlers;
    241294    pVCpu->iem.s.fDisregardLock     = fDisregardLock;
     295    pVCpu->iem.s.fPendingInstructionBreakpoints = false;
     296    pVCpu->iem.s.fPendingDataBreakpoints        = false;
     297    pVCpu->iem.s.fPendingIoBreakpoints          = false;
     298    if (RT_LIKELY(   !(pVCpu->cpum.GstCtx.dr[7] & X86_DR7_ENABLED_MASK)
     299                  && pVCpu->CTX_SUFF(pVM)->dbgf.ro.cEnabledHwBreakpoints == 0))
     300    { /* likely */ }
     301    else
     302        iemInitPendingBreakpointsSlow(pVCpu);
    242303
    243304#ifdef DBGFTRACE_ENABLED
     
    304365    if (pVCpu->iem.s.pbInstrBuf)
    305366    {
    306         uint64_t off = (pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT ? pVCpu->cpum.GstCtx.rip : pVCpu->cpum.GstCtx.eip + (uint32_t)pVCpu->cpum.GstCtx.cs.u64Base)
     367        uint64_t off = (pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT
     368                        ? pVCpu->cpum.GstCtx.rip
     369                        : pVCpu->cpum.GstCtx.eip + (uint32_t)pVCpu->cpum.GstCtx.cs.u64Base)
    307370                     - pVCpu->iem.s.uInstrBufPc;
    308371        if (off < pVCpu->iem.s.cbInstrBufTotal)
     
    421484    {
    422485        Log(("iemInitDecoderAndPrefetchOpcodes: %RGv - rc=%Rrc\n", GCPtrPC, rc));
    423 #ifdef VBOX_WITH_NESTED_HWVIRT_VMX_EPT
     486# ifdef VBOX_WITH_NESTED_HWVIRT_VMX_EPT
    424487        if (Walk.fFailed & PGM_WALKFAIL_EPT)
    425488            IEM_VMX_VMEXIT_EPT_RET(pVCpu, &Walk, IEM_ACCESS_INSTRUCTION, IEM_SLAT_FAIL_LINEAR_TO_PHYS_ADDR, 0 /* cbInstr */);
    426 #endif
     489# endif
    427490        return iemRaisePageFault(pVCpu, GCPtrPC, 1, IEM_ACCESS_INSTRUCTION, rc);
    428491    }
     
    431494    {
    432495        Log(("iemInitDecoderAndPrefetchOpcodes: %RGv - supervisor page\n", GCPtrPC));
    433 #ifdef VBOX_WITH_NESTED_HWVIRT_VMX_EPT
     496# ifdef VBOX_WITH_NESTED_HWVIRT_VMX_EPT
    434497        if (Walk.fFailed & PGM_WALKFAIL_EPT)
    435498            IEM_VMX_VMEXIT_EPT_RET(pVCpu, &Walk, IEM_ACCESS_INSTRUCTION, IEM_SLAT_FAIL_LINEAR_TO_PAGE_TABLE, 0 /* cbInstr */);
    436 #endif
     499# endif
    437500        return iemRaisePageFault(pVCpu, GCPtrPC, 1, IEM_ACCESS_INSTRUCTION, VERR_ACCESS_DENIED);
    438501    }
     
    441504    {
    442505        Log(("iemInitDecoderAndPrefetchOpcodes: %RGv - NX\n", GCPtrPC));
    443 #ifdef VBOX_WITH_NESTED_HWVIRT_VMX_EPT
     506# ifdef VBOX_WITH_NESTED_HWVIRT_VMX_EPT
    444507        if (Walk.fFailed & PGM_WALKFAIL_EPT)
    445508            IEM_VMX_VMEXIT_EPT_RET(pVCpu, &Walk, IEM_ACCESS_INSTRUCTION, IEM_SLAT_FAIL_LINEAR_TO_PAGE_TABLE, 0 /* cbInstr */);
    446 #endif
     509# endif
    447510        return iemRaisePageFault(pVCpu, GCPtrPC, 1, IEM_ACCESS_INSTRUCTION, VERR_ACCESS_DENIED);
    448511    }
     
    719782void iemOpcodeFetchBytesJmp(PVMCPUCC pVCpu, size_t cbDst, void *pvDst) IEM_NOEXCEPT_MAY_LONGJMP
    720783{
    721 #ifdef IN_RING3
     784# ifdef IN_RING3
    722785    for (;;)
    723786    {
     
    768831            if (RT_LIKELY((uint32_t)GCPtrFirst <= pVCpu->cpum.GstCtx.cs.u32Limit))
    769832            { /* likely */ }
    770             else /** @todo For CPUs older than the 386, we should not generate \#GP here but wrap around! */
     833            else /** @todo For CPUs older than the 386, we should not necessarily generate \#GP here but wrap around! */
    771834                iemRaiseSelectorBoundsJmp(pVCpu, X86_SREG_CS, IEM_ACCESS_INSTRUCTION);
    772835            cbMaxRead = pVCpu->cpum.GstCtx.cs.u32Limit - (uint32_t)GCPtrFirst + 1;
     
    97959858    IEM_TRY_SETJMP(pVCpu, rcStrict)
    97969859    {
    9797         uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
     9860        uint8_t b; IEM_OPCODE_GET_FIRST_U8(&b);
    97989861        rcStrict = FNIEMOP_CALL(g_apfnOneByteMap[b]);
    97999862    }
     
    98049867    IEM_CATCH_LONGJMP_END(pVCpu);
    98059868#else
    9806     uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
     9869    uint8_t b; IEM_OPCODE_GET_FIRST_U8(&b);
    98079870    VBOXSTRICTRC rcStrict = FNIEMOP_CALL(g_apfnOneByteMap[b]);
    98089871#endif
     
    98559918            IEM_TRY_SETJMP_AGAIN(pVCpu, rcStrict)
    98569919            {
    9857                 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
     9920                uint8_t b; IEM_OPCODE_GET_FIRST_U8(&b);
    98589921                rcStrict = FNIEMOP_CALL(g_apfnOneByteMap[b]);
    98599922            }
     
    98649927            IEM_CATCH_LONGJMP_END(pVCpu);
    98659928#else
    9866             IEM_OPCODE_GET_NEXT_U8(&b);
     9929            IEM_OPCODE_GET_FIRST_U8(&b);
    98679930            rcStrict = FNIEMOP_CALL(g_apfnOneByteMap[b]);
    98689931#endif
     
    1014510208                 * Do the decoding and emulation.
    1014610209                 */
    10147                 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
     10210                uint8_t b; IEM_OPCODE_GET_FIRST_U8(&b);
    1014810211                rcStrict = FNIEMOP_CALL(g_apfnOneByteMap[b]);
    1014910212#ifdef VBOX_STRICT
     
    1031310376                uint32_t const cPotentialExits = pVCpu->iem.s.cPotentialExits;
    1031410377
    10315                 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
     10378                uint8_t b; IEM_OPCODE_GET_FIRST_U8(&b);
    1031610379                rcStrict = FNIEMOP_CALL(g_apfnOneByteMap[b]);
    1031710380
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp

    r97642 r97694  
    66276627    AssertRCSuccessReturn(rc, RT_SUCCESS_NP(rc) ? VERR_IEM_IPE_1 : rc);
    66286628
     6629    /*
     6630     * Re-init hardware breakpoint summary if it was DR7 that got changed.
     6631     */
     6632    if (iDrReg == 7)
     6633    {
     6634        pVCpu->iem.s.fPendingInstructionBreakpoints = false;
     6635        pVCpu->iem.s.fPendingDataBreakpoints        = false;
     6636        pVCpu->iem.s.fPendingIoBreakpoints          = false;
     6637        iemInitPendingBreakpointsSlow(pVCpu);
     6638    }
     6639
    66296640    return iemRegAddToRipAndFinishingClearingRF(pVCpu, cbInstr);
    66306641}
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImplSvmInstr.cpp

    r97370 r97694  
    3333#define VMCPU_INCL_CPUM_GST_CTX
    3434#include <VBox/vmm/iem.h>
     35#include <VBox/vmm/apic.h>
    3536#include <VBox/vmm/cpum.h>
    36 #include <VBox/vmm/apic.h>
    37 #include <VBox/vmm/pgm.h>
     37#include <VBox/vmm/dbgf.h>
    3838#include <VBox/vmm/em.h>
    3939#include <VBox/vmm/hm.h>
     40#include <VBox/vmm/pgm.h>
    4041#ifdef VBOX_WITH_NESTED_HWVIRT_SVM
    4142# include <VBox/vmm/hm_svm.h>
     
    5556#include "IEMInline.h"
    5657
     58#ifdef VBOX_WITH_NESTED_HWVIRT_SVM /* Almost the whole file. */
     59
    5760
    5861/*********************************************************************************************************************************
    5962*   Defined Constants And Macros                                                                                                 *
    6063*********************************************************************************************************************************/
    61 #ifdef VBOX_WITH_NESTED_HWVIRT_SVM
    6264/**
    6365 * Check the common SVM instruction preconditions.
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp

    r97583 r97694  
    3333#define VMCPU_INCL_CPUM_GST_CTX
    3434#include <VBox/vmm/iem.h>
     35#include <VBox/vmm/apic.h>
    3536#include <VBox/vmm/cpum.h>
    36 #include <VBox/vmm/apic.h>
     37#include <VBox/vmm/dbgf.h>
     38#include <VBox/vmm/em.h>
     39#include <VBox/vmm/gim.h>
     40#include <VBox/vmm/hm.h>
    3741#include <VBox/vmm/pgm.h>
    38 #include <VBox/vmm/em.h>
    39 #include <VBox/vmm/hm.h>
    40 #include <VBox/vmm/gim.h>
    4142#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
    4243# include <VBox/vmm/hmvmxinline.h>
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