From 019a98083a57861475461fd63895240b5c341077 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 22 Feb 2023 22:16:51 -1000 Subject: [PATCH] softmmu: Check watchpoints for read+write at once MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Atomic operations are read-modify-write, and we'd like to be able to test both read and write with one call. This is easy enough, with BP_MEM_READ | BP_MEM_WRITE. Add BP_HIT_SHIFT to make it easy to set BP_WATCHPOINT_HIT_*. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- include/hw/core/cpu.h | 7 ++++--- softmmu/watchpoint.c | 19 ++++++++++--------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h index fb5d9667ca..75689bff02 100644 --- a/include/hw/core/cpu.h +++ b/include/hw/core/cpu.h @@ -923,9 +923,10 @@ void cpu_single_step(CPUState *cpu, int enabled); #define BP_GDB 0x10 #define BP_CPU 0x20 #define BP_ANY (BP_GDB | BP_CPU) -#define BP_WATCHPOINT_HIT_READ 0x40 -#define BP_WATCHPOINT_HIT_WRITE 0x80 -#define BP_WATCHPOINT_HIT (BP_WATCHPOINT_HIT_READ | BP_WATCHPOINT_HIT_WRITE) +#define BP_HIT_SHIFT 6 +#define BP_WATCHPOINT_HIT_READ (BP_MEM_READ << BP_HIT_SHIFT) +#define BP_WATCHPOINT_HIT_WRITE (BP_MEM_WRITE << BP_HIT_SHIFT) +#define BP_WATCHPOINT_HIT (BP_MEM_ACCESS << BP_HIT_SHIFT) int cpu_breakpoint_insert(CPUState *cpu, vaddr pc, int flags, CPUBreakpoint **breakpoint); diff --git a/softmmu/watchpoint.c b/softmmu/watchpoint.c index 279129dd1c..ad58736787 100644 --- a/softmmu/watchpoint.c +++ b/softmmu/watchpoint.c @@ -162,9 +162,12 @@ void cpu_check_watchpoint(CPUState *cpu, vaddr addr, vaddr len, /* this is currently used only by ARM BE32 */ addr = cc->tcg_ops->adjust_watchpoint_address(cpu, addr, len); } + + assert((flags & ~BP_MEM_ACCESS) == 0); QTAILQ_FOREACH(wp, &cpu->watchpoints, entry) { - if (watchpoint_address_matches(wp, addr, len) - && (wp->flags & flags)) { + int hit_flags = wp->flags & flags; + + if (hit_flags && watchpoint_address_matches(wp, addr, len)) { if (replay_running_debug()) { /* * replay_breakpoint reads icount. @@ -184,16 +187,14 @@ void cpu_check_watchpoint(CPUState *cpu, vaddr addr, vaddr len, replay_breakpoint(); return; } - if (flags == BP_MEM_READ) { - wp->flags |= BP_WATCHPOINT_HIT_READ; - } else { - wp->flags |= BP_WATCHPOINT_HIT_WRITE; - } + + wp->flags |= hit_flags << BP_HIT_SHIFT; wp->hitaddr = MAX(addr, wp->vaddr); wp->hitattrs = attrs; - if (wp->flags & BP_CPU && cc->tcg_ops->debug_check_watchpoint && - !cc->tcg_ops->debug_check_watchpoint(cpu, wp)) { + if (wp->flags & BP_CPU + && cc->tcg_ops->debug_check_watchpoint + && !cc->tcg_ops->debug_check_watchpoint(cpu, wp)) { wp->flags &= ~BP_WATCHPOINT_HIT; continue; }