[PATCH] target/riscv: Fix index of fired breakpoint and watchpoint

Alvin Chang via posted 1 patch 1 day, 1 hour ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20251128080928.3160155-1-alvinga@andestech.com
Maintainers: Palmer Dabbelt <palmer@dabbelt.com>, Alistair Francis <alistair.francis@wdc.com>, Weiwei Li <liwei1518@gmail.com>, Daniel Henrique Barboza <dbarboza@ventanamicro.com>, Liu Zhiwei <zhiwei_liu@linux.alibaba.com>
target/riscv/debug.c | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
[PATCH] target/riscv: Fix index of fired breakpoint and watchpoint
Posted by Alvin Chang via 1 day, 1 hour ago
The do_trigger_action() receives index of fired trigger as second
parameter. However, in current implementation, the argument is hardcoded
as DBG_ACTION_BP which is 0. This is a bug because we may match/fire any
breakpoints or watchpoints at other index than 0.

Fix this bug by iterating cpu_breakpoint[] and cpu_watchpoint[] to
compare and match necessary checkpoints. The index of the fired
cpu_breakpoint or the cpu_watchpoint is the index of the trigger we want
to provide to do_trigger_action().

Signed-off-by: Alvin Chang <alvinga@andestech.com>
Reviewed-by: Yu-Ming Chang <yumin686@andestech.com>
---
 target/riscv/debug.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/target/riscv/debug.c b/target/riscv/debug.c
index 5664466..f3bca8e 100644
--- a/target/riscv/debug.c
+++ b/target/riscv/debug.c
@@ -929,11 +929,24 @@ void riscv_cpu_debug_excp_handler(CPUState *cs)
 
     if (cs->watchpoint_hit) {
         if (cs->watchpoint_hit->flags & BP_CPU) {
-            do_trigger_action(env, DBG_ACTION_BP);
+            /* Search fired trigger and do its action */
+            for (int i = 0; i < ARRAY_SIZE(env->cpu_watchpoint); i++) {
+                if (cs->watchpoint_hit == env->cpu_watchpoint[i]) {
+                    do_trigger_action(env, i);
+                    break;
+                }
+            }
         }
     } else {
         if (cpu_breakpoint_test(cs, env->pc, BP_CPU)) {
-            do_trigger_action(env, DBG_ACTION_BP);
+            /* Search fired trigger and do its action */
+            for (int i = 0; i < ARRAY_SIZE(env->cpu_breakpoint); i++) {
+                CPUBreakpoint *bp = env->cpu_breakpoint[i];
+                if (bp && bp->pc == env->pc && (bp->flags & BP_CPU)) {
+                    do_trigger_action(env, i);
+                    break;
+                }
+            }
         }
     }
 }
-- 
2.43.0
Re: [PATCH] target/riscv: Fix index of fired breakpoint and watchpoint
Posted by Daniel Henrique Barboza 21 hours ago

On 11/28/25 5:09 AM, Alvin Chang wrote:
> The do_trigger_action() receives index of fired trigger as second
> parameter. However, in current implementation, the argument is hardcoded
> as DBG_ACTION_BP which is 0. This is a bug because we may match/fire any
> breakpoints or watchpoints at other index than 0.
> 
> Fix this bug by iterating cpu_breakpoint[] and cpu_watchpoint[] to
> compare and match necessary checkpoints. The index of the fired
> cpu_breakpoint or the cpu_watchpoint is the index of the trigger we want
> to provide to do_trigger_action().
> 
> Signed-off-by: Alvin Chang <alvinga@andestech.com>
> Reviewed-by: Yu-Ming Chang <yumin686@andestech.com>
> ---


Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>

>   target/riscv/debug.c | 17 +++++++++++++++--
>   1 file changed, 15 insertions(+), 2 deletions(-)
> 
> diff --git a/target/riscv/debug.c b/target/riscv/debug.c
> index 5664466..f3bca8e 100644
> --- a/target/riscv/debug.c
> +++ b/target/riscv/debug.c
> @@ -929,11 +929,24 @@ void riscv_cpu_debug_excp_handler(CPUState *cs)
>   
>       if (cs->watchpoint_hit) {
>           if (cs->watchpoint_hit->flags & BP_CPU) {
> -            do_trigger_action(env, DBG_ACTION_BP);
> +            /* Search fired trigger and do its action */
> +            for (int i = 0; i < ARRAY_SIZE(env->cpu_watchpoint); i++) {
> +                if (cs->watchpoint_hit == env->cpu_watchpoint[i]) {
> +                    do_trigger_action(env, i);
> +                    break;
> +                }
> +            }
>           }
>       } else {
>           if (cpu_breakpoint_test(cs, env->pc, BP_CPU)) {
> -            do_trigger_action(env, DBG_ACTION_BP);
> +            /* Search fired trigger and do its action */
> +            for (int i = 0; i < ARRAY_SIZE(env->cpu_breakpoint); i++) {
> +                CPUBreakpoint *bp = env->cpu_breakpoint[i];
> +                if (bp && bp->pc == env->pc && (bp->flags & BP_CPU)) {
> +                    do_trigger_action(env, i);
> +                    break;
> +                }
> +            }
>           }
>       }
>   }