Linux-RISC-V Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: "Clément Léger" <clement.leger@linux.dev>
To: Paul Walmsley <pjw@kernel.org>,
	Palmer Dabbelt <palmer@dabbelt.com>,
	Albert Ou <aou@eecs.berkeley.edu>
Cc: "Clément Léger" <clement.leger@linux.dev>,
	"Alexandre Ghiti" <alex@ghiti.fr>,
	WangYuli <wangyuli@uniontech.com>,
	linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org
Subject: [PATCH 1/3] riscv: kgdb: use patch_insn_write() to set breakpoints
Date: Fri, 13 Nov 2026 08:16:12 +0100	[thread overview]
Message-ID: <20261113071616.219623-2-clement.leger@linux.dev> (raw)
In-Reply-To: <20261113071616.219623-1-clement.leger@linux.dev>

When using CONFIG_STRICT_KERNEL_RWX, the text section is not writable
and copy_to_kernel_nofault() returns -EFAULT. Fix this by using
patch_insn_write() were applicable and implement
kgdb_arch_set_breakpoint()/kgdb_arch_remove_breakpoint().

patch_insn_write() correctly remaps the text as writable using a fixmap
alias.

Signed-off-by: Clément Léger <clement.leger@linux.dev>
---
 arch/riscv/kernel/kgdb.c | 34 +++++++++++++++++++++++++++++-----
 1 file changed, 29 insertions(+), 5 deletions(-)

diff --git a/arch/riscv/kernel/kgdb.c b/arch/riscv/kernel/kgdb.c
index 0bf629204c76..4ad817698af8 100644
--- a/arch/riscv/kernel/kgdb.c
+++ b/arch/riscv/kernel/kgdb.c
@@ -12,6 +12,7 @@
 #include <asm/cacheflush.h>
 #include <asm/gdb_xml.h>
 #include <asm/insn.h>
+#include <asm/text-patching.h>
 
 enum {
 	NOT_KGDB_BREAK = 0,
@@ -134,9 +135,9 @@ static int do_single_step(struct pt_regs *regs)
 	stepped_address = addr;
 
 	/* Replace the op code with the break instruction */
-	error = copy_to_kernel_nofault((void *)stepped_address,
-				   arch_kgdb_ops.gdb_bpt_instr,
-				   BREAK_INSTR_SIZE);
+	error = patch_insn_write((void *)stepped_address,
+				 arch_kgdb_ops.gdb_bpt_instr,
+				 BREAK_INSTR_SIZE);
 	/* Flush and return */
 	if (!error) {
 		flush_icache_range(addr, addr + BREAK_INSTR_SIZE);
@@ -154,8 +155,8 @@ static int do_single_step(struct pt_regs *regs)
 static void undo_single_step(struct pt_regs *regs)
 {
 	if (stepped_opcode != 0) {
-		copy_to_kernel_nofault((void *)stepped_address,
-				   (void *)&stepped_opcode, BREAK_INSTR_SIZE);
+		patch_insn_write((void *)stepped_address,
+				 (void *)&stepped_opcode, BREAK_INSTR_SIZE);
 		flush_icache_range(stepped_address,
 				   stepped_address + BREAK_INSTR_SIZE);
 	}
@@ -261,6 +262,29 @@ noinline void arch_kgdb_breakpoint(void)
 	    "kgdb_compiled_break: ebreak\n");
 }
 
+/*
+ * Kernel text may be read-only (CONFIG_STRICT_KERNEL_RWX), so software
+ * breakpoints must be planted through the writable patch alias instead of
+ * writing the text address directly.
+ */
+int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
+{
+	int err;
+
+	err = copy_from_kernel_nofault(bpt->saved_instr, (char *)bpt->bpt_addr,
+				       BREAK_INSTR_SIZE);
+	if (err)
+		return err;
+	return patch_insn_write((void *)bpt->bpt_addr,
+				arch_kgdb_ops.gdb_bpt_instr, BREAK_INSTR_SIZE);
+}
+
+int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt)
+{
+	return patch_insn_write((void *)bpt->bpt_addr, bpt->saved_instr,
+				BREAK_INSTR_SIZE);
+}
+
 void kgdb_arch_handle_qxfer_pkt(char *remcom_in_buffer,
 				char *remcom_out_buffer)
 {
-- 
2.55.0


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

  reply	other threads:[~2026-11-13  7:17 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-13  7:16 [PATCH 0/3] riscv: kgdb: Fix break size, insn patch and masking Clément Léger
2026-11-13  7:16 ` Clément Léger [this message]
2026-11-13  7:16 ` [PATCH 2/3] riscv: kgdb: use BREAK_INSTR_SIZE instead of hardcoded value Clément Léger
2026-11-13  7:16 ` [PATCH 3/3] riscv: kgdb: clear bit 0 of single-step jump targets Clément Léger

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=20261113071616.219623-2-clement.leger@linux.dev \
    --to=clement.leger@linux.dev \
    --cc=alex@ghiti.fr \
    --cc=aou@eecs.berkeley.edu \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-riscv@lists.infradead.org \
    --cc=palmer@dabbelt.com \
    --cc=pjw@kernel.org \
    --cc=wangyuli@uniontech.com \
    /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