public inbox for linux-riscv@lists.infradead.org
 help / color / mirror / Atom feed
From: Yipeng Zou <zouyipeng@huawei.com>
To: <linux-riscv@lists.infradead.org>, <oleg@redhat.com>,
	<paul.walmsley@sifive.com>, <palmer@dabbelt.com>,
	<aou@eecs.berkeley.edu>, <guoren@kernel.org>
Cc: <zouyipeng@huawei.com>
Subject: [PATCH -next 1/2] riscv: ptrace: Implement PTRACE_{PEEK,POKE}USR
Date: Mon, 22 Aug 2022 11:01:04 +0800	[thread overview]
Message-ID: <20220822030105.16053-2-zouyipeng@huawei.com> (raw)
In-Reply-To: <20220822030105.16053-1-zouyipeng@huawei.com>

Implement PTRACE_{PEEK,POKE}USR for RV64 user app to peek/poke tracee's
space register.

As the Linux manual page say: the addr is define to a word offset in
the tracee's USER area.In riscv it's defined in:

struct user {
	struct user_regs {
		ulong pc;	// addr 0
		ulong ra;	// addr 8
		...
		...
		ulong t6;	// addr 248
	}
	struct d_ext_state {
		u64 f[0];	// addr 256
		...
		...
		u64 f[31];	// addr 504
		u32 fcsr;	// addr 512 read-only
	}
}

Signed-off-by: Yipeng Zou <zouyipeng@huawei.com>
---
 arch/riscv/kernel/ptrace.c | 66 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 66 insertions(+)

diff --git a/arch/riscv/kernel/ptrace.c b/arch/riscv/kernel/ptrace.c
index 2ae8280ae475..6dc0687e419f 100644
--- a/arch/riscv/kernel/ptrace.c
+++ b/arch/riscv/kernel/ptrace.c
@@ -215,12 +215,78 @@ void ptrace_disable(struct task_struct *child)
 	clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
 }
 
+static inline unsigned long ptrace_get_gpr_reg(struct task_struct *child, unsigned long offset)
+{
+	struct pt_regs *regs = task_pt_regs(child);
+
+	return *((unsigned long *)regs + offset / sizeof(regs->a0));
+}
+
+static inline int ptrace_set_gpr_reg(struct task_struct *child, unsigned long offset,
+				     unsigned long data)
+{
+	struct pt_regs *regs = task_pt_regs(child);
+
+	*((unsigned long *)regs + offset / sizeof(regs->a0)) = data;
+	return 0;
+}
+
+#ifdef CONFIG_FPU
+static inline unsigned long ptrace_get_fpr_reg(struct task_struct *child, unsigned long offset)
+{
+	struct __riscv_d_ext_state *fstate = &child->thread.fstate;
+
+	if (offset <= offsetof(struct __riscv_d_ext_state, f[31]))
+		return fstate->f[offset / sizeof(fstate->f[0])];
+	else if (offset == offsetof(struct __riscv_d_ext_state, fcsr))
+		return fstate->fcsr;
+	return -EIO;
+}
+
+static inline int ptrace_set_fpr_reg(struct task_struct *child, unsigned long offset,
+				     unsigned long data)
+{
+	struct __riscv_d_ext_state *fstate = &child->thread.fstate;
+
+	if (offset <= offsetof(struct __riscv_d_ext_state, f[31]))
+		fstate->f[offset / sizeof(fstate->f[0])] = data;
+	else /* Only f[0] ~ f[31] can write by PTRACE_POKEUSR */
+		return -EIO;
+	return 0;
+}
+#endif
+
 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) {
+	case PTRACE_PEEKUSR:
+	case PTRACE_POKEUSR:
+		/* addr must be aligned to register size */
+		if (addr & (sizeof(addr) - 1))
+			break;
+
+		if (addr < sizeof(struct user_regs_struct)) {
+			if (request == PTRACE_PEEKUSR)
+				ret = put_user(ptrace_get_gpr_reg(child, addr), datap);
+			else	// PTRACE_POKEUSR
+				ret = ptrace_set_gpr_reg(child, addr, data);
+#ifdef CONFIG_FPU
+		} else if (addr < (sizeof(struct user_regs_struct) +
+				   sizeof(struct __riscv_d_ext_state))) {
+			addr -= sizeof(struct user_regs_struct);
+			if (request == PTRACE_PEEKUSR)
+				ret = put_user(ptrace_get_fpr_reg(child, addr), datap);
+			else	// PTRACE_POKEUSR
+				ret = ptrace_set_fpr_reg(child, addr, data);
+#endif
+		} else {
+			// addr invalid
+		}
+		break;
 	default:
 		ret = ptrace_request(child, request, addr, data);
 		break;
-- 
2.17.1


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

  reply	other threads:[~2022-08-22  3:05 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-08-22  3:01 [PATCH -next 0/2] riscv: ptrace: implement PTRACE_{PEEK,POKE}USR Yipeng Zou
2022-08-22  3:01 ` Yipeng Zou [this message]
2022-08-22  3:01 ` [PATCH -next 2/2] riscv: ptrace: Implement Compat PTRACE_{PEEK,POKE}USR Yipeng Zou
2022-08-22  8:19 ` [PATCH -next 0/2] riscv: ptrace: implement PTRACE_{PEEK,POKE}USR Andreas Schwab
2022-10-06  1:26   ` Palmer Dabbelt
2022-10-08  1:24     ` Yipeng Zou

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=20220822030105.16053-2-zouyipeng@huawei.com \
    --to=zouyipeng@huawei.com \
    --cc=aou@eecs.berkeley.edu \
    --cc=guoren@kernel.org \
    --cc=linux-riscv@lists.infradead.org \
    --cc=oleg@redhat.com \
    --cc=palmer@dabbelt.com \
    --cc=paul.walmsley@sifive.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