aboutsummaryrefslogtreecommitdiff
path: root/softmmu
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2023-02-22 22:16:51 -1000
committerRichard Henderson <richard.henderson@linaro.org>2023-03-05 13:44:07 -0800
commit019a98083a57861475461fd63895240b5c341077 (patch)
tree0728a302d360e5d18bf0d9caa7053c6f76bffe87 /softmmu
parent0953674ed0acacfa9b2409678f8ce8333398ee1c (diff)
softmmu: Check watchpoints for read+write at once
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é <philmd@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'softmmu')
-rw-r--r--softmmu/watchpoint.c19
1 files changed, 10 insertions, 9 deletions
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;
}