VirtualBox

Changeset 64770 in vbox for trunk


Ignore:
Timestamp:
Dec 1, 2016 12:28:44 PM (8 years ago)
Author:
vboxsync
Message:

VMM/DBGF, HM: Fix int3 based breakpoints set in the VM debugger when using VT-x.

Location:
trunk
Files:
11 edited

Legend:

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

    r64720 r64770  
    124124VMMR3DECL(PDBGFADDRESS) DBGFR3AddrFromPhys(PUVM pUVM, PDBGFADDRESS pAddress, RTGCPHYS PhysAddr);
    125125VMMR3DECL(bool)         DBGFR3AddrIsValid(PUVM pUVM, PCDBGFADDRESS pAddress);
    126 VMMR3DECL(int)          DBGFR3AddrToPhys(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddress, PRTGCPHYS pGCPhys);
     126VMMR3DECL(int)          DBGFR3AddrToPhys(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, PRTGCPHYS pGCPhys);
    127127VMMR3DECL(int)          DBGFR3AddrToHostPhys(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddress, PRTHCPHYS pHCPhys);
    128128VMMR3DECL(int)          DBGFR3AddrToVolatileR3Ptr(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddress, bool fReadOnly, void **ppvR3Ptr);
     
    791791            uint8_t         cb;
    792792        } Reg;
    793         /** Recompiler breakpoint data. */
     793
     794        /** INT3 breakpoint data. */
    794795        struct DBGFBPINT3
    795796        {
    796797            /** The flat GC address of the breakpoint. */
    797798            RTGCUINTPTR     GCPtr;
     799            /** The physical address of the breakpoint. */
     800            RTGCPHYS        PhysAddr;
    798801            /** The byte value we replaced by the INT 3 instruction. */
    799802            uint8_t         bOrg;
     
    831834
    832835        /** Paddind to ensure that the size is identical on win32 and linux. */
    833         uint64_t    u64Padding[2];
     836        uint64_t    u64Padding[3];
    834837    } u;
    835838} DBGFBP;
     
    844847
    845848#ifdef IN_RING3 /* The breakpoint management API is only available in ring-3. */
    846 VMMR3DECL(int)  DBGFR3BpSet(PUVM pUVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable, uint32_t *piBp);
     849VMMR3DECL(int)  DBGFR3BpSetInt3(PUVM pUVM, VMCPUID idSrcCpu, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable, uint32_t *piBp);
    847850VMMR3DECL(int)  DBGFR3BpSetReg(PUVM pUVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable,
    848851                               uint8_t fType, uint8_t cb, uint32_t *piBp);
     
    879882VMM_INT_DECL(bool)          DBGFBpIsHwArmed(PVM pVM);
    880883VMM_INT_DECL(bool)          DBGFBpIsHwIoArmed(PVM pVM);
     884VMM_INT_DECL(bool)          DBGFBpIsInt3Armed(PVM pVM);
    881885VMM_INT_DECL(bool)          DBGFIsStepping(PVMCPU pVCpu);
    882886VMM_INT_DECL(VBOXSTRICTRC)  DBGFBpCheckIo(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, RTIOPORT uIoPort, uint8_t cbValue);
  • trunk/include/VBox/vmm/vm.h

    r63648 r64770  
    12071207            /** Enabled software interrupt breakpoints. */
    12081208            uint32_t                    cSoftIntBreakpoints;
    1209             /** Number of selected events. */
     1209            /** The number of selected events. */
    12101210            uint32_t                    cSelectedEvents;
     1211            /** The number of enabled hardware breakpoints. */
     1212            uint8_t                     cEnabledHwBreakpoints;
     1213            /** The number of enabled hardware I/O breakpoints. */
     1214            uint8_t                     cEnabledHwIoBreakpoints;
     1215            /** The number of enabled INT3 breakpoints. */
     1216            uint8_t                     cEnabledInt3Breakpoints;
     1217            uint8_t                     abPadding[1]; /**< Unused padding space up for grabs. */
    12111218        } const     ro;
    12121219#endif
  • trunk/src/VBox/Debugger/DBGCEmulateCodeView.cpp

    r64721 r64770  
    10851085     */
    10861086    uint32_t iBp;
    1087     rc = DBGFR3BpSet(pUVM, &Address, iHitTrigger, iHitDisable, &iBp);
     1087    PDBGC    pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
     1088    rc = DBGFR3BpSetInt3(pUVM, pDbgc->idCpu, &Address, iHitTrigger, iHitDisable, &iBp);
    10881089    if (RT_SUCCESS(rc))
    10891090    {
    1090         PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
    10911091        rc = dbgcBpAdd(pDbgc, iBp, pszCmds);
    10921092        if (RT_SUCCESS(rc))
  • trunk/src/VBox/Debugger/testcase/tstDBGCStubs.cpp

    r64721 r64770  
    4242}
    4343
    44 VMMR3DECL(int)  DBGFR3AddrToPhys(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddress, PRTGCPHYS pGCPhys)
     44VMMR3DECL(int)  DBGFR3AddrToPhys(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, PRTGCPHYS pGCPhys)
    4545{
    4646    return VERR_INTERNAL_ERROR;
     
    6868    return VERR_INTERNAL_ERROR;
    6969}
    70 VMMR3DECL(int) DBGFR3BpSet(PUVM pUVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable, PRTUINT piBp)
     70VMMR3DECL(int) DBGFR3BpSetInt3(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable, PRTUINT piBp)
    7171{
    7272    return VERR_INTERNAL_ERROR;
  • trunk/src/VBox/VMM/VMMAll/DBGFAll.cpp

    r62478 r64770  
    150150{
    151151    return pVM->dbgf.s.cEnabledHwIoBreakpoints > 0;
     152}
     153
     154
     155/**
     156 * Checks if any INT3 breakpoints are armed.
     157 *
     158 * @returns true if armed, false if not.
     159 * @param   pVM        The cross context VM structure.
     160 * @remarks Don't call this from CPUMRecalcHyperDRx!
     161 */
     162VMM_INT_DECL(bool) DBGFBpIsInt3Armed(PVM pVM)
     163{
     164    return pVM->dbgf.s.cEnabledInt3Breakpoints > 0;
    152165}
    153166
  • trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp

    r64663 r64770  
    16701670static int hmR0SvmLoadGuestXcptIntercepts(PVMCPU pVCpu, PSVMVMCB pVmcb, PCPUMCTX pCtx)
    16711671{
    1672     int rc = VINF_SUCCESS;
    1673     NOREF(pCtx);
    16741672    if (HMCPU_CF_IS_PENDING(pVCpu, HM_CHANGED_GUEST_XCPT_INTERCEPTS))
    16751673    {
    1676         /* The remaining intercepts are handled elsewhere, e.g. in hmR0SvmLoadSharedCR0(). */
     1674        /* Trap #UD for GIM provider (e.g. for hypercalls). */
    16771675        if (pVCpu->hm.s.fGIMTrapXcptUD)
    16781676            hmR0SvmAddXcptIntercept(pVmcb, X86_XCPT_UD);
    16791677        else
    16801678            hmR0SvmRemoveXcptIntercept(pVmcb, X86_XCPT_UD);
     1679
     1680        /* Trap #BP for INT3 debug breakpoints set by the VM debugger. */
     1681        if (pVCpu->CTX_SUFF(pVM)->dbgf.ro.cEnabledInt3Breakpoints)
     1682            hmR0SvmAddXcptIntercept(pVmcb, X86_XCPT_BP);
     1683        else
     1684            hmR0SvmRemoveXcptIntercept(pVmcb, X86_XCPT_BP);
     1685
     1686        /* The remaining intercepts are handled elsewhere, e.g. in hmR0SvmLoadSharedCR0(). */
    16811687        HMCPU_CF_CLEAR(pVCpu, HM_CHANGED_GUEST_XCPT_INTERCEPTS);
    16821688    }
    1683     return rc;
     1689    return VINF_SUCCESS;
    16841690}
    16851691
  • trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp

    r64676 r64770  
    26502650    LogFlowFunc(("pVM=%p pVCpu=%p\n", pVM, pVCpu));
    26512651
     2652    /** @todo r=ramshankar: Shouldn't setting up \#UD intercepts be handled by
     2653     *        hmR0VmxLoadGuestXcptIntercepts()? Why do we check it here? */
    26522654    uint32_t u32XcptBitmap = pVCpu->hm.s.fGIMTrapXcptUD ? RT_BIT(X86_XCPT_UD) : 0;
    26532655
     
    91079109    /** Stuff we need in VMX_VMCS32_CTRL_PROC_EXEC2. */
    91089110    uint32_t    fCpe2Extra;
    9109     /** Extra stuff we need in   */
     9111    /** Extra stuff we need in VMX_VMCS32_CTRL_EXCEPTION_BITMAP. */
    91109112    uint32_t    bmXcptExtra;
    91119113    /** The sequence number of the Dtrace provider settings the state was
     
    93059307        ASMBitSet(pDbgState->bmExitsToCheck, VMX_EXIT_XCPT_OR_NMI);
    93069308    }
     9309
     9310    /*
     9311     * INT3 breakpoints - triggered by #BP exceptions.
     9312     */
     9313    if (pVM->dbgf.ro.cEnabledInt3Breakpoints > 0)
     9314        pDbgState->bmXcptExtra |= RT_BIT_32(X86_XCPT_BP);
    93079315
    93089316    /*
     
    1040610414    if (   !pVCpu->hm.s.fUseDebugLoop
    1040710415        && (!VBOXVMM_ANY_PROBES_ENABLED() || !hmR0VmxAnyExpensiveProbesEnabled())
    10408         && !DBGFIsStepping(pVCpu) )
     10416        && !DBGFIsStepping(pVCpu)
     10417        && !pVM->dbgf.ro.cEnabledInt3Breakpoints)
    1040910418        rcStrict = hmR0VmxRunGuestCodeNormal(pVM, pVCpu, pCtx);
    1041010419    else
  • trunk/src/VBox/VMM/VMMR3/DBGFAddr.cpp

    r62478 r64770  
    237237 * @param   pGCPhys         Where to return the physical address.
    238238 */
    239 static DECLCALLBACK(int) dbgfR3AddrToPhysOnVCpu(PVMCPU pVCpu, PDBGFADDRESS pAddress, PRTGCPHYS pGCPhys)
     239static DECLCALLBACK(int) dbgfR3AddrToPhysOnVCpu(PVMCPU pVCpu, PCDBGFADDRESS pAddress, PRTGCPHYS pGCPhys)
    240240{
    241241    VMCPU_ASSERT_EMT(pVCpu);
     
    265265 * @param   pGCPhys         Where to return the physical address.
    266266 */
    267 VMMR3DECL(int)  DBGFR3AddrToPhys(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddress, PRTGCPHYS pGCPhys)
     267VMMR3DECL(int)  DBGFR3AddrToPhys(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, PRTGCPHYS pGCPhys)
    268268{
    269269    /*
  • trunk/src/VBox/VMM/VMMR3/DBGFBp.cpp

    r64530 r64770  
    4242
    4343/*********************************************************************************************************************************
     44*   Structures and Typedefs                                                                                                      *
     45*********************************************************************************************************************************/
     46/**
     47 * DBGF INT3-breakpoint set callback arguments.
     48 */
     49typedef struct DBGFBPINT3ARGS
     50{
     51    /** The source virtual CPU ID (used for breakpoint address resolution). */
     52    VMCPUID         idSrcCpu;
     53    /** The breakpoint address. */
     54    PCDBGFADDRESS   pAddress;
     55    /** The hit count at which the breakpoint starts triggering. */
     56    uint64_t        iHitTrigger;
     57    /** The hit count at which disables the breakpoint. */
     58    uint64_t        iHitDisable;
     59    /** Where to store the breakpoint Id (optional). */
     60    uint32_t       *piBp;
     61} DBGFBPINT3ARGS;
     62/** Pointer to a DBGF INT3 breakpoint set callback argument. */
     63typedef DBGFBPINT3ARGS *PDBGFBPINT3ARGS;
     64
     65
     66/*********************************************************************************************************************************
    4467*   Internal Functions                                                                                                           *
    4568*********************************************************************************************************************************/
    4669RT_C_DECLS_BEGIN
    4770static int dbgfR3BpRegArm(PVM pVM, PDBGFBP pBp);
    48 static int dbgfR3BpInt3Arm(PUVM pUVM, PDBGFBP pBp);
     71static int dbgfR3BpInt3Arm(PVM pVM, PDBGFBP pBp);
    4972RT_C_DECLS_END
    5073
     
    166189
    167190/**
    168  * Updates IOM on whether we've got any armed I/O port or MMIO breakpoints.
    169  *
    170  * @returns VINF_SUCCESS
     191 * Updates the search optimization structure for enabled breakpoints of the
     192 * specified type.
     193 *
     194 * @returns VINF_SUCCESS.
    171195 * @param   pVM         The cross context VM structure.
    172196 * @param   enmType     The breakpoint type.
     
    317341
    318342/**
    319  * Sets a breakpoint (int 3 based).
    320  *
    321  * @returns VBox status code.
    322  * @param   pUVM            The user mode VM handle.
    323  * @param   pAddress        The address of the breakpoint.
    324  * @param   piHitTrigger    The hit count at which the breakpoint start triggering.
    325  *                          Use 0 (or 1) if it's gonna trigger at once.
    326  * @param   piHitDisable    The hit count which disables the breakpoint.
    327  *                          Use ~(uint64_t) if it's never gonna be disabled.
    328  * @param   piBp            Where to store the breakpoint id. (optional)
    329  * @thread  Any thread.
    330  */
    331 static DECLCALLBACK(int) dbgfR3BpSetInt3(PUVM pUVM, PCDBGFADDRESS pAddress, uint64_t *piHitTrigger,
    332                                          uint64_t *piHitDisable, uint32_t *piBp)
     343 * @callback_method_impl{FNVMMEMTRENDEZVOUS}
     344 */
     345static DECLCALLBACK(VBOXSTRICTRC) dbgfR3BpEnableInt3OnCpu(PVM pVM, PVMCPU pVCpu, void *pvUser)
    333346{
    334347    /*
    335348     * Validate input.
    336349     */
    337     PVM pVM = pUVM->pVM;
     350    PDBGFBP pBp = (PDBGFBP)pvUser;
     351    AssertReturn(pBp, VERR_INVALID_PARAMETER);
     352    Assert(pBp->enmType == DBGFBPTYPE_INT3);
     353    VMCPU_ASSERT_EMT(pVCpu); RT_NOREF(pVCpu);
    338354    VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
    339     if (!DBGFR3AddrIsValid(pUVM, pAddress))
     355
     356    /*
     357     * Arm the breakpoint.
     358     */
     359    return dbgfR3BpInt3Arm(pVM, pBp);
     360}
     361
     362
     363/**
     364 * @callback_method_impl{FNVMMEMTRENDEZVOUS}
     365 */
     366static DECLCALLBACK(VBOXSTRICTRC) dbgfR3BpSetInt3OnCpu(PVM pVM, PVMCPU pVCpu, void *pvUser)
     367{
     368    /*
     369     * Validate input.
     370     */
     371    PDBGFBPINT3ARGS pBpArgs = (PDBGFBPINT3ARGS)pvUser;
     372    AssertReturn(pBpArgs, VERR_INVALID_PARAMETER);
     373    VMCPU_ASSERT_EMT(pVCpu);
     374    VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
     375
     376    AssertMsgReturn(!pBpArgs->piBp || VALID_PTR(pBpArgs->piBp), ("piBp=%p\n", pBpArgs->piBp), VERR_INVALID_POINTER);
     377    PCDBGFADDRESS pAddress = pBpArgs->pAddress;
     378    if (!DBGFR3AddrIsValid(pVM->pUVM, pAddress))
    340379        return VERR_INVALID_PARAMETER;
    341     if (*piHitTrigger > *piHitDisable)
     380
     381    if (pBpArgs->iHitTrigger > pBpArgs->iHitDisable)
    342382        return VERR_INVALID_PARAMETER;
    343     AssertMsgReturn(!piBp || VALID_PTR(piBp), ("piBp=%p\n", piBp), VERR_INVALID_POINTER);
    344     if (piBp)
    345         *piBp = UINT32_MAX;
    346 
    347     /*
    348      * Check if the breakpoint already exists.
    349      */
    350     PDBGFBP pBp = dbgfR3BpGetByAddr(pVM, DBGFBPTYPE_INT3, pAddress->FlatPtr);
    351     if (pBp)
    352     {
    353         int rc = VINF_SUCCESS;
    354         if (!pBp->fEnabled)
    355             rc = dbgfR3BpInt3Arm(pUVM, pBp);
     383
     384    /*
     385     * Check if we're on the source CPU where we can resolve the breakpoint address.
     386     */
     387    if (pVCpu->idCpu == pBpArgs->idSrcCpu)
     388    {
     389        if (pBpArgs->piBp)
     390            *pBpArgs->piBp = UINT32_MAX;
     391
     392        /*
     393         * Check if the breakpoint already exists.
     394         */
     395        PDBGFBP pBp = dbgfR3BpGetByAddr(pVM, DBGFBPTYPE_INT3, pAddress->FlatPtr);
     396        if (pBp)
     397        {
     398            int rc = VINF_SUCCESS;
     399            if (!pBp->fEnabled)
     400                rc = dbgfR3BpInt3Arm(pVM, pBp);
     401            if (RT_SUCCESS(rc))
     402            {
     403                if (pBpArgs->piBp)
     404                    *pBpArgs->piBp = pBp->iBp;
     405
     406                /*
     407                 * Returning VINF_DBGF_BP_ALREADY_EXIST here causes a VBOXSTRICTRC out-of-range assertion
     408                 * in VMMR3EmtRendezvous(). Re-setting of an existing breakpoint shouldn't cause an assertion
     409                 * killing the VM (and debugging session), so for now we'll pretend success.
     410                 */
     411#if 0
     412                rc = VINF_DBGF_BP_ALREADY_EXIST;
     413#endif
     414            }
     415            else
     416                dbgfR3BpFree(pVM, pBp);
     417            return rc;
     418        }
     419
     420        /*
     421         * Allocate the breakpoint.
     422         */
     423        pBp = dbgfR3BpAlloc(pVM, DBGFBPTYPE_INT3);
     424        if (!pBp)
     425            return VERR_DBGF_NO_MORE_BP_SLOTS;
     426
     427        /*
     428         * Translate & save the breakpoint address into a guest-physical address.
     429         */
     430        int rc = DBGFR3AddrToPhys(pVM->pUVM, pBpArgs->idSrcCpu, pAddress, &pBp->u.Int3.PhysAddr);
    356431        if (RT_SUCCESS(rc))
    357432        {
    358             rc = VINF_DBGF_BP_ALREADY_EXIST;
    359             if (piBp)
    360                 *piBp = pBp->iBp;
     433            /* The physical address from DBGFR3AddrToPhys() is the start of the page,
     434               we need the exact byte offset into the page while writing to it in dbgfR3BpInt3Arm(). */
     435            pBp->u.Int3.PhysAddr |= (pAddress->FlatPtr & X86_PAGE_OFFSET_MASK);
     436            pBp->u.Int3.GCPtr = pAddress->FlatPtr;
     437            pBp->iHitTrigger  = pBpArgs->iHitTrigger;
     438            pBp->iHitDisable  = pBpArgs->iHitDisable;
     439
     440            /*
     441             * Now set the breakpoint in guest memory.
     442             */
     443            rc = dbgfR3BpInt3Arm(pVM, pBp);
     444            if (RT_SUCCESS(rc))
     445            {
     446                if (pBpArgs->piBp)
     447                    *pBpArgs->piBp = pBp->iBp;
     448                return VINF_SUCCESS;
     449            }
    361450        }
     451
     452        dbgfR3BpFree(pVM, pBp);
    362453        return rc;
    363454    }
    364455
    365     /*
    366      * Allocate and initialize the bp.
    367      */
    368     pBp = dbgfR3BpAlloc(pVM, DBGFBPTYPE_INT3);
    369     if (!pBp)
    370         return VERR_DBGF_NO_MORE_BP_SLOTS;
    371     pBp->u.Int3.GCPtr   = pAddress->FlatPtr;
    372     pBp->iHitTrigger    = *piHitTrigger;
    373     pBp->iHitDisable    = *piHitDisable;
    374     ASMCompilerBarrier();
    375     pBp->fEnabled       = true;
    376     dbgfR3BpUpdateSearchOptimizations(pVM, DBGFBPTYPE_INT3, &pVM->dbgf.s.Int3);
    377 
    378     /*
    379      * Now ask REM to set the breakpoint.
    380      */
    381     int rc = dbgfR3BpInt3Arm(pUVM, pBp);
    382     if (RT_SUCCESS(rc))
    383     {
    384         if (piBp)
    385             *piBp = pBp->iBp;
    386     }
    387     else
    388         dbgfR3BpFree(pVM, pBp);
    389 
    390     return rc;
     456    return VINF_SUCCESS;
    391457}
    392458
     
    397463 * @returns VBox status code.
    398464 * @param   pUVM        The user mode VM handle.
     465 * @param   idSrcCpu    The ID of the virtual CPU used for the
     466 *                      breakpoint address resolution.
    399467 * @param   pAddress    The address of the breakpoint.
    400468 * @param   iHitTrigger The hit count at which the breakpoint start triggering.
     
    405473 * @thread  Any thread.
    406474 */
    407 VMMR3DECL(int) DBGFR3BpSet(PUVM pUVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable, uint32_t *piBp)
    408 {
    409     /*
    410      * This must be done on EMT.
    411      */
    412     int rc = VMR3ReqCallWaitU(pUVM, 0 /*idDstCpu*/, (PFNRT)dbgfR3BpSetInt3, 5,
    413                               pUVM, pAddress, &iHitTrigger, &iHitDisable, piBp);
     475VMMR3DECL(int) DBGFR3BpSetInt3(PUVM pUVM, VMCPUID idSrcCpu, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable,
     476                               uint32_t *piBp)
     477{
     478    AssertReturn(idSrcCpu <= pUVM->cCpus, VERR_INVALID_CPU_ID);
     479
     480    DBGFBPINT3ARGS BpArgs;
     481    RT_ZERO(BpArgs);
     482    BpArgs.idSrcCpu    = idSrcCpu;
     483    BpArgs.iHitTrigger = iHitTrigger;
     484    BpArgs.iHitDisable = iHitDisable;
     485    BpArgs.pAddress    = pAddress;
     486    BpArgs.piBp        = piBp;
     487
     488    int rc = VMMR3EmtRendezvous(pUVM->pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ALL_AT_ONCE, dbgfR3BpSetInt3OnCpu, &BpArgs);
    414489    LogFlow(("DBGFR3BpSet: returns %Rrc\n", rc));
    415490    return rc;
     
    419494/**
    420495 * Arms an int 3 breakpoint.
    421  * This is used to implement both DBGFR3BpSetReg() and DBGFR3BpEnable().
    422  *
    423  * @returns VBox status code.
    424  * @param   pUVM        The user mode VM handle.
     496 *
     497 * This is used to implement both DBGFR3BpSetInt3() and
     498 * DBGFR3BpEnable().
     499 *
     500 * @returns VBox status code.
     501 * @param   pVM         The cross context VM structure.
    425502 * @param   pBp         The breakpoint.
    426503 */
    427 static int dbgfR3BpInt3Arm(PUVM pUVM, PDBGFBP pBp)
    428 {
    429     /** @todo should actually use physical address here! */
    430 
    431     /** @todo SMP support! */
    432     VMCPUID idCpu = 0;
    433 
    434     /*
    435      * Save current byte and write int3 instruction.
    436      */
    437     DBGFADDRESS Addr;
    438     DBGFR3AddrFromFlat(pUVM, &Addr, pBp->u.Int3.GCPtr);
    439     int rc = DBGFR3MemRead(pUVM, idCpu, &Addr, &pBp->u.Int3.bOrg, 1);
     504static int dbgfR3BpInt3Arm(PVM pVM, PDBGFBP pBp)
     505{
     506    VM_ASSERT_EMT(pVM);
     507
     508    /*
     509     * Save current byte and write the int3 instruction byte.
     510     */
     511    int rc = PGMPhysSimpleReadGCPhys(pVM, &pBp->u.Int3.bOrg, pBp->u.Int3.PhysAddr, sizeof(pBp->u.Int3.bOrg));
    440512    if (RT_SUCCESS(rc))
    441513    {
    442514        static const uint8_t s_bInt3 = 0xcc;
    443         rc = DBGFR3MemWrite(pUVM, idCpu, &Addr, &s_bInt3, 1);
     515        rc = PGMPhysSimpleWriteGCPhys(pVM, pBp->u.Int3.PhysAddr, &s_bInt3, sizeof(s_bInt3));
     516        if (RT_SUCCESS(rc))
     517        {
     518            pBp->fEnabled = true;
     519            dbgfR3BpUpdateSearchOptimizations(pVM, DBGFBPTYPE_INT3, &pVM->dbgf.s.Int3);
     520            pVM->dbgf.s.cEnabledInt3Breakpoints = pVM->dbgf.s.Int3.cToSearch;
     521            Log(("DBGF: Set breakpoint at %RGv (Phys %RGp) cEnabledInt3Breakpoints=%u\n", pBp->u.Int3.GCPtr,
     522                 pBp->u.Int3.PhysAddr, pVM->dbgf.s.cEnabledInt3Breakpoints));
     523        }
    444524    }
    445525    return rc;
     
    449529/**
    450530 * Disarms an int 3 breakpoint.
     531 *
    451532 * This is used to implement both DBGFR3BpClear() and DBGFR3BpDisable().
    452533 *
    453534 * @returns VBox status code.
    454  * @param   pUVM        The user mode VM handle.
     535 * @param   pVM         The cross context VM structure.
    455536 * @param   pBp         The breakpoint.
    456537 */
    457 static int dbgfR3BpInt3Disarm(PUVM pUVM, PDBGFBP pBp)
    458 {
    459     /** @todo SMP support! */
    460     VMCPUID idCpu = 0;
     538static int dbgfR3BpInt3Disarm(PVM pVM, PDBGFBP pBp)
     539{
     540    VM_ASSERT_EMT(pVM);
    461541
    462542    /*
     
    464544     * We currently ignore invalid bytes.
    465545     */
    466     DBGFADDRESS     Addr;
    467     DBGFR3AddrFromFlat(pUVM, &Addr, pBp->u.Int3.GCPtr);
    468     uint8_t         bCurrent;
    469     int rc = DBGFR3MemRead(pUVM, idCpu, &Addr, &bCurrent, 1);
    470     if (bCurrent == 0xcc)
    471         rc = DBGFR3MemWrite(pUVM, idCpu, &Addr, &pBp->u.Int3.bOrg, 1);
     546    uint8_t bCurrent = 0;
     547    int rc = PGMPhysSimpleReadGCPhys(pVM, &bCurrent, pBp->u.Int3.PhysAddr, sizeof(bCurrent));
     548    if (   RT_SUCCESS(rc)
     549        && bCurrent == 0xcc)
     550    {
     551        rc = PGMPhysSimpleWriteGCPhys(pVM, pBp->u.Int3.PhysAddr, &pBp->u.Int3.bOrg, sizeof(pBp->u.Int3.bOrg));
     552        if (RT_SUCCESS(rc))
     553        {
     554            pBp->fEnabled = false;
     555            dbgfR3BpUpdateSearchOptimizations(pVM, DBGFBPTYPE_INT3, &pVM->dbgf.s.Int3);
     556            pVM->dbgf.s.cEnabledInt3Breakpoints = pVM->dbgf.s.Int3.cToSearch;
     557            Log(("DBGF: Removed breakpoint at %RGv (Phys %RGp) cEnabledInt3Breakpoints=%u\n", pBp->u.Int3.GCPtr,
     558                 pBp->u.Int3.PhysAddr, pVM->dbgf.s.cEnabledInt3Breakpoints));
     559        }
     560    }
    472561    return rc;
     562}
     563
     564
     565/**
     566 * @callback_method_impl{FNVMMEMTRENDEZVOUS}
     567 */
     568static DECLCALLBACK(VBOXSTRICTRC) dbgfR3BpDisableInt3OnCpu(PVM pVM, PVMCPU pVCpu, void *pvUser)
     569{
     570    /*
     571     * Validate input.
     572     */
     573    PDBGFBP pBp = (PDBGFBP)pvUser;
     574    AssertReturn(pBp, VERR_INVALID_PARAMETER);
     575    Assert(pBp->enmType == DBGFBPTYPE_INT3);
     576    VMCPU_ASSERT_EMT(pVCpu); RT_NOREF(pVCpu);
     577    VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
     578
     579    /*
     580     * Disarm the breakpoint.
     581     */
     582    return dbgfR3BpInt3Disarm(pVM, pBp);
    473583}
    474584
     
    9661076     * Allocate and initialize the breakpoint.
    9671077     */
    968     PDBGFBP pBp = dbgfR3BpAlloc(pVM, DBGFBPTYPE_PORT_IO);
     1078    PDBGFBP pBp = dbgfR3BpAlloc(pVM, DBGFBPTYPE_MMIO);
    9691079    if (!pBp)
    9701080        return VERR_DBGF_NO_MORE_BP_SLOTS;
     
    10411151     */
    10421152    PVM pVM = pUVM->pVM;
     1153    VM_ASSERT_EMT(pVM);
    10431154    VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
    10441155    PDBGFBP pBp = dbgfR3BpGet(pVM, iBp);
     
    10601171
    10611172            case DBGFBPTYPE_INT3:
    1062                 rc = dbgfR3BpInt3Disarm(pUVM, pBp);
    1063                 dbgfR3BpUpdateSearchOptimizations(pVM, DBGFBPTYPE_INT3, &pVM->dbgf.s.Int3);
     1173                rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ONCE, dbgfR3BpDisableInt3OnCpu, pBp);
    10641174                break;
    10651175
     
    11371247
    11381248    /*
    1139      * Remove the breakpoint.
     1249     * Arm the breakpoint.
    11401250     */
    11411251    int rc;
     
    11481258
    11491259        case DBGFBPTYPE_INT3:
    1150             dbgfR3BpUpdateSearchOptimizations(pVM, DBGFBPTYPE_INT3, &pVM->dbgf.s.Int3);
    1151             rc = dbgfR3BpInt3Arm(pUVM, pBp);
     1260            rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ONCE, dbgfR3BpEnableInt3OnCpu, pBp);
    11521261            break;
    11531262
     
    12321341
    12331342        case DBGFBPTYPE_INT3:
    1234             rc = dbgfR3BpInt3Disarm(pUVM, pBp);
    1235             dbgfR3BpUpdateSearchOptimizations(pVM, DBGFBPTYPE_INT3, &pVM->dbgf.s.Int3);
     1343            rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ONCE, dbgfR3BpDisableInt3OnCpu, pBp);
    12361344            break;
    12371345
     
    13371445     */
    13381446    int rc = VMR3ReqPriorityCallWaitU(pUVM, 0 /*idDstCpu*/, (PFNRT)dbgfR3BpEnum, 3, pUVM, pfnCallback, pvUser);
    1339     LogFlow(("DBGFR3BpClear: returns %Rrc\n", rc));
     1447    LogFlow(("DBGFR3BpEnum: returns %Rrc\n", rc));
    13401448    return rc;
    13411449}
  • trunk/src/VBox/VMM/VMMR3/DBGFMem.cpp

    r62478 r64770  
    161161
    162162    /*
    163      * HMA is special
     163     * HMA is special.
    164164     */
    165165    int rc;
     
    174174    {
    175175        /*
    176          * Select DBGF worker by addressing mode.
     176         * Select PGM worker by addressing mode.
    177177         */
    178178        PVMCPU  pVCpu   = VMMGetCpuById(pVM, idCpu);
  • trunk/src/VBox/VMM/include/DBGFInternal.h

    r64720 r64770  
    209209    uint32_t                    cSoftIntBreakpoints;
    210210
    211     /** Number of selected events. */
     211    /** The number of selected events. */
    212212    uint32_t                    cSelectedEvents;
     213
     214    /** The number of enabled hardware breakpoints. */
     215    uint8_t                     cEnabledHwBreakpoints;
     216    /** The number of enabled hardware I/O breakpoints. */
     217    uint8_t                     cEnabledHwIoBreakpoints;
     218    /** The number of enabled INT3 breakpoints. */
     219    uint8_t                     cEnabledInt3Breakpoints;
     220    uint8_t                     abPadding; /**< Unused padding space up for grabs. */
     221    uint32_t                    uPadding;
    213222
    214223    /** Debugger Attached flag.
     
    276285    } SteppingFilter;
    277286
    278     uint32_t                    u32Padding; /**< Alignment padding. */
    279 
    280     /** The number of enabled hardware breakpoints. */
    281     uint8_t                     cEnabledHwBreakpoints;
    282     /** The number of enabled hardware I/O breakpoints. */
    283     uint8_t                     cEnabledHwIoBreakpoints;
    284     uint8_t                     abPadding[2]; /**< Unused padding space up for grabs. */
     287    uint32_t                    u32Padding[2]; /**< Alignment padding. */
    285288
    286289    /** Array of hardware breakpoints. (0..3)
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