Record the CPUBreakpoint in check_for_breakpoints_slow, into a new CPUState field, so that the as-yet unconverted target debug_excp_handler functions won't see it.
Only call debug_excp_handler for BP_CPU, and clear the CPUState fields after the call. This will allow these actions to be dropped from the target hook. Signed-off-by: Richard Henderson <[email protected]> --- include/hw/core/cpu.h | 1 + accel/tcg/cpu-exec.c | 32 +++++++++++++++++++++++--------- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h index 3986e43f84..1a42940d92 100644 --- a/include/hw/core/cpu.h +++ b/include/hw/core/cpu.h @@ -526,6 +526,7 @@ struct CPUState { /* ice debug support */ IntervalTreeRoot breakpoints; IntervalTreeRoot watchpoints; + CPUBreakpoint *breakpoint_hit; CPUBreakpoint *watchpoint_hit; void *opaque; diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c index 3205f365e5..a4eb1f1c31 100644 --- a/accel/tcg/cpu-exec.c +++ b/accel/tcg/cpu-exec.c @@ -363,6 +363,10 @@ static bool check_for_breakpoints_slow(CPUState *cpu, vaddr pc, return false; found: + bp->hitaddr = pc; + bp->hitlast = pc; + bp->hitattrs = MEMTXATTRS_UNSPECIFIED; + cpu->breakpoint_hit = bp; cpu->exception_index = EXCP_DEBUG; return true; } @@ -681,19 +685,29 @@ static inline bool cpu_handle_halt(CPUState *cpu) static inline void cpu_handle_debug_exception(CPUState *cpu) { - const TCGCPUOps *tcg_ops = cpu->cc->tcg_ops; - IntervalTreeNode *n; + CPUBreakpoint *hit = cpu->watchpoint_hit; - for (n = interval_tree_iter_first(&cpu->watchpoints, 0, -1); n; - n = interval_tree_iter_next(n, 0, -1)) { - CPUBreakpoint *wp = container_of(n, CPUBreakpoint, itree); - if (wp != cpu->watchpoint_hit) { - wp->flags &= ~BP_WATCHPOINT_HIT; + if (hit) { + IntervalTreeNode *n; + + for (n = interval_tree_iter_first(&cpu->watchpoints, 0, -1); n; + n = interval_tree_iter_next(n, 0, -1)) { + CPUBreakpoint *wp = container_of(n, CPUBreakpoint, itree); + if (wp != hit) { + wp->flags &= ~BP_WATCHPOINT_HIT; + } + } + } else { + hit = cpu->breakpoint_hit; + if (!hit) { + return; } } - if (tcg_ops->debug_excp_handler) { - tcg_ops->debug_excp_handler(cpu, cpu->watchpoint_hit); + if (hit->flags & BP_CPU) { + cpu->cc->tcg_ops->debug_excp_handler(cpu, hit); + cpu->watchpoint_hit = NULL; + cpu->breakpoint_hit = NULL; } } -- 2.43.0
