VirtualBox

Changeset 97705 in vbox for trunk


Ignore:
Timestamp:
Nov 29, 2022 2:11:49 PM (2 years ago)
Author:
vboxsync
Message:

VMM/IEM,DBGF,CPUM: Do debugger I/O breakpoints via the internal EFLAGS bits too. Seems we might need two bits, so had to shift the internal bits down from 24 to 22. bugref:9898

Location:
trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/cpumctx.h

    r97406 r97705  
    261261 * clear drop in thruput, it would on the whole make the most sense to use 24
    262262 * here.
    263  */
    264 #define CPUMX86EFLAGS_HW_BITS       24
     263 *
     264 * Update: We need more than 8 bits because of DBGF, so using 22 now.
     265 */
     266#define CPUMX86EFLAGS_HW_BITS       22
    265267/** Mask for the hardware EFLAGS bits, 64-bit version. */
    266268#define CPUMX86EFLAGS_HW_MASK_64    (RT_BIT_64(CPUMX86EFLAGS_HW_BITS) - UINT64_C(1))
     
    275277
    276278/** Mask of internal flags kept with EFLAGS, 64-bit version.
    277  * The first 3 available bits are taken by CPUMCTX_INHIBIT_SHADOW_SS,
    278  * CPUMCTX_INHIBIT_SHADOW_STI and CPUMCTX_INHIBIT_NMI.  The next 4 bits are
    279  * taken by CPUMCTX_DBG_HIT_DRX_MASK.
    280  */
    281 #define CPUMX86EFLAGS_INT_MASK_64   UINT64_C(0x000000007f000000)
     279 * Bits 22-24 are taken by CPUMCTX_INHIBIT_SHADOW_SS, CPUMCTX_INHIBIT_SHADOW_STI
     280 * and CPUMCTX_INHIBIT_NMI, bits 25-28 are for CPUMCTX_DBG_HIT_DRX_MASK, and
     281 * bits 29-30 are for DBGF events and breakpoints.
     282 *
     283 * @todo The two DBGF bits could be merged.  The NMI inhibiting could move to
     284 *       bit 32 or higher as it isn't automatically cleared on instruction
     285 *       completion (except for iret).
     286 */
     287#define CPUMX86EFLAGS_INT_MASK_64   UINT64_C(0x00000000ffc00000)
    282288/** Mask of internal flags kept with EFLAGS, 32-bit version. */
    283 #define CPUMX86EFLAGS_INT_MASK_32           UINT32_C(0x7f000000)
     289#define CPUMX86EFLAGS_INT_MASK_32           UINT32_C(0xffc00000)
    284290
    285291
     
    10541060#define CPUMCTX_DBG_HIT_DRX_SHIFT       CPUMCTX_DBG_HIT_DR0_BIT
    10551061/** Mask of all guest pending DR0-DR3 breakpoint indicators. */
    1056 #define CPUMCTX_DBG_HIT_DRX_MASK       (CPUMCTX_DBG_HIT_DR0 | CPUMCTX_DBG_HIT_DR1 | CPUMCTX_DBG_HIT_DR2 | CPUMCTX_DBG_HIT_DR3)
    1057 AssertCompile(CPUMCTX_DBG_HIT_DRX_MASK < UINT32_MAX);
     1062#define CPUMCTX_DBG_HIT_DRX_MASK        (CPUMCTX_DBG_HIT_DR0 | CPUMCTX_DBG_HIT_DR1 | CPUMCTX_DBG_HIT_DR2 | CPUMCTX_DBG_HIT_DR3)
     1063/** DBGF event/breakpoint pending. */
     1064#define CPUMCTX_DBG_DBGF_EVENT          RT_BIT_32(CPUMCTX_DBG_DBGF_EVENT_BIT)
     1065#define CPUMCTX_DBG_DBGF_EVENT_BIT      (7 + CPUMX86EFLAGS_HW_BITS)
     1066/** DBGF event/breakpoint pending. */
     1067#define CPUMCTX_DBG_DBGF_BP             RT_BIT_32(CPUMCTX_DBG_DBGF_BP_BIT)
     1068#define CPUMCTX_DBG_DBGF_BP_BIT         (8 + CPUMX86EFLAGS_HW_BITS)
     1069/** Mask of all DBGF indicators. */
     1070#define CPUMCTX_DBG_DBGF_MASK           (CPUMCTX_DBG_DBGF_EVENT | CPUMCTX_DBG_DBGF_BP)
     1071AssertCompile((CPUMCTX_DBG_HIT_DRX_MASK | CPUMCTX_DBG_DBGF_MASK) < UINT32_MAX);
    10581072/** @}  */
    10591073
  • trunk/include/VBox/vmm/dbgf.h

    r97693 r97705  
    11241124VMM_INT_DECL(VBOXSTRICTRC)  DBGFBpCheckInstruction(PVMCC pVM, PVMCPUCC pVCpu, RTGCPTR GCPtrPC);
    11251125VMM_INT_DECL(VBOXSTRICTRC)  DBGFBpCheckIo(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, RTIOPORT uIoPort, uint8_t cbValue);
     1126VMM_INT_DECL(uint32_t)      DBGFBpCheckIo2(PVMCC pVM, PVMCPUCC pVCpu, RTIOPORT uIoPort, uint8_t cbValue);
    11261127VMM_INT_DECL(VBOXSTRICTRC)  DBGFBpCheckPortIo(PVMCC pVM, PVMCPU pVCpu, RTIOPORT uIoPort,
    11271128                                              uint32_t fAccess, uint32_t uValue, bool fBefore);
  • trunk/src/VBox/VMM/VMMAll/DBGFAll.cpp

    r97699 r97705  
    229229        uint32_t fMatched = 0;
    230230        uint32_t fEnabled = 0;
    231         for (unsigned iBp = 0, iBpMask = 1; iBp < 4; iBp++, iBpMask <<= 1)
     231        for (unsigned iBp = 0, uBpMask = 1; iBp < 4; iBp++, uBpMask <<= 1)
    232232            if (X86_DR7_IS_EO_CFG(fDr7, iBp))
    233233            {
    234234                if (fDr7 & X86_DR7_L_G(iBp))
    235                     fEnabled |= iBpMask;
     235                    fEnabled |= uBpMask;
    236236                if (pVCpu->cpum.GstCtx.dr[iBp] == GCPtrPC)
    237                     fMatched |= iBpMask;
     237                    fMatched |= uBpMask;
    238238            }
    239239        if (!(fEnabled & fMatched))
     
    361361
    362362/**
     363 * Checks I/O access for guest or hypervisor hardware breakpoints.
     364 *
     365 * Caller must make sure DR0-3 and DR7 are present in the CPU context before
     366 * calling this function.
     367 *
     368 * @returns CPUMCTX_DBG_DBGF_BP, CPUMCTX_DBG_HIT_DRX_MASK, or 0 (no match).
     369 *
     370 * @param   pVM         The cross context VM structure.
     371 * @param   pVCpu       The cross context virtual CPU structure of the calling EMT.
     372 * @param   uIoPort     The I/O port being accessed.
     373 * @param   cbValue     The size/width of the access, in bytes.
     374 */
     375VMM_INT_DECL(uint32_t) DBGFBpCheckIo2(PVMCC pVM, PVMCPUCC pVCpu, RTIOPORT uIoPort, uint8_t cbValue)
     376{
     377    uint32_t const uIoPortFirst = uIoPort;
     378    uint32_t const uIoPortLast  = uIoPortFirst + cbValue - 1;
     379
     380    /*
     381     * Check hyper breakpoints first as the VMM debugger has priority over
     382     * the guest.
     383     */
     384    if (pVM->dbgf.s.cEnabledHwIoBreakpoints > 0)
     385        for (unsigned iBp = 0; iBp < RT_ELEMENTS(pVM->dbgf.s.aHwBreakpoints); iBp++)
     386        {
     387            if (   pVM->dbgf.s.aHwBreakpoints[iBp].fType == X86_DR7_RW_IO
     388                && pVM->dbgf.s.aHwBreakpoints[iBp].fEnabled
     389                && pVM->dbgf.s.aHwBreakpoints[iBp].hBp   != NIL_DBGFBP)
     390            {
     391                uint8_t  cbReg      = pVM->dbgf.s.aHwBreakpoints[iBp].cb; Assert(RT_IS_POWER_OF_TWO(cbReg));
     392                uint64_t uDrXFirst  = pVM->dbgf.s.aHwBreakpoints[iBp].GCPtr & ~(uint64_t)(cbReg - 1);
     393                uint64_t uDrXLast   = uDrXFirst + cbReg - 1;
     394                if (uDrXFirst <= uIoPortLast && uDrXLast >= uIoPortFirst)
     395                {
     396                    /* (See also DBGFRZTrap01Handler.) */
     397                    pVCpu->dbgf.s.hBpActive = pVM->dbgf.s.aHwBreakpoints[iBp].hBp;
     398                    pVCpu->dbgf.s.fSingleSteppingRaw = false;
     399
     400                    LogFlow(("DBGFBpCheckIo2: hit hw breakpoint %d at %04x:%RGv (iop %#x L %u)\n",
     401                             iBp, pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.rip, uIoPort, cbValue));
     402                    return CPUMCTX_DBG_DBGF_BP;
     403                }
     404            }
     405        }
     406
     407    /*
     408     * Check the guest.
     409     */
     410    uint32_t const fDr7 = pVCpu->cpum.GstCtx.dr[7];
     411    if (   (fDr7 & X86_DR7_ENABLED_MASK)
     412        && X86_DR7_ANY_RW_IO(fDr7)
     413        && (pVCpu->cpum.GstCtx.cr4 & X86_CR4_DE) )
     414    {
     415        uint32_t fEnabled = 0;
     416        uint32_t fMatched = 0;
     417        for (unsigned iBp = 0, uBpMask = 1; iBp < 4; iBp++, uBpMask <<= 1)
     418        {
     419            if (fDr7 & X86_DR7_L_G(iBp))
     420                fEnabled |= uBpMask;
     421            if (X86_DR7_GET_RW(fDr7, iBp) == X86_DR7_RW_IO)
     422            {
     423                /* ASSUME the breakpoint and the I/O width qualifier uses the same encoding (1 2 x 4). */
     424                static uint8_t const s_abInvAlign[4] = { 0, 1, 7, 3 };
     425                uint8_t  const cbInvAlign = s_abInvAlign[X86_DR7_GET_LEN(fDr7, iBp)];
     426                uint64_t const uDrXFirst  = pVCpu->cpum.GstCtx.dr[iBp] & ~(uint64_t)cbInvAlign;
     427                uint64_t const uDrXLast   = uDrXFirst + cbInvAlign;
     428                if (uDrXFirst <= uIoPortLast && uDrXLast >= uIoPortFirst)
     429                    fMatched |= uBpMask;
     430            }
     431        }
     432        if (fEnabled & fMatched)
     433        {
     434            LogFlow(("DBGFBpCheckIo2: hit hw breakpoint %#x at %04x:%RGv (iop %#x L %u)\n",
     435                     fMatched, pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.rip, uIoPort, cbValue));
     436            return fMatched << CPUMCTX_DBG_HIT_DRX_SHIFT;
     437        }
     438    }
     439
     440    return 0;
     441}
     442
     443
     444/**
    363445 * Returns the single stepping state for a virtual CPU.
    364446 *
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp

    r97694 r97705  
    73467346        if (rcStrict != VINF_SUCCESS)
    73477347            iemSetPassUpStatus(pVCpu, rcStrict);
     7348
     7349        /*
     7350         * Check for I/O breakpoints before we complete the instruction.
     7351         */
     7352        uint32_t const fDr7 = pVCpu->cpum.GstCtx.dr[7];
     7353        if (RT_UNLIKELY(   (   (   (fDr7 & X86_DR7_ENABLED_MASK)
     7354                                && X86_DR7_ANY_RW_IO(fDr7)
     7355                                && (pVCpu->cpum.GstCtx.cr4 & X86_CR4_DE))
     7356                            || pVM->dbgf.ro.cEnabledHwIoBreakpoints > 0)
     7357                        && rcStrict == VINF_SUCCESS))
     7358        {
     7359            IEM_CTX_IMPORT_RET(pVCpu, CPUMCTX_EXTRN_DR0_DR3 | CPUMCTX_EXTRN_DR6);
     7360            pVCpu->cpum.GstCtx.eflags.uBoth |= DBGFBpCheckIo2(pVM, pVCpu, u16Port, cbReg);
     7361        }
     7362
    73487363        rcStrict = iemRegAddToRipAndFinishingClearingRF(pVCpu, cbInstr);
    7349 
    7350         /*
    7351          * Check for I/O breakpoints.
    7352          */
    7353         /** @todo this should set a internal flag and be raised by
    7354          *        iemRegAddToRipAndFinishingClearingRF! */
    7355         uint32_t const uDr7 = pVCpu->cpum.GstCtx.dr[7];
    7356         if (RT_UNLIKELY(   (   (   (uDr7 & X86_DR7_ENABLED_MASK)
    7357                                 && X86_DR7_ANY_RW_IO(uDr7)
    7358                                 && (pVCpu->cpum.GstCtx.cr4 & X86_CR4_DE))
    7359                             || DBGFBpIsHwIoArmed(pVM))
    7360                         && rcStrict == VINF_SUCCESS))
    7361         {
    7362             IEM_CTX_IMPORT_RET(pVCpu, CPUMCTX_EXTRN_DR0_DR3 | CPUMCTX_EXTRN_DR6);
    7363             rcStrict = DBGFBpCheckIo(pVM, pVCpu, IEM_GET_CTX(pVCpu), u16Port, cbReg);
    7364             if (rcStrict == VINF_EM_RAW_GUEST_TRAP)
    7365                 rcStrict = iemRaiseDebugException(pVCpu);
    7366         }
    73677364    }
    73687365
     
    74587455        if (rcStrict != VINF_SUCCESS)
    74597456            iemSetPassUpStatus(pVCpu, rcStrict);
     7457
     7458        /*
     7459         * Check for I/O breakpoints before we complete the instruction.
     7460         */
     7461        uint32_t const fDr7 = pVCpu->cpum.GstCtx.dr[7];
     7462        if (RT_UNLIKELY(   (   (   (fDr7 & X86_DR7_ENABLED_MASK)
     7463                                && X86_DR7_ANY_RW_IO(fDr7)
     7464                                && (pVCpu->cpum.GstCtx.cr4 & X86_CR4_DE))
     7465                            || pVM->dbgf.ro.cEnabledHwIoBreakpoints > 0)
     7466                        && rcStrict == VINF_SUCCESS))
     7467        {
     7468            IEM_CTX_IMPORT_RET(pVCpu, CPUMCTX_EXTRN_DR0_DR3 | CPUMCTX_EXTRN_DR6);
     7469            pVCpu->cpum.GstCtx.eflags.uBoth |= DBGFBpCheckIo2(pVM, pVCpu, u16Port, cbReg);
     7470        }
     7471
    74607472        rcStrict = iemRegAddToRipAndFinishingClearingRF(pVCpu, cbInstr);
    7461 
    7462         /*
    7463          * Check for I/O breakpoints.
    7464          */
    7465         /** @todo this should set a internal flag and be raised by
    7466          *        iemRegAddToRipAndFinishingClearingRF! */
    7467         uint32_t const uDr7 = pVCpu->cpum.GstCtx.dr[7];
    7468         if (RT_UNLIKELY(   (   (   (uDr7 & X86_DR7_ENABLED_MASK)
    7469                                 && X86_DR7_ANY_RW_IO(uDr7)
    7470                                 && (pVCpu->cpum.GstCtx.cr4 & X86_CR4_DE))
    7471                             || DBGFBpIsHwIoArmed(pVM))
    7472                         && rcStrict == VINF_SUCCESS))
    7473         {
    7474             IEM_CTX_IMPORT_RET(pVCpu, CPUMCTX_EXTRN_DR0_DR3 | CPUMCTX_EXTRN_DR6);
    7475             rcStrict = DBGFBpCheckIo(pVM, pVCpu, IEM_GET_CTX(pVCpu), u16Port, cbReg);
    7476             if (rcStrict == VINF_EM_RAW_GUEST_TRAP)
    7477                 rcStrict = iemRaiseDebugException(pVCpu);
    7478         }
    74797473    }
    74807474    return rcStrict;
  • trunk/src/VBox/VMM/VMMR3/DBGFR3Bp.cpp

    r97393 r97705  
    22992299    {
    23002300        case X86_DR7_RW_EO:
    2301             if (cb == 1)
    2302                 break;
    2303             AssertMsgFailedReturn(("fType=%#x cb=%d != 1\n", fType, cb), VERR_INVALID_PARAMETER);
     2301            AssertMsgReturn(cb == 1, ("fType=%#x cb=%d != 1\n", fType, cb), VERR_INVALID_PARAMETER);
     2302            break;
    23042303        case X86_DR7_RW_IO:
    23052304        case X86_DR7_RW_RW:
     
    23132312    AssertRCReturn(rc, rc);
    23142313
     2314    /*
     2315     * Check if we've already got a matching breakpoint for that address.
     2316     */
    23152317    PDBGFBPINT pBp = NULL;
    23162318    DBGFBP hBp = dbgfR3BpGetByAddr(pUVM, DBGFBPTYPE_REG, pAddress->FlatPtr, &pBp);
     
    23202322    {
    23212323        rc = VINF_SUCCESS;
    2322         if (!DBGF_BP_PUB_IS_ENABLED(&pBp->Pub))
     2324        if (!DBGF_BP_PUB_IS_ENABLED(&pBp->Pub) && (fFlags & DBGF_BP_F_ENABLED))
    23232325            rc = dbgfR3BpArm(pUVM, hBp, pBp);
     2326        /* else: We don't disable it when DBGF_BP_F_ENABLED isn't given. */
    23242327        if (RT_SUCCESS(rc))
    23252328        {
     
    23312334    }
    23322335
    2333     /* Allocate new breakpoint. */
    2334     rc = dbgfR3BpAlloc(pUVM, hOwner, pvUser, DBGFBPTYPE_REG, fFlags,
    2335                        iHitTrigger, iHitDisable, &hBp, &pBp);
     2336    /*
     2337     * Allocate new breakpoint.
     2338     */
     2339    rc = dbgfR3BpAlloc(pUVM, hOwner, pvUser, DBGFBPTYPE_REG, fFlags, iHitTrigger, iHitDisable, &hBp, &pBp);
    23362340    if (RT_SUCCESS(rc))
    23372341    {
  • trunk/src/VBox/VMM/include/IEMInline.h

    r97694 r97705  
    17581758     * Normally we're just here to clear RF and/or interrupt shadow bits.
    17591759     */
    1760     if (RT_LIKELY((pVCpu->cpum.GstCtx.eflags.uBoth & (X86_EFL_TF | CPUMCTX_DBG_HIT_DRX_MASK)) == 0))
     1760    if (RT_LIKELY((pVCpu->cpum.GstCtx.eflags.uBoth & (X86_EFL_TF | CPUMCTX_DBG_HIT_DRX_MASK | CPUMCTX_DBG_DBGF_MASK)) == 0))
    17611761        pVCpu->cpum.GstCtx.eflags.uBoth &= ~(X86_EFL_RF | CPUMCTX_INHIBIT_SHADOW);
    17621762    else
    17631763    {
    1764 #if 1
    17651764        /*
    1766          * Raise a #DB.
     1765         * Raise a #DB or/and DBGF event.
    17671766         */
    1768         IEM_CTX_IMPORT_RET(pVCpu, CPUMCTX_EXTRN_DR6);
    1769         pVCpu->cpum.GstCtx.dr[6] &= ~X86_DR6_B_MASK;
    1770         if (pVCpu->cpum.GstCtx.eflags.uBoth & X86_EFL_TF)
    1771             pVCpu->cpum.GstCtx.dr[6] |= X86_DR6_BS;
    1772         pVCpu->cpum.GstCtx.dr[6] |= (pVCpu->cpum.GstCtx.eflags.uBoth & CPUMCTX_DBG_HIT_DRX_MASK) >> CPUMCTX_DBG_HIT_DRX_SHIFT;
    1773         /** @todo Do we set all pending \#DB events, or just one? */
    1774         LogFlowFunc(("Guest #DB fired at %04X:%016llX: DR6=%08X, RFLAGS=%16RX64\n",
    1775                      pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.rip, (unsigned)pVCpu->cpum.GstCtx.dr[6],
    1776                      pVCpu->cpum.GstCtx.rflags.uBoth));
    1777         pVCpu->cpum.GstCtx.eflags.uBoth &= ~(X86_EFL_RF | CPUMCTX_INHIBIT_SHADOW | CPUMCTX_DBG_HIT_DRX_MASK);
    1778         return iemRaiseDebugException(pVCpu);
    1779 #else
    1780         pVCpu->cpum.GstCtx.eflags.uBoth &= ~(X86_EFL_RF | CPUMCTX_INHIBIT_SHADOW | CPUMCTX_DBG_HIT_DRX_MASK);
    1781 #endif
     1767        VBOXSTRICTRC rcStrict;
     1768        if (pVCpu->cpum.GstCtx.eflags.uBoth & (X86_EFL_TF | CPUMCTX_DBG_HIT_DRX_MASK))
     1769        {
     1770            IEM_CTX_IMPORT_RET(pVCpu, CPUMCTX_EXTRN_DR6);
     1771            pVCpu->cpum.GstCtx.dr[6] &= ~X86_DR6_B_MASK;
     1772            if (pVCpu->cpum.GstCtx.eflags.uBoth & X86_EFL_TF)
     1773                pVCpu->cpum.GstCtx.dr[6] |= X86_DR6_BS;
     1774            pVCpu->cpum.GstCtx.dr[6] |= (pVCpu->cpum.GstCtx.eflags.uBoth & CPUMCTX_DBG_HIT_DRX_MASK) >> CPUMCTX_DBG_HIT_DRX_SHIFT;
     1775            LogFlowFunc(("Guest #DB fired at %04X:%016llX: DR6=%08X, RFLAGS=%16RX64\n",
     1776                         pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.rip, (unsigned)pVCpu->cpum.GstCtx.dr[6],
     1777                         pVCpu->cpum.GstCtx.rflags.uBoth));
     1778
     1779            pVCpu->cpum.GstCtx.eflags.uBoth &= ~(X86_EFL_RF | CPUMCTX_INHIBIT_SHADOW | CPUMCTX_DBG_HIT_DRX_MASK);
     1780            rcStrict = iemRaiseDebugException(pVCpu);
     1781
     1782            /* A DBGF event/breakpoint trumps the iemRaiseDebugException informational status code. */
     1783            if ((pVCpu->cpum.GstCtx.eflags.uBoth & CPUMCTX_DBG_DBGF_MASK) && RT_FAILURE(rcStrict))
     1784            {
     1785                rcStrict = pVCpu->cpum.GstCtx.eflags.uBoth & CPUMCTX_DBG_DBGF_BP ? VINF_EM_DBG_BREAKPOINT : VINF_EM_DBG_EVENT;
     1786                LogFlowFunc(("dbgf at %04X:%016llX: %Rrc\n", pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.rip, VBOXSTRICTRC_VAL(rcStrict)));
     1787            }
     1788        }
     1789        else
     1790        {
     1791            Assert(pVCpu->cpum.GstCtx.eflags.uBoth & CPUMCTX_DBG_DBGF_MASK);
     1792            rcStrict = pVCpu->cpum.GstCtx.eflags.uBoth & CPUMCTX_DBG_DBGF_BP ? VINF_EM_DBG_BREAKPOINT : VINF_EM_DBG_EVENT;
     1793            LogFlowFunc(("dbgf at %04X:%016llX: %Rrc\n", pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.rip, VBOXSTRICTRC_VAL(rcStrict)));
     1794        }
     1795        pVCpu->cpum.GstCtx.eflags.uBoth &= ~CPUMCTX_DBG_DBGF_MASK;
     1796        return rcStrict;
    17821797    }
    17831798    return VINF_SUCCESS;
     
    17971812    AssertCompile(CPUMCTX_INHIBIT_SHADOW < UINT32_MAX);
    17981813    if (RT_LIKELY(!(  pVCpu->cpum.GstCtx.eflags.uBoth
    1799                     & (X86_EFL_TF | X86_EFL_RF | CPUMCTX_INHIBIT_SHADOW | CPUMCTX_DBG_HIT_DRX_MASK)) ))
     1814                    & (X86_EFL_TF | X86_EFL_RF | CPUMCTX_INHIBIT_SHADOW | CPUMCTX_DBG_HIT_DRX_MASK | CPUMCTX_DBG_DBGF_MASK)) ))
    18001815        return VINF_SUCCESS;
    18011816    return iemFinishInstructionWithFlagsSet(pVCpu);
     
    18361851                 pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.rip, (unsigned)pVCpu->cpum.GstCtx.dr[6],
    18371852                 pVCpu->cpum.GstCtx.rflags.uBoth));
    1838     pVCpu->cpum.GstCtx.eflags.uBoth &= ~(X86_EFL_RF | CPUMCTX_INHIBIT_SHADOW | CPUMCTX_DBG_HIT_DRX_MASK);
     1853    pVCpu->cpum.GstCtx.eflags.uBoth &= ~(X86_EFL_RF | CPUMCTX_INHIBIT_SHADOW | CPUMCTX_DBG_HIT_DRX_MASK | CPUMCTX_DBG_DBGF_MASK);
    18391854    return iemRaiseDebugException(pVCpu);
    18401855}
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