From: Xiaofeng Yuan <yuanxiaofeng@eswincomputing.com>
To: Paul Walmsley <pjw@kernel.org>,
Palmer Dabbelt <palmer@dabbelt.com>,
Albert Ou <aou@eecs.berkeley.edu>
Cc: Alexandre Ghiti <alex@ghiti.fr>, Nam Cao <namcao@linutronix.de>,
Naveen N Rao <naveen@kernel.org>,
"David S . Miller" <davem@davemloft.net>,
Masami Hiramatsu <mhiramat@kernel.org>,
linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org,
linux-trace-kernel@vger.kernel.org,
Xiaofeng Yuan <yuanxiaofeng@eswincomputing.com>
Subject: [PATCH v7 2/2] riscv: kprobes: add KUnit test for LR/SC sequence rejection
Date: Mon, 19 Oct 2026 21:41:21 +0800 [thread overview]
Message-ID: <20261019134121.1763-3-yuanxiaofeng@eswincomputing.com> (raw)
In-Reply-To: <20261019134121.1763-1-yuanxiaofeng@eswincomputing.com>
Extend the kprobes KUnit test with a function containing an LR/SC
sequence and assert that register_kprobe() accepts a probe placed right
before or right after the sequence, and rejects a probe placed on the
LR, on an instruction inside the sequence, or on the SC.
Add a second, never-executed function that pins the 16-instruction
tracking window: the 15th instruction after the LR (the last that can
still be inside the loop) must be rejected, and the 16th must be
accepted because it is either the SC (rejected during decoding) or a
plain instruction outside the loop.
Signed-off-by: Xiaofeng Yuan <yuanxiaofeng@eswincomputing.com>
---
.../kernel/tests/kprobes/test-kprobes-asm.S | 60 +++++++++++++++++++
.../riscv/kernel/tests/kprobes/test-kprobes.c | 34 +++++++++++
.../riscv/kernel/tests/kprobes/test-kprobes.h | 6 ++
3 files changed, 100 insertions(+)
diff --git a/arch/riscv/kernel/tests/kprobes/test-kprobes-asm.S b/arch/riscv/kernel/tests/kprobes/test-kprobes-asm.S
index 15e50934b..7924dd55a 100644
--- a/arch/riscv/kernel/tests/kprobes/test-kprobes-asm.S
+++ b/arch/riscv/kernel/tests/kprobes/test-kprobes-asm.S
@@ -100,6 +100,49 @@ test_kprobes_branch_addr8:
.option pop
SYM_FUNC_END(test_kprobes_branch)
+/*
+ * This function is never executed; it only provides the probe addresses
+ * in test_kprobes_lrsc_allowed_addresses[] and
+ * test_kprobes_lrsc_rejected_addresses[] for test_kprobe_lrsc(). The
+ * lr.w/sc.w use the invalid address 0(x0) and would fault if executed,
+ * so do not add this function to test_kprobes_functions[].
+ */
+SYM_FUNC_START(test_kprobes_lrsc)
+.Llrsc_before:
+ nop
+1:
+.Llrsc_lr:
+ lr.w t0, 0(x0)
+.Llrsc_inside:
+ addi t0, t0, 1
+.Llrsc_sc:
+ sc.w t0, t0, 0(x0)
+ bnez t0, 1b
+.Llrsc_after:
+ ret
+SYM_FUNC_END(test_kprobes_lrsc)
+
+/*
+ * Also never executed; it pins the 16-instruction LR/SC tracking window.
+ * The LR is followed by 13 nops. The 15th instruction (counting the LR
+ * as the 1st) is the last one that can still be inside the loop and must
+ * be rejected. The 16th is accepted: it is either the SC, rejected later
+ * during decoding, or a plain instruction, which cannot lie inside a
+ * 16-instruction loop because that loop's 16th instruction must be the SC.
+ */
+SYM_FUNC_START(test_kprobes_lrsc_gap)
+.Llrsc_gap_lr:
+ lr.w t0, 0(x0)
+ .rept 13
+ nop
+ .endr
+.Llrsc_gap_pos15:
+ nop
+.Llrsc_gap_pos16:
+ nop
+ ret
+SYM_FUNC_END(test_kprobes_lrsc_gap)
+
#ifdef CONFIG_RISCV_ISA_C
SYM_FUNC_START(test_kprobes_c_j)
@@ -253,3 +296,20 @@ SYM_DATA_START(test_kprobes_functions)
#endif /* CONFIG_RISCV_ISA_C */
RISCV_PTR 0
SYM_DATA_END(test_kprobes_functions)
+
+.section .rodata
+SYM_DATA_START(test_kprobes_lrsc_allowed_addresses)
+ RISCV_PTR .Llrsc_before
+ RISCV_PTR .Llrsc_after
+ RISCV_PTR .Llrsc_gap_pos16
+ RISCV_PTR 0
+SYM_DATA_END(test_kprobes_lrsc_allowed_addresses)
+
+.section .rodata
+SYM_DATA_START(test_kprobes_lrsc_rejected_addresses)
+ RISCV_PTR .Llrsc_lr
+ RISCV_PTR .Llrsc_inside
+ RISCV_PTR .Llrsc_sc
+ RISCV_PTR .Llrsc_gap_pos15
+ RISCV_PTR 0
+SYM_DATA_END(test_kprobes_lrsc_rejected_addresses)
diff --git a/arch/riscv/kernel/tests/kprobes/test-kprobes.c b/arch/riscv/kernel/tests/kprobes/test-kprobes.c
index 027424a3f..dd2fb0749 100644
--- a/arch/riscv/kernel/tests/kprobes/test-kprobes.c
+++ b/arch/riscv/kernel/tests/kprobes/test-kprobes.c
@@ -43,8 +43,42 @@ static void test_kprobe_riscv(struct kunit *test)
kfree(kp);
}
+static void test_kprobe_lrsc(struct kunit *test)
+{
+ int i;
+
+ /* probes outside the LR/SC sequence must be accepted */
+ for (i = 0; test_kprobes_lrsc_allowed_addresses[i]; i++) {
+ struct kprobe kp = {};
+ int ret;
+
+ kp.pre_handler = kprobe_dummy_handler;
+ kp.addr = test_kprobes_lrsc_allowed_addresses[i];
+
+ ret = register_kprobe(&kp);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+ if (!ret)
+ unregister_kprobe(&kp);
+ }
+
+ /* probes on or inside the LR/SC sequence must be rejected */
+ for (i = 0; test_kprobes_lrsc_rejected_addresses[i]; i++) {
+ struct kprobe kp = {};
+ int ret;
+
+ kp.pre_handler = kprobe_dummy_handler;
+ kp.addr = test_kprobes_lrsc_rejected_addresses[i];
+
+ ret = register_kprobe(&kp);
+ KUNIT_EXPECT_LT(test, ret, 0);
+ if (!ret)
+ unregister_kprobe(&kp);
+ }
+}
+
static struct kunit_case kprobes_testcases[] = {
KUNIT_CASE(test_kprobe_riscv),
+ KUNIT_CASE(test_kprobe_lrsc),
{}
};
diff --git a/arch/riscv/kernel/tests/kprobes/test-kprobes.h b/arch/riscv/kernel/tests/kprobes/test-kprobes.h
index 537f44aa9..93393e77a 100644
--- a/arch/riscv/kernel/tests/kprobes/test-kprobes.h
+++ b/arch/riscv/kernel/tests/kprobes/test-kprobes.h
@@ -19,6 +19,12 @@ extern void *test_kprobes_addresses[];
/* array of functions that return KPROBE_TEST_MAGIC */
extern long (*test_kprobes_functions[])(void);
+/* probe points that must be accepted, terminated by NULL */
+extern void *test_kprobes_lrsc_allowed_addresses[];
+
+/* probe points that must be rejected, terminated by NULL */
+extern void *test_kprobes_lrsc_rejected_addresses[];
+
#endif /* __ASSEMBLER__ */
#endif /* TEST_KPROBES_H */
--
2.34.1
prev parent reply other threads:[~2026-10-19 13:41 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-19 13:41 [PATCH v7 0/2] riscv: kprobes: reject probes inside LR/SC sequences Xiaofeng Yuan
2026-10-19 13:41 ` [PATCH v7 1/2] " Xiaofeng Yuan
2026-10-19 13:41 ` Xiaofeng Yuan [this message]
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=20261019134121.1763-3-yuanxiaofeng@eswincomputing.com \
--to=yuanxiaofeng@eswincomputing.com \
--cc=alex@ghiti.fr \
--cc=aou@eecs.berkeley.edu \
--cc=davem@davemloft.net \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=linux-trace-kernel@vger.kernel.org \
--cc=mhiramat@kernel.org \
--cc=namcao@linutronix.de \
--cc=naveen@kernel.org \
--cc=palmer@dabbelt.com \
--cc=pjw@kernel.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®