From: Jesse Taube <jesse@rivosinc.com>
To: linux-riscv@lists.infradead.org
Cc: "Paul Walmsley" <paul.walmsley@sifive.com>,
"Palmer Dabbelt" <palmer@dabbelt.com>,
"Albert Ou" <aou@eecs.berkeley.edu>,
"Alexandre Ghiti" <alex@ghiti.fr>,
"Oleg Nesterov" <oleg@redhat.com>, "Kees Cook" <kees@kernel.org>,
"Peter Zijlstra" <peterz@infradead.org>,
"Ingo Molnar" <mingo@redhat.com>,
"Arnaldo Carvalho de Melo" <acme@kernel.org>,
"Namhyung Kim" <namhyung@kernel.org>,
"Mark Rutland" <mark.rutland@arm.com>,
"Alexander Shishkin" <alexander.shishkin@linux.intel.com>,
"Jiri Olsa" <jolsa@kernel.org>, "Ian Rogers" <irogers@google.com>,
"Adrian Hunter" <adrian.hunter@intel.com>,
"Liang, Kan" <kan.liang@linux.intel.com>,
"Shuah Khan" <shuah@kernel.org>,
"Jesse Taube" <jesse@rivosinc.com>,
"Himanshu Chauhan" <hchauhan@ventanamicro.com>,
"Charlie Jenkins" <charlie@rivosinc.com>,
"Samuel Holland" <samuel.holland@sifive.com>,
"Conor Dooley" <conor.dooley@microchip.com>,
"Deepak Gupta" <debug@rivosinc.com>,
"Andrew Jones" <ajones@ventanamicro.com>,
"Atish Patra" <atishp@rivosinc.com>,
"Anup Patel" <apatel@ventanamicro.com>,
"Mayuresh Chitale" <mchitale@ventanamicro.com>,
"Evan Green" <evan@rivosinc.com>,
WangYuli <wangyuli@uniontech.com>,
"Huacai Chen" <chenhuacai@kernel.org>,
"Arnd Bergmann" <arnd@arndb.de>,
"Andrew Morton" <akpm@linux-foundation.org>,
"Luis Chamberlain" <mcgrof@kernel.org>,
"Mike Rapoport (Microsoft)" <rppt@kernel.org>,
"Nam Cao" <namcao@linutronix.de>,
"Yunhui Cui" <cuiyunhui@bytedance.com>,
"Joel Granados" <joel.granados@kernel.org>,
"Clément Léger" <cleger@rivosinc.com>,
"Sebastian Andrzej Siewior" <bigeasy@linutronix.de>,
"Celeste Liu" <coelacanthushex@gmail.com>,
"Chunyan Zhang" <zhangchunyan@iscas.ac.cn>,
"Nylon Chen" <nylon.chen@sifive.com>,
"Thomas Gleixner" <tglx@linutronix.de>,
"Thomas Weißschuh" <thomas.weissschuh@linutronix.de>,
"Vincenzo Frascino" <vincenzo.frascino@arm.com>,
"Joey Gouly" <joey.gouly@arm.com>,
"Akihiko Odaki" <akihiko.odaki@daynix.com>,
"Ravi Bangoria" <ravi.bangoria@amd.com>,
linux-kernel@vger.kernel.org, linux-mm@kvack.org,
linux-perf-users@vger.kernel.org,
linux-kselftest@vger.kernel.org
Subject: [PATCH 6/8] riscv: ptrace: Add hw breakpoint support
Date: Tue, 5 Aug 2025 12:39:53 -0700 [thread overview]
Message-ID: <20250805193955.798277-7-jesse@rivosinc.com> (raw)
In-Reply-To: <20250805193955.798277-1-jesse@rivosinc.com>
Add ability to setup hw breakpoints to ptrace. Call defines a new
structure of __riscv_hwdebug_state which will be passed to ptrace.
Signed-off-by: Jesse Taube <jesse@rivosinc.com>
---
RFC -> V1:
- Add struct __riscv_hwdebug_state for ptrace_hbp_set/get
- Break out ptrace_hbp_set/get so regset can use them
- Check for NULL instead of IS_ERR_OR_NULL
- Move ptrace_get/sethbpregs above user_regset
---
arch/riscv/include/asm/processor.h | 4 +
arch/riscv/include/uapi/asm/ptrace.h | 9 +++
arch/riscv/kernel/hw_breakpoint.c | 14 +++-
arch/riscv/kernel/process.c | 4 +
arch/riscv/kernel/ptrace.c | 110 +++++++++++++++++++++++++++
5 files changed, 140 insertions(+), 1 deletion(-)
diff --git a/arch/riscv/include/asm/processor.h b/arch/riscv/include/asm/processor.h
index 5f56eb9d114a..488d956a951f 100644
--- a/arch/riscv/include/asm/processor.h
+++ b/arch/riscv/include/asm/processor.h
@@ -12,6 +12,7 @@
#include <vdso/processor.h>
+#include <asm/hw_breakpoint.h>
#include <asm/ptrace.h>
#define arch_get_mmap_end(addr, len, flags) \
@@ -108,6 +109,9 @@ struct thread_struct {
struct __riscv_v_ext_state vstate;
unsigned long align_ctl;
struct __riscv_v_ext_state kernel_vstate;
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+ struct perf_event *ptrace_bps[RV_MAX_TRIGGERS];
+#endif
#ifdef CONFIG_SMP
/* Flush the icache on migration */
bool force_icache_flush;
diff --git a/arch/riscv/include/uapi/asm/ptrace.h b/arch/riscv/include/uapi/asm/ptrace.h
index a38268b19c3d..20d1aa595cbd 100644
--- a/arch/riscv/include/uapi/asm/ptrace.h
+++ b/arch/riscv/include/uapi/asm/ptrace.h
@@ -14,6 +14,8 @@
#define PTRACE_GETFDPIC_EXEC 0
#define PTRACE_GETFDPIC_INTERP 1
+#define PTRACE_GETHBPREGS 2
+#define PTRACE_SETHBPREGS 3
/*
* User-mode register state for core dumps, ptrace, sigcontext
@@ -120,6 +122,13 @@ struct __riscv_v_regset_state {
char vreg[];
};
+struct __riscv_hwdebug_state {
+ unsigned long addr;
+ unsigned long type;
+ unsigned long len;
+ unsigned long ctrl;
+} __packed;
+
/*
* According to spec: The number of bits in a single vector register,
* VLEN >= ELEN, which must be a power of 2, and must be no greater than
diff --git a/arch/riscv/kernel/hw_breakpoint.c b/arch/riscv/kernel/hw_breakpoint.c
index 1e70ef9e6867..b1c9c40f5fde 100644
--- a/arch/riscv/kernel/hw_breakpoint.c
+++ b/arch/riscv/kernel/hw_breakpoint.c
@@ -721,7 +721,19 @@ void arch_uninstall_hw_breakpoint(struct perf_event *event)
pr_warn("%s: Failed to uninstall trigger %d. error: %ld\n", __func__, i, ret.error);
}
-void flush_ptrace_hw_breakpoint(struct task_struct *tsk) { }
+/*
+ * Release the user breakpoints used by ptrace
+ */
+void flush_ptrace_hw_breakpoint(struct task_struct *tsk)
+{
+ int i;
+ struct thread_struct *t = &tsk->thread;
+
+ for (i = 0; i < dbtr_total_num; i++) {
+ unregister_hw_breakpoint(t->ptrace_bps[i]);
+ t->ptrace_bps[i] = NULL;
+ }
+}
void hw_breakpoint_pmu_read(struct perf_event *bp) { }
diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c
index 15d8f75902f8..9cf07ecfb523 100644
--- a/arch/riscv/kernel/process.c
+++ b/arch/riscv/kernel/process.c
@@ -9,6 +9,7 @@
#include <linux/bitfield.h>
#include <linux/cpu.h>
+#include <linux/hw_breakpoint.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/sched/debug.h>
@@ -164,6 +165,7 @@ void start_thread(struct pt_regs *regs, unsigned long pc,
void flush_thread(void)
{
+ flush_ptrace_hw_breakpoint(current);
#ifdef CONFIG_FPU
/*
* Reset FPU state and context
@@ -218,6 +220,8 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
set_bit(MM_CONTEXT_LOCK_PMLEN, &p->mm->context.flags);
memset(&p->thread.s, 0, sizeof(p->thread.s));
+ if (IS_ENABLED(CONFIG_HAVE_HW_BREAKPOINT))
+ memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps));
/* p->thread holds context to be restored by __switch_to() */
if (unlikely(args->fn)) {
diff --git a/arch/riscv/kernel/ptrace.c b/arch/riscv/kernel/ptrace.c
index ea67e9fb7a58..e097e6a61910 100644
--- a/arch/riscv/kernel/ptrace.c
+++ b/arch/riscv/kernel/ptrace.c
@@ -9,11 +9,13 @@
#include <asm/vector.h>
#include <asm/ptrace.h>
+#include <asm/hw_breakpoint.h>
#include <asm/syscall.h>
#include <asm/thread_info.h>
#include <asm/switch_to.h>
#include <linux/audit.h>
#include <linux/compat.h>
+#include <linux/hw_breakpoint.h>
#include <linux/ptrace.h>
#include <linux/elf.h>
#include <linux/regset.h>
@@ -184,6 +186,104 @@ static int tagged_addr_ctrl_set(struct task_struct *target,
}
#endif
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+static void ptrace_hbptriggered(struct perf_event *bp,
+ struct perf_sample_data *data,
+ struct pt_regs *regs)
+{
+ struct arch_hw_breakpoint *bkpt = counter_arch_bp(bp);
+ int num = 0;
+
+ force_sig_ptrace_errno_trap(num, (void __user *)bkpt->address);
+}
+
+static int ptrace_hbp_get(struct task_struct *child, unsigned long idx,
+ struct __riscv_hwdebug_state *state)
+{
+ struct perf_event *bp;
+
+ if (idx >= RV_MAX_TRIGGERS)
+ return -EINVAL;
+
+ bp = child->thread.ptrace_bps[idx];
+
+ if (!bp)
+ return -ENOENT;
+
+ state->addr = bp->attr.bp_addr;
+ state->len = bp->attr.bp_len;
+ state->type = bp->attr.bp_type;
+ state->ctrl = bp->attr.disabled == 1;
+
+ return 0;
+}
+
+static int ptrace_hbp_set(struct task_struct *child, unsigned long idx,
+ struct __riscv_hwdebug_state *state)
+{
+ struct perf_event *bp;
+ struct perf_event_attr attr;
+
+ if (idx >= RV_MAX_TRIGGERS)
+ return -EINVAL;
+
+ bp = child->thread.ptrace_bps[idx];
+ if (bp)
+ attr = bp->attr;
+ else
+ ptrace_breakpoint_init(&attr);
+
+ attr.bp_addr = state->addr;
+ attr.bp_len = state->len;
+ attr.bp_type = state->type;
+ attr.disabled = state->ctrl == 1;
+
+ if (!bp) {
+ bp = register_user_hw_breakpoint(&attr, ptrace_hbptriggered, NULL,
+ child);
+ if (IS_ERR(bp))
+ return PTR_ERR(bp);
+
+ child->thread.ptrace_bps[idx] = bp;
+ return 0;
+ }
+
+ return modify_user_hw_breakpoint(bp, &attr);
+}
+
+/*
+ * idx selects the breakpoint index.
+ * Both PTRACE_GETHBPREGS and PTRACE_SETHBPREGS transfer __riscv_hwdebug_state
+ */
+
+static long ptrace_gethbpregs(struct task_struct *child, unsigned long idx,
+ unsigned long __user *datap)
+{
+ struct __riscv_hwdebug_state state;
+ long ret;
+
+ ret = ptrace_hbp_get(child, idx, &state);
+ if (ret)
+ return ret;
+ if (copy_to_user(datap, &state, sizeof(state)))
+ return -EFAULT;
+
+ return 0;
+}
+
+static long ptrace_sethbpregs(struct task_struct *child, unsigned long idx,
+ unsigned long __user *datap)
+{
+ struct __riscv_hwdebug_state state;
+
+ if (copy_from_user(&state, datap, sizeof(state)))
+ return -EFAULT;
+
+ return ptrace_hbp_set(child, idx, &state);
+
+}
+#endif
+
static const struct user_regset riscv_user_regset[] = {
[REGSET_X] = {
.core_note_type = NT_PRSTATUS,
@@ -340,8 +440,18 @@ long arch_ptrace(struct task_struct *child, long request,
unsigned long addr, unsigned long data)
{
long ret = -EIO;
+ unsigned long __user *datap = (unsigned long __user *) data;
switch (request) {
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+ case PTRACE_GETHBPREGS:
+ ret = ptrace_gethbpregs(child, addr, datap);
+ break;
+
+ case PTRACE_SETHBPREGS:
+ ret = ptrace_sethbpregs(child, addr, datap);
+ break;
+#endif
default:
ret = ptrace_request(child, request, addr, data);
break;
--
2.43.0
WARNING: multiple messages have this Message-ID (diff)
From: Jesse Taube <jesse@rivosinc.com>
To: linux-riscv@lists.infradead.org
Cc: "Paul Walmsley" <paul.walmsley@sifive.com>,
"Palmer Dabbelt" <palmer@dabbelt.com>,
"Albert Ou" <aou@eecs.berkeley.edu>,
"Alexandre Ghiti" <alex@ghiti.fr>,
"Oleg Nesterov" <oleg@redhat.com>, "Kees Cook" <kees@kernel.org>,
"Peter Zijlstra" <peterz@infradead.org>,
"Ingo Molnar" <mingo@redhat.com>,
"Arnaldo Carvalho de Melo" <acme@kernel.org>,
"Namhyung Kim" <namhyung@kernel.org>,
"Mark Rutland" <mark.rutland@arm.com>,
"Alexander Shishkin" <alexander.shishkin@linux.intel.com>,
"Jiri Olsa" <jolsa@kernel.org>, "Ian Rogers" <irogers@google.com>,
"Adrian Hunter" <adrian.hunter@intel.com>,
"Liang, Kan" <kan.liang@linux.intel.com>,
"Shuah Khan" <shuah@kernel.org>,
"Jesse Taube" <jesse@rivosinc.com>,
"Himanshu Chauhan" <hchauhan@ventanamicro.com>,
"Charlie Jenkins" <charlie@rivosinc.com>,
"Samuel Holland" <samuel.holland@sifive.com>,
"Conor Dooley" <conor.dooley@microchip.com>,
"Deepak Gupta" <debug@rivosinc.com>,
"Andrew Jones" <ajones@ventanamicro.com>,
"Atish Patra" <atishp@rivosinc.com>,
"Anup Patel" <apatel@ventanamicro.com>,
"Mayuresh Chitale" <mchitale@ventanamicro.com>,
"Evan Green" <evan@rivosinc.com>,
WangYuli <wangyuli@uniontech.com>,
"Huacai Chen" <chenhuacai@kernel.org>,
"Arnd Bergmann" <arnd@arndb.de>,
"Andrew Morton" <akpm@linux-foundation.org>,
"Luis Chamberlain" <mcgrof@kernel.org>,
"Mike Rapoport (Microsoft)" <rppt@kernel.org>,
"Nam Cao" <namcao@linutronix.de>,
"Yunhui Cui" <cuiyunhui@bytedance.com>,
"Joel Granados" <joel.granados@kernel.org>,
"Clément Léger" <cleger@rivosinc.com>,
"Sebastian Andrzej Siewior" <bigeasy@linutronix.de>,
"Celeste Liu" <coelacanthushex@gmail.com>,
"Chunyan Zhang" <zhangchunyan@iscas.ac.cn>,
"Nylon Chen" <nylon.chen@sifive.com>,
"Thomas Gleixner" <tglx@linutronix.de>,
"Thomas Weißschuh" <thomas.weissschuh@linutronix.de>,
"Vincenzo Frascino" <vincenzo.frascino@arm.com>,
"Joey Gouly" <joey.gouly@arm.com>,
"Akihiko Odaki" <akihiko.odaki@daynix.com>,
"Ravi Bangoria" <ravi.bangoria@amd.com>,
linux-kernel@vger.kernel.org, linux-mm@kvack.org,
linux-perf-users@vger.kernel.org,
linux-kselftest@vger.kernel.org
Subject: [PATCH 6/8] riscv: ptrace: Add hw breakpoint support
Date: Tue, 5 Aug 2025 12:39:53 -0700 [thread overview]
Message-ID: <20250805193955.798277-7-jesse@rivosinc.com> (raw)
In-Reply-To: <20250805193955.798277-1-jesse@rivosinc.com>
Add ability to setup hw breakpoints to ptrace. Call defines a new
structure of __riscv_hwdebug_state which will be passed to ptrace.
Signed-off-by: Jesse Taube <jesse@rivosinc.com>
---
RFC -> V1:
- Add struct __riscv_hwdebug_state for ptrace_hbp_set/get
- Break out ptrace_hbp_set/get so regset can use them
- Check for NULL instead of IS_ERR_OR_NULL
- Move ptrace_get/sethbpregs above user_regset
---
arch/riscv/include/asm/processor.h | 4 +
arch/riscv/include/uapi/asm/ptrace.h | 9 +++
arch/riscv/kernel/hw_breakpoint.c | 14 +++-
arch/riscv/kernel/process.c | 4 +
arch/riscv/kernel/ptrace.c | 110 +++++++++++++++++++++++++++
5 files changed, 140 insertions(+), 1 deletion(-)
diff --git a/arch/riscv/include/asm/processor.h b/arch/riscv/include/asm/processor.h
index 5f56eb9d114a..488d956a951f 100644
--- a/arch/riscv/include/asm/processor.h
+++ b/arch/riscv/include/asm/processor.h
@@ -12,6 +12,7 @@
#include <vdso/processor.h>
+#include <asm/hw_breakpoint.h>
#include <asm/ptrace.h>
#define arch_get_mmap_end(addr, len, flags) \
@@ -108,6 +109,9 @@ struct thread_struct {
struct __riscv_v_ext_state vstate;
unsigned long align_ctl;
struct __riscv_v_ext_state kernel_vstate;
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+ struct perf_event *ptrace_bps[RV_MAX_TRIGGERS];
+#endif
#ifdef CONFIG_SMP
/* Flush the icache on migration */
bool force_icache_flush;
diff --git a/arch/riscv/include/uapi/asm/ptrace.h b/arch/riscv/include/uapi/asm/ptrace.h
index a38268b19c3d..20d1aa595cbd 100644
--- a/arch/riscv/include/uapi/asm/ptrace.h
+++ b/arch/riscv/include/uapi/asm/ptrace.h
@@ -14,6 +14,8 @@
#define PTRACE_GETFDPIC_EXEC 0
#define PTRACE_GETFDPIC_INTERP 1
+#define PTRACE_GETHBPREGS 2
+#define PTRACE_SETHBPREGS 3
/*
* User-mode register state for core dumps, ptrace, sigcontext
@@ -120,6 +122,13 @@ struct __riscv_v_regset_state {
char vreg[];
};
+struct __riscv_hwdebug_state {
+ unsigned long addr;
+ unsigned long type;
+ unsigned long len;
+ unsigned long ctrl;
+} __packed;
+
/*
* According to spec: The number of bits in a single vector register,
* VLEN >= ELEN, which must be a power of 2, and must be no greater than
diff --git a/arch/riscv/kernel/hw_breakpoint.c b/arch/riscv/kernel/hw_breakpoint.c
index 1e70ef9e6867..b1c9c40f5fde 100644
--- a/arch/riscv/kernel/hw_breakpoint.c
+++ b/arch/riscv/kernel/hw_breakpoint.c
@@ -721,7 +721,19 @@ void arch_uninstall_hw_breakpoint(struct perf_event *event)
pr_warn("%s: Failed to uninstall trigger %d. error: %ld\n", __func__, i, ret.error);
}
-void flush_ptrace_hw_breakpoint(struct task_struct *tsk) { }
+/*
+ * Release the user breakpoints used by ptrace
+ */
+void flush_ptrace_hw_breakpoint(struct task_struct *tsk)
+{
+ int i;
+ struct thread_struct *t = &tsk->thread;
+
+ for (i = 0; i < dbtr_total_num; i++) {
+ unregister_hw_breakpoint(t->ptrace_bps[i]);
+ t->ptrace_bps[i] = NULL;
+ }
+}
void hw_breakpoint_pmu_read(struct perf_event *bp) { }
diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c
index 15d8f75902f8..9cf07ecfb523 100644
--- a/arch/riscv/kernel/process.c
+++ b/arch/riscv/kernel/process.c
@@ -9,6 +9,7 @@
#include <linux/bitfield.h>
#include <linux/cpu.h>
+#include <linux/hw_breakpoint.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/sched/debug.h>
@@ -164,6 +165,7 @@ void start_thread(struct pt_regs *regs, unsigned long pc,
void flush_thread(void)
{
+ flush_ptrace_hw_breakpoint(current);
#ifdef CONFIG_FPU
/*
* Reset FPU state and context
@@ -218,6 +220,8 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
set_bit(MM_CONTEXT_LOCK_PMLEN, &p->mm->context.flags);
memset(&p->thread.s, 0, sizeof(p->thread.s));
+ if (IS_ENABLED(CONFIG_HAVE_HW_BREAKPOINT))
+ memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps));
/* p->thread holds context to be restored by __switch_to() */
if (unlikely(args->fn)) {
diff --git a/arch/riscv/kernel/ptrace.c b/arch/riscv/kernel/ptrace.c
index ea67e9fb7a58..e097e6a61910 100644
--- a/arch/riscv/kernel/ptrace.c
+++ b/arch/riscv/kernel/ptrace.c
@@ -9,11 +9,13 @@
#include <asm/vector.h>
#include <asm/ptrace.h>
+#include <asm/hw_breakpoint.h>
#include <asm/syscall.h>
#include <asm/thread_info.h>
#include <asm/switch_to.h>
#include <linux/audit.h>
#include <linux/compat.h>
+#include <linux/hw_breakpoint.h>
#include <linux/ptrace.h>
#include <linux/elf.h>
#include <linux/regset.h>
@@ -184,6 +186,104 @@ static int tagged_addr_ctrl_set(struct task_struct *target,
}
#endif
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+static void ptrace_hbptriggered(struct perf_event *bp,
+ struct perf_sample_data *data,
+ struct pt_regs *regs)
+{
+ struct arch_hw_breakpoint *bkpt = counter_arch_bp(bp);
+ int num = 0;
+
+ force_sig_ptrace_errno_trap(num, (void __user *)bkpt->address);
+}
+
+static int ptrace_hbp_get(struct task_struct *child, unsigned long idx,
+ struct __riscv_hwdebug_state *state)
+{
+ struct perf_event *bp;
+
+ if (idx >= RV_MAX_TRIGGERS)
+ return -EINVAL;
+
+ bp = child->thread.ptrace_bps[idx];
+
+ if (!bp)
+ return -ENOENT;
+
+ state->addr = bp->attr.bp_addr;
+ state->len = bp->attr.bp_len;
+ state->type = bp->attr.bp_type;
+ state->ctrl = bp->attr.disabled == 1;
+
+ return 0;
+}
+
+static int ptrace_hbp_set(struct task_struct *child, unsigned long idx,
+ struct __riscv_hwdebug_state *state)
+{
+ struct perf_event *bp;
+ struct perf_event_attr attr;
+
+ if (idx >= RV_MAX_TRIGGERS)
+ return -EINVAL;
+
+ bp = child->thread.ptrace_bps[idx];
+ if (bp)
+ attr = bp->attr;
+ else
+ ptrace_breakpoint_init(&attr);
+
+ attr.bp_addr = state->addr;
+ attr.bp_len = state->len;
+ attr.bp_type = state->type;
+ attr.disabled = state->ctrl == 1;
+
+ if (!bp) {
+ bp = register_user_hw_breakpoint(&attr, ptrace_hbptriggered, NULL,
+ child);
+ if (IS_ERR(bp))
+ return PTR_ERR(bp);
+
+ child->thread.ptrace_bps[idx] = bp;
+ return 0;
+ }
+
+ return modify_user_hw_breakpoint(bp, &attr);
+}
+
+/*
+ * idx selects the breakpoint index.
+ * Both PTRACE_GETHBPREGS and PTRACE_SETHBPREGS transfer __riscv_hwdebug_state
+ */
+
+static long ptrace_gethbpregs(struct task_struct *child, unsigned long idx,
+ unsigned long __user *datap)
+{
+ struct __riscv_hwdebug_state state;
+ long ret;
+
+ ret = ptrace_hbp_get(child, idx, &state);
+ if (ret)
+ return ret;
+ if (copy_to_user(datap, &state, sizeof(state)))
+ return -EFAULT;
+
+ return 0;
+}
+
+static long ptrace_sethbpregs(struct task_struct *child, unsigned long idx,
+ unsigned long __user *datap)
+{
+ struct __riscv_hwdebug_state state;
+
+ if (copy_from_user(&state, datap, sizeof(state)))
+ return -EFAULT;
+
+ return ptrace_hbp_set(child, idx, &state);
+
+}
+#endif
+
static const struct user_regset riscv_user_regset[] = {
[REGSET_X] = {
.core_note_type = NT_PRSTATUS,
@@ -340,8 +440,18 @@ long arch_ptrace(struct task_struct *child, long request,
unsigned long addr, unsigned long data)
{
long ret = -EIO;
+ unsigned long __user *datap = (unsigned long __user *) data;
switch (request) {
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+ case PTRACE_GETHBPREGS:
+ ret = ptrace_gethbpregs(child, addr, datap);
+ break;
+
+ case PTRACE_SETHBPREGS:
+ ret = ptrace_sethbpregs(child, addr, datap);
+ break;
+#endif
default:
ret = ptrace_request(child, request, addr, data);
break;
--
2.43.0
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
next prev parent reply other threads:[~2025-08-05 19:40 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-08-05 19:39 [PATCH 0/8] riscv: add initial support for hardware breakpoints Jesse Taube
2025-08-05 19:39 ` Jesse Taube
2025-08-05 19:39 ` [PATCH 1/8] riscv: Add insn.c, consolidate instruction decoding Jesse Taube
2025-08-05 19:39 ` Jesse Taube
2025-08-05 19:39 ` [PATCH 2/8] riscv: Add SBI debug trigger extension and function ids Jesse Taube
2025-08-05 19:39 ` Jesse Taube
2025-08-05 19:39 ` [PATCH 3/8] riscv: insn: Add get_insn_nofault Jesse Taube
2025-08-05 19:39 ` Jesse Taube
2025-08-05 19:39 ` [PATCH 4/8] riscv: Introduce support for hardware break/watchpoints Jesse Taube
2025-08-05 19:39 ` Jesse Taube
2025-08-05 19:39 ` [PATCH 5/8] riscv: hw_breakpoint: Use icount for single stepping Jesse Taube
2025-08-05 19:39 ` Jesse Taube
2025-08-11 9:41 ` Anup Patel
2025-08-11 9:41 ` Anup Patel
2025-08-05 19:39 ` Jesse Taube [this message]
2025-08-05 19:39 ` [PATCH 6/8] riscv: ptrace: Add hw breakpoint support Jesse Taube
2025-08-05 19:39 ` [PATCH 7/8] riscv: ptrace: Add hw breakpoint regset Jesse Taube
2025-08-05 19:39 ` Jesse Taube
2025-08-05 19:39 ` [PATCH 8/8] selftests: riscv: Add test for hardware breakpoints Jesse Taube
2025-08-05 19:39 ` Jesse Taube
2025-08-15 5:42 ` Joel Stanley
2025-08-15 5:42 ` Joel Stanley
2025-08-22 17:58 ` Jesse Taube
2025-08-22 17:58 ` Jesse Taube
-- strict thread matches above, loose matches on Subject: below --
2025-08-22 17:47 [PATCH 0/8] riscv: add initial support " Jesse Taube
2025-08-22 17:47 ` [PATCH 6/8] riscv: ptrace: Add hw breakpoint support Jesse Taube
2025-08-22 17:47 ` Jesse Taube
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250805193955.798277-7-jesse@rivosinc.com \
--to=jesse@rivosinc.com \
--cc=acme@kernel.org \
--cc=adrian.hunter@intel.com \
--cc=ajones@ventanamicro.com \
--cc=akihiko.odaki@daynix.com \
--cc=akpm@linux-foundation.org \
--cc=alex@ghiti.fr \
--cc=alexander.shishkin@linux.intel.com \
--cc=aou@eecs.berkeley.edu \
--cc=apatel@ventanamicro.com \
--cc=arnd@arndb.de \
--cc=atishp@rivosinc.com \
--cc=bigeasy@linutronix.de \
--cc=charlie@rivosinc.com \
--cc=chenhuacai@kernel.org \
--cc=cleger@rivosinc.com \
--cc=coelacanthushex@gmail.com \
--cc=conor.dooley@microchip.com \
--cc=cuiyunhui@bytedance.com \
--cc=debug@rivosinc.com \
--cc=evan@rivosinc.com \
--cc=hchauhan@ventanamicro.com \
--cc=irogers@google.com \
--cc=joel.granados@kernel.org \
--cc=joey.gouly@arm.com \
--cc=jolsa@kernel.org \
--cc=kan.liang@linux.intel.com \
--cc=kees@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=mark.rutland@arm.com \
--cc=mcgrof@kernel.org \
--cc=mchitale@ventanamicro.com \
--cc=mingo@redhat.com \
--cc=namcao@linutronix.de \
--cc=namhyung@kernel.org \
--cc=nylon.chen@sifive.com \
--cc=oleg@redhat.com \
--cc=palmer@dabbelt.com \
--cc=paul.walmsley@sifive.com \
--cc=peterz@infradead.org \
--cc=ravi.bangoria@amd.com \
--cc=rppt@kernel.org \
--cc=samuel.holland@sifive.com \
--cc=shuah@kernel.org \
--cc=tglx@linutronix.de \
--cc=thomas.weissschuh@linutronix.de \
--cc=vincenzo.frascino@arm.com \
--cc=wangyuli@uniontech.com \
--cc=zhangchunyan@iscas.ac.cn \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.