linux-riscv.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: Ben Dooks <ben.dooks@codethink.co.uk>
To: linux-riscv@lists.infradead.org,
	Paul Walmsley <paul.walmsley@sifive.com>,
	Palmer Dabbelt <palmer@dabbelt.com>,
	Albert Ou <aou@eecs.berkeley.edu>
Cc: -linux-kernel@vger.kernel.org, Alexandre Ghiti <alex@ghiti.fr>,
	Javier Jardon <javier.jardon@codethink.co.uk>,
	Ben Dooks <bjdooks@gmail.com>,
	Lawrence Hunter <lawrence.hunter@codethink.co.uk>,
	Roan Richmod <roan.richmond@codethink.co.uk>,
	Sam Grove <sgrove@mips.com>, Chao-ying Fu <cfu@mips.com>,
	Mukunda Aprameya <maprameya@mips.com>,
	Umesh Kalappa <ukalappa@mips.com>,
	Djordje Todorovic <djordje.todorovic@htecgroup.com>,
	Kurt Martin <kmartin@mips.com>,
	allikarjuna Gouda <mgouda@mips.com>,
	Vaibhav Chauthmal <vchauthmal@mips.com>,
	wapnil Agrawal <sagrawal@mips.com>,
	Ben Dooks <ben.dooks@codethink.co.uk>
Subject: [PATCH 09/18] riscv: probes: sort out endian-ness
Date: Fri, 22 Aug 2025 17:52:39 +0100	[thread overview]
Message-ID: <20250822165248.289802-10-ben.dooks@codethink.co.uk> (raw)
In-Reply-To: <20250822165248.289802-1-ben.dooks@codethink.co.uk>

Updated {k,u}probe code to deal with big endian mode where
the instruction stream is always in little endian.

Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
---
 arch/riscv/kernel/probes/decode-insn.c |  2 +-
 arch/riscv/kernel/probes/decode-insn.h |  5 +++++
 arch/riscv/kernel/probes/kprobes.c     | 30 ++++++++++++++++----------
 arch/riscv/kernel/probes/uprobes.c     | 10 ++++-----
 4 files changed, 30 insertions(+), 17 deletions(-)

diff --git a/arch/riscv/kernel/probes/decode-insn.c b/arch/riscv/kernel/probes/decode-insn.c
index 65d9590bfb9f..5f30c10f7d8d 100644
--- a/arch/riscv/kernel/probes/decode-insn.c
+++ b/arch/riscv/kernel/probes/decode-insn.c
@@ -16,7 +16,7 @@
 enum probe_insn __kprobes
 riscv_probe_decode_insn(probe_opcode_t *addr, struct arch_probe_insn *api)
 {
-	probe_opcode_t insn = *addr;
+	probe_opcode_t insn = le32_to_cpu(*addr);
 
 	/*
 	 * Reject instructions list:
diff --git a/arch/riscv/kernel/probes/decode-insn.h b/arch/riscv/kernel/probes/decode-insn.h
index 42269a7d676d..0515deb204b5 100644
--- a/arch/riscv/kernel/probes/decode-insn.h
+++ b/arch/riscv/kernel/probes/decode-insn.h
@@ -15,4 +15,9 @@ enum probe_insn {
 enum probe_insn __kprobes
 riscv_probe_decode_insn(probe_opcode_t *addr, struct arch_probe_insn *asi);
 
+static inline int read_insn_length(void *ptr)
+{
+	return GET_INSN_LENGTH(le16_to_cpu(*(__le16 *)ptr));
+}
+
 #endif /* _RISCV_KERNEL_KPROBES_DECODE_INSN_H */
diff --git a/arch/riscv/kernel/probes/kprobes.c b/arch/riscv/kernel/probes/kprobes.c
index c0738d6c6498..9d496b15d18d 100644
--- a/arch/riscv/kernel/probes/kprobes.c
+++ b/arch/riscv/kernel/probes/kprobes.c
@@ -24,13 +24,13 @@ post_kprobe_handler(struct kprobe *, struct kprobe_ctlblk *, struct pt_regs *);
 
 static void __kprobes arch_prepare_ss_slot(struct kprobe *p)
 {
-	size_t len = GET_INSN_LENGTH(p->opcode);
-	u32 insn = __BUG_INSN_32;
+	size_t len = read_insn_length(&p->opcode);
+	u32 insn = cpu_to_le32(__BUG_INSN_32);
 
 	p->ainsn.api.restore = (unsigned long)p->addr + len;
 
 	patch_text_nosync(p->ainsn.api.insn, &p->opcode, len);
-	patch_text_nosync((void *)p->ainsn.api.insn + len, &insn, GET_INSN_LENGTH(insn));
+	patch_text_nosync((void *)p->ainsn.api.insn + len, &insn, GET_INSN_LENGTH(__BUG_INSN_32));
 }
 
 static void __kprobes arch_prepare_simulate(struct kprobe *p)
@@ -58,7 +58,7 @@ static bool __kprobes arch_check_kprobe(struct kprobe *p)
 		if (tmp == addr)
 			return true;
 
-		tmp += GET_INSN_LENGTH(*(u16 *)tmp);
+		tmp += read_insn_length((u16 *)tmp);
 	}
 
 	return false;
