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 8/8] selftests: riscv: Add test for hardware breakpoints
Date: Tue, 5 Aug 2025 12:39:55 -0700 [thread overview]
Message-ID: <20250805193955.798277-9-jesse@rivosinc.com> (raw)
In-Reply-To: <20250805193955.798277-1-jesse@rivosinc.com>
Add riscv specific selftest for hardhardware breakpoints.
These tests are based on:
tools/testing/selftests/breakpoints/breakpoint_test_arm64.c
Signed-off-by: Jesse Taube <jesse@rivosinc.com>
---
The selftest fails as register_user_hw_breakpoint seemingly does not
call arch_install_hw_breakpoint. The test also seems to fail on arm64
in the same way when I tested it.
RFC -> V1:
- New commit
---
tools/perf/tests/tests.h | 3 +-
tools/testing/selftests/riscv/Makefile | 2 +-
.../selftests/riscv/breakpoints/.gitignore | 1 +
.../selftests/riscv/breakpoints/Makefile | 12 +
.../riscv/breakpoints/breakpoint_test.c | 246 ++++++++++++++++++
5 files changed, 262 insertions(+), 2 deletions(-)
create mode 100644 tools/testing/selftests/riscv/breakpoints/.gitignore
create mode 100644 tools/testing/selftests/riscv/breakpoints/Makefile
create mode 100644 tools/testing/selftests/riscv/breakpoints/breakpoint_test.c
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index 8aea344536b8..5ff35304c11a 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -183,7 +183,8 @@ DECLARE_SUITE(util);
* Just disable the test for these architectures until these issues are
* resolved.
*/
-#if defined(__powerpc__) || defined(__s390x__) || defined(__arm__) || defined(__aarch64__)
+#if defined(__powerpc__) || defined(__s390x__) || defined(__arm__) || defined(__aarch64__) || \
+ defined(__riscv)
#define BP_SIGNAL_IS_SUPPORTED 0
#else
#define BP_SIGNAL_IS_SUPPORTED 1
diff --git a/tools/testing/selftests/riscv/Makefile b/tools/testing/selftests/riscv/Makefile
index 099b8c1f46f8..96aba246cb3e 100644
--- a/tools/testing/selftests/riscv/Makefile
+++ b/tools/testing/selftests/riscv/Makefile
@@ -5,7 +5,7 @@
ARCH ?= $(shell uname -m 2>/dev/null || echo not)
ifneq (,$(filter $(ARCH),riscv))
-RISCV_SUBTARGETS ?= abi hwprobe mm sigreturn vector
+RISCV_SUBTARGETS ?= abi hwprobe mm sigreturn vector breakpoints
else
RISCV_SUBTARGETS :=
endif
diff --git a/tools/testing/selftests/riscv/breakpoints/.gitignore b/tools/testing/selftests/riscv/breakpoints/.gitignore
new file mode 100644
index 000000000000..9b3193d06608
--- /dev/null
+++ b/tools/testing/selftests/riscv/breakpoints/.gitignore
@@ -0,0 +1 @@
+breakpoint_test
diff --git a/tools/testing/selftests/riscv/breakpoints/Makefile b/tools/testing/selftests/riscv/breakpoints/Makefile
new file mode 100644
index 000000000000..91e1c02c0073
--- /dev/null
+++ b/tools/testing/selftests/riscv/breakpoints/Makefile
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (C) 2021 ARM Limited
+# Originally tools/testing/arm64/abi/Makefile
+
+CFLAGS += -I$(top_srcdir)/tools/include
+
+TEST_GEN_PROGS := breakpoint_test
+
+include ../../lib.mk
+
+$(OUTPUT)/breakpoint_test: breakpoint_test.c
+ $(CC) -static -o$@ $(CFLAGS) $(LDFLAGS) $^
diff --git a/tools/testing/selftests/riscv/breakpoints/breakpoint_test.c b/tools/testing/selftests/riscv/breakpoints/breakpoint_test.c
new file mode 100644
index 000000000000..faeecc72da12
--- /dev/null
+++ b/tools/testing/selftests/riscv/breakpoints/breakpoint_test.c
@@ -0,0 +1,246 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2016 Google, Inc.
+ *
+ * Original Code by Pavel Labath <labath@google.com>
+ *
+ * Code modified by Pratyush Anand <panand@redhat.com>
+ * for testing different byte select for each access size.
+ * Originally tools/testing/selftests/breakpoints/breakpoint_test_arm64.c
+ */
+
+#define _GNU_SOURCE
+
+#include <asm/ptrace.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/ptrace.h>
+#include <sys/param.h>
+#include <sys/uio.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <elf.h>
+#include <errno.h>
+#include <signal.h>
+
+#include "../../kselftest.h"
+
+#define MAX_BP_SIZE 8
+
+static volatile uint8_t var[3*MAX_BP_SIZE] __attribute__((__aligned__(MAX_BP_SIZE)));
+
+static void child(int size, int wr)
+{
+ volatile uint8_t *addr = &var[MAX_BP_SIZE + wr];
+
+ if (ptrace(PTRACE_TRACEME, 0, NULL, NULL) != 0) {
+ ksft_print_msg(
+ "ptrace(PTRACE_TRACEME) failed: %s\n",
+ strerror(errno));
+ _exit(1);
+ }
+
+ if (raise(SIGSTOP) != 0) {
+ ksft_print_msg(
+ "raise(SIGSTOP) failed: %s\n", strerror(errno));
+ _exit(1);
+ }
+
+ if ((uintptr_t) addr % size) {
+ ksft_print_msg(
+ "Wrong address write for the given size: %s\n",
+ strerror(errno));
+ _exit(1);
+ }
+
+ switch (size) {
+ case 1:
+ *addr = 47;
+ break;
+ case 2:
+ *(uint16_t *)addr = 47;
+ break;
+ case 4:
+ *(uint32_t *)addr = 47;
+ break;
+ case 8:
+ *(uint64_t *)addr = 47;
+ break;
+ }
+
+ _exit(0);
+}
+
+static bool set_watchpoint(pid_t pid, int size, int wp)
+{
+ const volatile uint8_t *addr = &var[MAX_BP_SIZE + wp];
+ const int offset = (uintptr_t)addr % 8;
+ const unsigned int type = 2; /* Write */
+ const unsigned int enable = 1;
+ struct __riscv_hwdebug_state debug_state;
+ struct iovec iov;
+
+ memset(&debug_state, 0, sizeof(debug_state));
+ debug_state.addr = (uintptr_t)(addr - offset);
+ debug_state.len = size;
+ debug_state.ctrl = enable;
+ debug_state.type = type;
+ iov.iov_base = &debug_state;
+ iov.iov_len = sizeof(debug_state);
+ if (ptrace(PTRACE_SETREGSET, pid, NT_RISCV_HW_BREAK, &iov) == 0)
+ return true;
+
+ if (errno == EIO)
+ ksft_print_msg(
+ "ptrace(PTRACE_SETREGSET, NT_RISCV_HW_BREAK) not supported on this hardware: %s\n",
+ strerror(errno));
+
+ ksft_print_msg(
+ "ptrace(PTRACE_SETREGSET, NT_RISCV_HW_BREAK) failed: %s\n",
+ strerror(errno));
+ return false;
+}
+
+static bool run_test(int wr_size, int wp_size, int wr, int wp)
+{
+ int status;
+ siginfo_t siginfo;
+ pid_t pid = fork();
+ pid_t wpid;
+
+ if (pid < 0) {
+ ksft_test_result_fail(
+ "fork() failed: %s\n", strerror(errno));
+ return false;
+ }
+ if (pid == 0)
+ child(wr_size, wr);
+
+ wpid = waitpid(pid, &status, __WALL);
+ if (wpid != pid) {
+ ksft_print_msg(
+ "waitpid() failed: %s\n", strerror(errno));
+ return false;
+ }
+ if (!WIFSTOPPED(status)) {
+ ksft_print_msg(
+ "child did not stop: %s\n", strerror(errno));
+ return false;
+ }
+ if (WSTOPSIG(status) != SIGSTOP) {
+ ksft_print_msg("child did not stop with SIGSTOP\n");
+ return false;
+ }
+
+ if (!set_watchpoint(pid, wp_size, wp))
+ return false;
+
+ if (ptrace(PTRACE_CONT, pid, NULL, NULL) < 0) {
+ ksft_print_msg(
+ "ptrace(PTRACE_CONT) failed: %s\n",
+ strerror(errno));
+ return false;
+ }
+
+ alarm(3);
+ wpid = waitpid(pid, &status, __WALL);
+ if (wpid != pid) {
+ ksft_print_msg(
+ "waitpid() failed: %s\n", strerror(errno));
+ return false;
+ }
+ alarm(0);
+ if (WIFEXITED(status)) {
+ ksft_print_msg("child exited prematurely\n");
+ return false;
+ }
+ if (!WIFSTOPPED(status)) {
+ ksft_print_msg("child did not stop\n");
+ return false;
+ }
+ if (WSTOPSIG(status) != SIGTRAP) {
+ ksft_print_msg("child did not stop with SIGTRAP\n");
+ return false;
+ }
+ if (ptrace(PTRACE_GETSIGINFO, pid, NULL, &siginfo) != 0) {
+ ksft_print_msg(
+ "ptrace(PTRACE_GETSIGINFO): %s\n",
+ strerror(errno));
+ return false;
+ }
+ if (siginfo.si_code != TRAP_HWBKPT) {
+ ksft_print_msg(
+ "Unexpected si_code %d\n", siginfo.si_code);
+ return false;
+ }
+
+ kill(pid, SIGKILL);
+ wpid = waitpid(pid, &status, 0);
+ if (wpid != pid) {
+ ksft_print_msg(
+ "waitpid() failed: %s\n", strerror(errno));
+ return false;
+ }
+ return true;
+}
+
+static void sigalrm(int sig)
+{
+}
+
+int main(int argc, char **argv)
+{
+ int opt;
+ bool succeeded = true;
+ struct sigaction act;
+ int wr, wp, size;
+ bool result;
+
+ ksft_print_header();
+ ksft_set_plan(213);
+
+ act.sa_handler = sigalrm;
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = 0;
+ sigaction(SIGALRM, &act, NULL);
+ for (size = 1; size <= MAX_BP_SIZE; size = size*2) {
+ for (wr = 0; wr <= MAX_BP_SIZE; wr = wr + size) {
+ for (wp = wr - size; wp <= wr + size; wp = wp + size) {
+ result = run_test(size, MIN(size, 8), wr, wp);
+ if ((result && wr == wp) ||
+ (!result && wr != wp))
+ ksft_test_result_pass(
+ "Test size = %d write offset = %d watchpoint offset = %d\n",
+ size, wr, wp);
+ else {
+ ksft_test_result_fail(
+ "Test size = %d write offset = %d watchpoint offset = %d\n",
+ size, wr, wp);
+ succeeded = false;
+ }
+ }
+ }
+ }
+
+ for (size = 1; size <= MAX_BP_SIZE; size = size*2) {
+ if (run_test(size, 8, -size, -8))
+ ksft_test_result_pass(
+ "Test size = %d write offset = %d watchpoint offset = -8\n",
+ size, -size);
+ else {
+ ksft_test_result_fail(
+ "Test size = %d write offset = %d watchpoint offset = -8\n",
+ size, -size);
+ succeeded = false;
+ }
+ }
+
+ if (succeeded)
+ ksft_exit_pass();
+ else
+ ksft_exit_fail();
+}
--
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 8/8] selftests: riscv: Add test for hardware breakpoints
Date: Tue, 5 Aug 2025 12:39:55 -0700 [thread overview]
Message-ID: <20250805193955.798277-9-jesse@rivosinc.com> (raw)
In-Reply-To: <20250805193955.798277-1-jesse@rivosinc.com>
Add riscv specific selftest for hardhardware breakpoints.
These tests are based on:
tools/testing/selftests/breakpoints/breakpoint_test_arm64.c
Signed-off-by: Jesse Taube <jesse@rivosinc.com>
---
The selftest fails as register_user_hw_breakpoint seemingly does not
call arch_install_hw_breakpoint. The test also seems to fail on arm64
in the same way when I tested it.
RFC -> V1:
- New commit
---
tools/perf/tests/tests.h | 3 +-
tools/testing/selftests/riscv/Makefile | 2 +-
.../selftests/riscv/breakpoints/.gitignore | 1 +
.../selftests/riscv/breakpoints/Makefile | 12 +
.../riscv/breakpoints/breakpoint_test.c | 246 ++++++++++++++++++
5 files changed, 262 insertions(+), 2 deletions(-)
create mode 100644 tools/testing/selftests/riscv/breakpoints/.gitignore
create mode 100644 tools/testing/selftests/riscv/breakpoints/Makefile
create mode 100644 tools/testing/selftests/riscv/breakpoints/breakpoint_test.c
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index 8aea344536b8..5ff35304c11a 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -183,7 +183,8 @@ DECLARE_SUITE(util);
* Just disable the test for these architectures until these issues are
* resolved.
*/
-#if defined(__powerpc__) || defined(__s390x__) || defined(__arm__) || defined(__aarch64__)
+#if defined(__powerpc__) || defined(__s390x__) || defined(__arm__) || defined(__aarch64__) || \
+ defined(__riscv)
#define BP_SIGNAL_IS_SUPPORTED 0
#else
#define BP_SIGNAL_IS_SUPPORTED 1
diff --git a/tools/testing/selftests/riscv/Makefile b/tools/testing/selftests/riscv/Makefile
index 099b8c1f46f8..96aba246cb3e 100644
--- a/tools/testing/selftests/riscv/Makefile
+++ b/tools/testing/selftests/riscv/Makefile
@@ -5,7 +5,7 @@
ARCH ?= $(shell uname -m 2>/dev/null || echo not)
ifneq (,$(filter $(ARCH),riscv))
-RISCV_SUBTARGETS ?= abi hwprobe mm sigreturn vector
+RISCV_SUBTARGETS ?= abi hwprobe mm sigreturn vector breakpoints
else
RISCV_SUBTARGETS :=
endif
diff --git a/tools/testing/selftests/riscv/breakpoints/.gitignore b/tools/testing/selftests/riscv/breakpoints/.gitignore
new file mode 100644
index 000000000000..9b3193d06608
--- /dev/null
+++ b/tools/testing/selftests/riscv/breakpoints/.gitignore
@@ -0,0 +1 @@
+breakpoint_test
diff --git a/tools/testing/selftests/riscv/breakpoints/Makefile b/tools/testing/selftests/riscv/breakpoints/Makefile
new file mode 100644
index 000000000000..91e1c02c0073
--- /dev/null
+++ b/tools/testing/selftests/riscv/breakpoints/Makefile
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (C) 2021 ARM Limited
+# Originally tools/testing/arm64/abi/Makefile
+
+CFLAGS += -I$(top_srcdir)/tools/include
+
+TEST_GEN_PROGS := breakpoint_test
+
+include ../../lib.mk
+
+$(OUTPUT)/breakpoint_test: breakpoint_test.c
+ $(CC) -static -o$@ $(CFLAGS) $(LDFLAGS) $^
diff --git a/tools/testing/selftests/riscv/breakpoints/breakpoint_test.c b/tools/testing/selftests/riscv/breakpoints/breakpoint_test.c
new file mode 100644
index 000000000000..faeecc72da12
--- /dev/null
+++ b/tools/testing/selftests/riscv/breakpoints/breakpoint_test.c
@@ -0,0 +1,246 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2016 Google, Inc.
+ *
+ * Original Code by Pavel Labath <labath@google.com>
+ *
+ * Code modified by Pratyush Anand <panand@redhat.com>
+ * for testing different byte select for each access size.
+ * Originally tools/testing/selftests/breakpoints/breakpoint_test_arm64.c
+ */
+
+#define _GNU_SOURCE
+
+#include <asm/ptrace.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/ptrace.h>
+#include <sys/param.h>
+#include <sys/uio.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <elf.h>
+#include <errno.h>
+#include <signal.h>
+
+#include "../../kselftest.h"
+
+#define MAX_BP_SIZE 8
+
+static volatile uint8_t var[3*MAX_BP_SIZE] __attribute__((__aligned__(MAX_BP_SIZE)));
+
+static void child(int size, int wr)
+{
+ volatile uint8_t *addr = &var[MAX_BP_SIZE + wr];
+
+ if (ptrace(PTRACE_TRACEME, 0, NULL, NULL) != 0) {
+ ksft_print_msg(
+ "ptrace(PTRACE_TRACEME) failed: %s\n",
+ strerror(errno));
+ _exit(1);
+ }
+
+ if (raise(SIGSTOP) != 0) {
+ ksft_print_msg(
+ "raise(SIGSTOP) failed: %s\n", strerror(errno));
+ _exit(1);
+ }
+
+ if ((uintptr_t) addr % size) {
+ ksft_print_msg(
+ "Wrong address write for the given size: %s\n",
+ strerror(errno));
+ _exit(1);
+ }
+
+ switch (size) {
+ case 1:
+ *addr = 47;
+ break;
+ case 2:
+ *(uint16_t *)addr = 47;
+ break;
+ case 4:
+ *(uint32_t *)addr = 47;
+ break;
+ case 8:
+ *(uint64_t *)addr = 47;
+ break;
+ }
+
+ _exit(0);
+}
+
+static bool set_watchpoint(pid_t pid, int size, int wp)
+{
+ const volatile uint8_t *addr = &var[MAX_BP_SIZE + wp];
+ const int offset = (uintptr_t)addr % 8;
+ const unsigned int type = 2; /* Write */
+ const unsigned int enable = 1;
+ struct __riscv_hwdebug_state debug_state;
+ struct iovec iov;
+
+ memset(&debug_state, 0, sizeof(debug_state));
+ debug_state.addr = (uintptr_t)(addr - offset);
+ debug_state.len = size;
+ debug_state.ctrl = enable;
+ debug_state.type = type;
+ iov.iov_base = &debug_state;
+ iov.iov_len = sizeof(debug_state);
+ if (ptrace(PTRACE_SETREGSET, pid, NT_RISCV_HW_BREAK, &iov) == 0)
+ return true;
+
+ if (errno == EIO)
+ ksft_print_msg(
+ "ptrace(PTRACE_SETREGSET, NT_RISCV_HW_BREAK) not supported on this hardware: %s\n",
+ strerror(errno));
+
+ ksft_print_msg(
+ "ptrace(PTRACE_SETREGSET, NT_RISCV_HW_BREAK) failed: %s\n",
+ strerror(errno));
+ return false;
+}
+
+static bool run_test(int wr_size, int wp_size, int wr, int wp)
+{
+ int status;
+ siginfo_t siginfo;
+ pid_t pid = fork();
+ pid_t wpid;
+
+ if (pid < 0) {
+ ksft_test_result_fail(
+ "fork() failed: %s\n", strerror(errno));
+ return false;
+ }
+ if (pid == 0)
+ child(wr_size, wr);
+
+ wpid = waitpid(pid, &status, __WALL);
+ if (wpid != pid) {
+ ksft_print_msg(
+ "waitpid() failed: %s\n", strerror(errno));
+ return false;
+ }
+ if (!WIFSTOPPED(status)) {
+ ksft_print_msg(
+ "child did not stop: %s\n", strerror(errno));
+ return false;
+ }
+ if (WSTOPSIG(status) != SIGSTOP) {
+ ksft_print_msg("child did not stop with SIGSTOP\n");
+ return false;
+ }
+
+ if (!set_watchpoint(pid, wp_size, wp))
+ return false;
+
+ if (ptrace(PTRACE_CONT, pid, NULL, NULL) < 0) {
+ ksft_print_msg(
+ "ptrace(PTRACE_CONT) failed: %s\n",
+ strerror(errno));
+ return false;
+ }
+
+ alarm(3);
+ wpid = waitpid(pid, &status, __WALL);
+ if (wpid != pid) {
+ ksft_print_msg(
+ "waitpid() failed: %s\n", strerror(errno));
+ return false;
+ }
+ alarm(0);
+ if (WIFEXITED(status)) {
+ ksft_print_msg("child exited prematurely\n");
+ return false;
+ }
+ if (!WIFSTOPPED(status)) {
+ ksft_print_msg("child did not stop\n");
+ return false;
+ }
+ if (WSTOPSIG(status) != SIGTRAP) {
+ ksft_print_msg("child did not stop with SIGTRAP\n");
+ return false;
+ }
+ if (ptrace(PTRACE_GETSIGINFO, pid, NULL, &siginfo) != 0) {
+ ksft_print_msg(
+ "ptrace(PTRACE_GETSIGINFO): %s\n",
+ strerror(errno));
+ return false;
+ }
+ if (siginfo.si_code != TRAP_HWBKPT) {
+ ksft_print_msg(
+ "Unexpected si_code %d\n", siginfo.si_code);
+ return false;
+ }
+
+ kill(pid, SIGKILL);
+ wpid = waitpid(pid, &status, 0);
+ if (wpid != pid) {
+ ksft_print_msg(
+ "waitpid() failed: %s\n", strerror(errno));
+ return false;
+ }
+ return true;
+}
+
+static void sigalrm(int sig)
+{
+}
+
+int main(int argc, char **argv)
+{
+ int opt;
+ bool succeeded = true;
+ struct sigaction act;
+ int wr, wp, size;
+ bool result;
+
+ ksft_print_header();
+ ksft_set_plan(213);
+
+ act.sa_handler = sigalrm;
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = 0;
+ sigaction(SIGALRM, &act, NULL);
+ for (size = 1; size <= MAX_BP_SIZE; size = size*2) {
+ for (wr = 0; wr <= MAX_BP_SIZE; wr = wr + size) {
+ for (wp = wr - size; wp <= wr + size; wp = wp + size) {
+ result = run_test(size, MIN(size, 8), wr, wp);
+ if ((result && wr == wp) ||
+ (!result && wr != wp))
+ ksft_test_result_pass(
+ "Test size = %d write offset = %d watchpoint offset = %d\n",
+ size, wr, wp);
+ else {
+ ksft_test_result_fail(
+ "Test size = %d write offset = %d watchpoint offset = %d\n",
+ size, wr, wp);
+ succeeded = false;
+ }
+ }
+ }
+ }
+
+ for (size = 1; size <= MAX_BP_SIZE; size = size*2) {
+ if (run_test(size, 8, -size, -8))
+ ksft_test_result_pass(
+ "Test size = %d write offset = %d watchpoint offset = -8\n",
+ size, -size);
+ else {
+ ksft_test_result_fail(
+ "Test size = %d write offset = %d watchpoint offset = -8\n",
+ size, -size);
+ succeeded = false;
+ }
+ }
+
+ if (succeeded)
+ ksft_exit_pass();
+ else
+ ksft_exit_fail();
+}
--
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 ` [PATCH 6/8] riscv: ptrace: Add hw breakpoint support Jesse Taube
2025-08-05 19:39 ` 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 ` Jesse Taube [this message]
2025-08-05 19:39 ` [PATCH 8/8] selftests: riscv: Add test for hardware breakpoints 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 8/8] selftests: riscv: Add test " 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-9-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.