@@ -75,9 +75,9 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
 		return -EILSEQ;
 
 	/* copy instruction */
-	p->opcode = (kprobe_opcode_t)(*insn++);
-	if (GET_INSN_LENGTH(p->opcode) == 4)
-		p->opcode |= (kprobe_opcode_t)(*insn) << 16;
+	*((u16 *)&p->opcode) = (*insn++);
+	if (read_insn_length(&p->opcode) == 4)
+		p->opcode = (kprobe_opcode_t)(*(u32 *)p->addr);
 
 	/* decode instruction */
 	switch (riscv_probe_decode_insn(p->addr, &p->ainsn.api)) {
@@ -107,16 +107,24 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
 /* install breakpoint in text */
 void __kprobes arch_arm_kprobe(struct kprobe *p)
 {
-	size_t len = GET_INSN_LENGTH(p->opcode);
-	u32 insn = len == 4 ? __BUG_INSN_32 : __BUG_INSN_16;
+	size_t len = read_insn_length(&p->opcode);
+	u32 insn;
+
+	if (len == 4)
+		insn = cpu_to_le32(__BUG_INSN_32);
+	else {
+		insn = cpu_to_le16(__BUG_INSN_16);
+		insn |= cpu_to_le16(__BUG_INSN_16) << 16;
+	}
 
+	pr_info("%s: patching %px (%d bytes)\n", __func__, p->addr, (int)len);
 	patch_text(p->addr, &insn, len);
 }
 
 /* remove breakpoint from text */
 void __kprobes arch_disarm_kprobe(struct kprobe *p)
 {
-	size_t len = GET_INSN_LENGTH(p->opcode);
+	size_t len = read_insn_length(&p->opcode);
 
 	patch_text(p->addr, &p->opcode, len);
 }
@@ -336,7 +344,7 @@ kprobe_single_step_handler(struct pt_regs *regs)
 	struct kprobe *cur = kprobe_running();
 
 	if (cur && (kcb->kprobe_status & (KPROBE_HIT_SS | KPROBE_REENTER)) &&
-	    ((unsigned long)&cur->ainsn.api.insn[0] + GET_INSN_LENGTH(cur->opcode) == addr)) {
+	    ((unsigned long)&cur->ainsn.api.insn[0] + read_insn_length(&cur->opcode) == addr)) {
 		kprobes_restore_local_irqflag(kcb, regs);
 		post_kprobe_handler(cur, kcb, regs);
 		return true;
diff --git a/arch/riscv/kernel/probes/uprobes.c b/arch/riscv/kernel/probes/uprobes.c
index cc15f7ca6cc1..ffdda8771380 100644
--- a/arch/riscv/kernel/probes/uprobes.c
+++ b/arch/riscv/kernel/probes/uprobes.c
@@ -12,9 +12,9 @@
 bool is_swbp_insn(uprobe_opcode_t *insn)
 {
 #ifdef CONFIG_RISCV_ISA_C
-	return (*insn & 0xffff) == UPROBE_SWBP_INSN;
+	return (*(u16 *)insn) == cpu_to_le16(UPROBE_SWBP_INSN);
 #else
-	return *insn == UPROBE_SWBP_INSN;
+	return *insn == cpu_to_le32(UPROBE_SWBP_INSN);
 #endif
 }
 
@@ -35,7 +35,7 @@ int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm,
 
 	opcode = *(probe_opcode_t *)(&auprobe->insn[0]);
 
-	auprobe->insn_size = GET_INSN_LENGTH(opcode);
+	auprobe->insn_size = GET_INSN_LENGTH(le32_to_cpu(opcode));
 
 	switch (riscv_probe_decode_insn(&opcode, &auprobe->api)) {
 	case INSN_REJECTED:
@@ -173,8 +173,8 @@ void arch_uprobe_copy_ixol(struct page *page, unsigned long vaddr,
 
 	/* Add ebreak behind opcode to simulate singlestep */
 	if (vaddr) {
-		dst += GET_INSN_LENGTH(*(probe_opcode_t *)src);
-		*(uprobe_opcode_t *)dst = __BUG_INSN_32;
+		dst += read_insn_length(src);
+		*(uprobe_opcode_t *)dst = cpu_to_le32(__BUG_INSN_32);
 	}
 
 	flush_icache_range(start, start + len);
-- 
2.37.2.352.g3c44437643


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

  parent reply	other threads:[~2025-08-23  6:40 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-08-22 16:52 RISC-V big-endian support Ben Dooks
2025-08-22 16:52 ` [PATCH 01/18] riscv: add initial kconfig and build flags for big-endian Ben Dooks
2025-08-22 16:52 ` [PATCH 02/18] riscv: update byteorder.h " Ben Dooks
2025-08-22 16:52 ` [PATCH 03/18] riscv: disable vector if big-endian, gcc unsupported option Ben Dooks
2025-08-22 16:52 ` [PATCH 04/18] riscv: word-at-atime: move to generic if we're big endian Ben Dooks
2025-08-22 16:52 ` [PATCH 05/18] riscv: asm: use .insn for making custom instructioons Ben Dooks
2025-08-22 16:52 ` [PATCH 06/18] kconfig: remove CONFIG_COMAPT for big-endian Ben Dooks
2025-08-22 16:52 ` [PATCH 07/18] riscv: fixup use of natural endian on instructions Ben Dooks
2025-08-22 16:52 ` [PATCH 08/18] riscv: bpf: big endian fixes, updated BPF_ALU ops Ben Dooks
2025-08-22 16:52 ` Ben Dooks [this message]
2025-08-22 16:52 ` [PATCH 10/18] riscv: ftrace big endian updates Ben Dooks
2025-08-22 16:52 ` [PATCH 11/18] riscv: traps: make insn fetch common in unknown instruction Ben Dooks
2025-08-22 16:52 ` [PATCH 12/18] riscv: threads need UBE flag setting if big-endian Ben Dooks
2025-08-22 16:52 ` [PATCH 13/18] riscv: fixes for big-endian library routines Ben Dooks
2025-08-22 16:52 ` [PATCH 14/18] riscv: update to add ASM_INSN for .2byte instructions Ben Dooks
2025-08-22 16:52 ` [PATCH 15/18] KVM: riscv: set HSTATUS big endian same as build Ben Dooks
2025-08-22 16:52 ` [PATCH 16/18] KVM: riscv: add hstatus to allow endian control Ben Dooks
2025-08-22 16:52 ` [PATCH 17/18] KVM: riscv: instructions are little endian Ben Dooks
2025-08-22 16:52 ` [PATCH 18/18] KVM: riscv: add warning if undecoded instruction Ben Dooks

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=20250822165248.289802-10-ben.dooks@codethink.co.uk \
    --to=ben.dooks@codethink.co.uk \
    --cc=-linux-kernel@vger.kernel.org \
    --cc=alex@ghiti.fr \
    --cc=aou@eecs.berkeley.edu \
    --cc=bjdooks@gmail.com \
    --cc=cfu@mips.com \
    --cc=djordje.todorovic@htecgroup.com \
    --cc=javier.jardon@codethink.co.uk \
    --cc=kmartin@mips.com \
    --cc=lawrence.hunter@codethink.co.uk \
    --cc=linux-riscv@lists.infradead.org \
    --cc=maprameya@mips.com \
    --cc=mgouda@mips.com \
    --cc=palmer@dabbelt.com \
    --cc=paul.walmsley@sifive.com \
    --cc=roan.richmond@codethink.co.uk \
    --cc=sagrawal@mips.com \
    --cc=sgrove@mips.com \
    --cc=ukalappa@mips.com \
    --cc=vchauthmal@mips.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;
as well as URLs for NNTP newsgroup(s).