From: Richard Kuo <rkuo@codeaurora.org>
To: linux-kernel@vger.kernel.org, linux-hexagon@vger.kernel.org
Subject: [patch v2 19/35] Hexagon: Add ptrace support
Date: Tue, 30 Aug 2011 14:07:48 -0500 [thread overview]
Message-ID: <20110830190801.540467107@codeaurora.org> (raw)
In-Reply-To: 20110830190729.923334292@codeaurora.org
[-- Attachment #1: ptrace.diff --]
[-- Type: text/plain, Size: 11434 bytes --]
Signed-off-by: Richard Kuo <rkuo@codeaurora.org>
---
arch/hexagon/include/asm/ptrace.h | 46 +++++
arch/hexagon/kernel/ptrace.c | 333 ++++++++++++++++++++++++++++++++++++++
2 files changed, 379 insertions(+)
Index: linux-hexagon-kernel/arch/hexagon/include/asm/ptrace.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-hexagon-kernel/arch/hexagon/include/asm/ptrace.h 2011-08-27 20:20:34.605565846 -0500
@@ -0,0 +1,46 @@
+/*
+ * Ptrace definitions for the Hexagon architecture
+ *
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef _ASM_PTRACE_H
+#define _ASM_PTRACE_H
+
+#include <asm/registers.h>
+
+/* arch_ptrace and ptrace_disable use task_struct in arg lists */
+struct task_struct;
+
+/*
+ * ptrace commands not part of Linux base set (but common to essentially
+ * all supported architectures).
+ */
+
+#define PTRACE_GETREGS 12
+#define PTRACE_SETREGS 13
+
+#define N_PTRACE_REGS 44
+
+#define profile_pc(regs) instruction_pointer(regs)
+#define instruction_pointer(regs) pt_elr(regs)
+
+/* kprobe-based event tracer support */
+extern int regs_query_register_offset(const char *name);
+extern const char *regs_query_register_name(unsigned int offset);
+
+#endif
Index: linux-hexagon-kernel/arch/hexagon/kernel/ptrace.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-hexagon-kernel/arch/hexagon/kernel/ptrace.c 2011-08-27 20:22:01.865792314 -0500
@@ -0,0 +1,333 @@
+/*
+ * Ptrace support for Hexagon
+ *
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <generated/compile.h>
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/errno.h>
+#include <linux/ptrace.h>
+#include <linux/regset.h>
+#include <linux/user.h>
+
+#include <asm/system.h>
+#include <asm/user.h>
+
+struct pt_regs_offset {
+ const char *name;
+ int offset;
+};
+
+#define REG_OFFSET_NAME(r) {.name = #r, .offset = offsetof(struct pt_regs, r)}
+#define REG_OFFSET_HVM_NAME(r, s) {.name = #r, \
+ .offset = offsetof(struct pt_regs, s)}
+#define REG_OFFSET_END {.name = NULL, .offset = 0}
+
+static const struct pt_regs_offset regoffset_table[] = {
+ REG_OFFSET_NAME(r00),
+ REG_OFFSET_NAME(r01),
+ REG_OFFSET_NAME(r02),
+ REG_OFFSET_NAME(r03),
+ REG_OFFSET_NAME(r04),
+ REG_OFFSET_NAME(r05),
+ REG_OFFSET_NAME(r06),
+ REG_OFFSET_NAME(r07),
+ REG_OFFSET_NAME(r08),
+ REG_OFFSET_NAME(r09),
+
+ REG_OFFSET_NAME(r10),
+ REG_OFFSET_NAME(r11),
+ REG_OFFSET_NAME(r12),
+ REG_OFFSET_NAME(r13),
+ REG_OFFSET_NAME(r14),
+ REG_OFFSET_NAME(r15),
+ REG_OFFSET_NAME(r16),
+ REG_OFFSET_NAME(r17),
+ REG_OFFSET_NAME(r18),
+ REG_OFFSET_NAME(r19),
+
+ REG_OFFSET_NAME(r20),
+ REG_OFFSET_NAME(r21),
+ REG_OFFSET_NAME(r22),
+ REG_OFFSET_NAME(r23),
+ REG_OFFSET_NAME(r24),
+ REG_OFFSET_NAME(r25),
+ REG_OFFSET_NAME(r26),
+ REG_OFFSET_NAME(r27),
+ REG_OFFSET_NAME(r28),
+ REG_OFFSET_NAME(r29),
+
+ REG_OFFSET_NAME(r30),
+ REG_OFFSET_NAME(r31),
+
+ REG_OFFSET_NAME(gp),
+ REG_OFFSET_NAME(ugp),
+ REG_OFFSET_NAME(sa0),
+ REG_OFFSET_NAME(lc0),
+ REG_OFFSET_NAME(sa1),
+ REG_OFFSET_NAME(lc1),
+ REG_OFFSET_NAME(m0),
+ REG_OFFSET_NAME(m1),
+ REG_OFFSET_NAME(preds),
+ REG_OFFSET_HVM_NAME(pc, hvmer.vmel),
+ REG_OFFSET_HVM_NAME(cause, hvmer.vmest),
+ REG_OFFSET_HVM_NAME(badva, hvmer.vmbadva),
+};
+
+/**
+ * regs_query_register_offset() - query register offset from its name
+ * @name: the name of a register
+ *
+ * regs_query_register_offset() returns the offset of a register in struct
+ * pt_regs from its name. If the name is invalid, this returns -EINVAL;
+ */
+int regs_query_register_offset(const char *name)
+{
+ const struct pt_regs_offset *roff;
+ for (roff = regoffset_table; roff->name != NULL; roff++)
+ if (!strcmp(roff->name, name))
+ return roff->offset;
+ return -EINVAL;
+}
+
+/**
+ * regs_query_register_name() - query register name from its offset
+ * @offset: the offset of a register in struct pt_regs.
+ *
+ * regs_query_register_name() returns the name of a register from its
+ * offset in struct pt_regs. If the @offset is invalid, this returns NULL;
+ */
+const char *regs_query_register_name(unsigned int offset)
+{
+ const struct pt_regs_offset *roff;
+ for (roff = regoffset_table; roff->name != NULL; roff++)
+ if (roff->offset == offset)
+ return roff->name;
+ return NULL;
+}
+
+static int gpr_get(struct task_struct *target,
+ const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ void *kbuf, void __user *ubuf)
+{
+ int ret;
+ unsigned int dummy;
+ struct pt_regs *regs = task_pt_regs(target);
+
+
+ if (!regs)
+ return -EIO;
+
+ /* The general idea here is that the copyout must happen in
+ * exactly the same order in which the userspace expects these
+ * regs. Now, the sequence in userspace does not match the
+ * sequence in the kernel, so everything past the 32 gprs
+ * happens one at a time.
+ */
+ ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ ®s->r00, 0, 32*sizeof(unsigned long));
+
+#define ONEXT(KPT_REG, USR_REG) \
+ if (!ret) \
+ ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, \
+ KPT_REG, offsetof(struct user_regs_struct, USR_REG), \
+ offsetof(struct user_regs_struct, USR_REG) + \
+ sizeof(unsigned long));
+
+ /* Must be exactly same sequence as struct user_regs_struct */
+ ONEXT(®s->gp, gp);
+ ONEXT(®s->ugp, ugp);
+ ONEXT(®s->sa0, sa0);
+ ONEXT(®s->lc0, lc0);
+ ONEXT(®s->sa1, sa1);
+ ONEXT(®s->lc1, lc1);
+ ONEXT(®s->m0, m0);
+ ONEXT(®s->m1, m1);
+ ONEXT(®s->preds, p3_0);
+ ONEXT(&pt_elr(regs), pc);
+ dummy = pt_cause(regs);
+ ONEXT(&dummy, cause);
+ ONEXT(&pt_badva(regs), badva);
+
+ /* Pad the rest with zeros, if needed */
+ if (!ret)
+ ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
+ sizeof(struct user_regs_struct), -1);
+ return ret;
+}
+
+static int gpr_set(struct task_struct *target,
+ const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ const void *kbuf, const void __user *ubuf)
+{
+ int ret;
+ unsigned long bucket;
+ struct pt_regs *regs = task_pt_regs(target);
+
+ if (!regs)
+ return -EIO;
+
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ ®s->r00, 0, 32*sizeof(unsigned long));
+
+#define INEXT(KPT_REG, USR_REG) \
+ if (!ret) \
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, \
+ KPT_REG, offsetof(struct user_regs_struct, USR_REG), \
+ offsetof(struct user_regs_struct, USR_REG) + \
+ sizeof(unsigned long));
+
+ /* Must be exactly same sequence as struct user_regs_struct */
+ INEXT(®s->gp, gp);
+ INEXT(®s->ugp, ugp);
+ INEXT(®s->sa0, sa0);
+ INEXT(®s->lc0, lc0);
+ INEXT(®s->sa1, sa1);
+ INEXT(®s->lc1, lc1);
+ INEXT(®s->m0, m0);
+ INEXT(®s->m1, m1);
+ INEXT(®s->preds, p3_0);
+ INEXT(&pt_elr(regs), pc);
+
+ /* CAUSE and BADVA aren't writeable. */
+ INEXT(&bucket, cause);
+ INEXT(&bucket, badva);
+
+ /* Ignore the rest, if needed */
+ if (!ret)
+ ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
+ sizeof(struct user_regs_struct), -1);
+
+ if (ret)
+ return ret;
+
+ /*
+ * This is special; SP is actually restored by the VM via the
+ * special event record which is set by the special trap.
+ */
+ regs->hvmer.vmpsp = regs->r29;
+ return 0;
+}
+
+enum hexagon_regset {
+ REGSET_GPR,
+};
+
+static const struct user_regset hexagon_regsets[] = {
+ [REGSET_GPR] = {
+ .core_note_type = NT_PRSTATUS,
+ .n = N_PTRACE_REGS,
+ .size = sizeof(unsigned long),
+ .align = sizeof(unsigned long),
+ .get = gpr_get,
+ .set = gpr_set
+ },
+};
+
+static const struct user_regset_view hexagon_user_view = {
+ .name = UTS_MACHINE,
+ .e_machine = ELF_ARCH,
+ .ei_osabi = ELF_OSABI,
+ .regsets = hexagon_regsets,
+ .n = ARRAY_SIZE(hexagon_regsets)
+};
+
+static int ptrace_pokeusr(struct task_struct *target, int regnum,
+ unsigned long data)
+{
+ struct pt_regs *regs = task_pt_regs(target);
+
+ if (!regs || (regnum < 0))
+ return -EIO;
+
+ if (regnum < 32) {
+ unsigned long *p = ®s->r00;
+ *(p+regnum) = data;
+
+ /* Return happens via HVM */
+ if (regnum == 29)
+ regs->hvmer.vmpsp = regs->r29;
+ return 0;
+ }
+
+/*
+ * Todo: sync up with gdb on register passing numbering.
+ */
+
+#define SETREG(KPT_REG, USR_REG) \
+ case offsetof(struct user_regs_struct, USR_REG)>>2: \
+ KPT_REG = data; \
+ return 0;
+
+ /* Other regs are scattered about */
+ switch (regnum) {
+ SETREG(regs->gp, gp);
+ SETREG(regs->ugp, ugp);
+ SETREG(regs->sa0, sa0);
+ SETREG(regs->lc0, lc0);
+ SETREG(regs->sa1, sa1);
+ SETREG(regs->lc1, lc1);
+ SETREG(regs->m0, m0);
+ SETREG(regs->m1, m1);
+ SETREG(regs->preds, p3_0);
+ SETREG(pt_elr(regs), pc);
+ }
+
+ /* CAUSE and BADVA aren't writeable. */
+ return -EINVAL;
+}
+
+void ptrace_disable(struct task_struct *child)
+{
+ /* Boilerplate - resolves to null inline if no HW single-step */
+ user_disable_single_step(child);
+}
+
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
+{
+ void __user *udata = (void __user *) data;
+
+ switch (request) {
+ case PTRACE_POKETEXT: /* write the word at location addr. */
+ case PTRACE_POKEDATA:
+ return generic_ptrace_pokedata(child, addr, data);
+ case PTRACE_POKEUSR: /* write register specified by addr. */
+ return ptrace_pokeusr(child, addr, data);
+ case PTRACE_GETREGS:
+ return copy_regset_to_user(child, &hexagon_user_view,
+ REGSET_GPR, 0,
+ sizeof(struct user_regs_struct),
+ udata);
+ case PTRACE_SETREGS:
+ return copy_regset_from_user(child, &hexagon_user_view,
+ REGSET_GPR, 0,
+ sizeof(struct user_regs_struct),
+ udata);
+ default:
+ return ptrace_request(child, request, addr, data);
+ }
+
+ return 0;
+}
--
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
next prev parent reply other threads:[~2011-08-30 19:07 UTC|newest]
Thread overview: 84+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-08-30 19:07 [patch v2 00/35] Hexagon: Add support for Qualcomm Hexagon architecture Richard Kuo
2011-08-30 19:07 ` [patch v2 01/35] Hexagon: Add generic headers Richard Kuo
2011-08-31 13:24 ` Arnd Bergmann
2011-08-31 19:51 ` David Brown
2011-08-31 20:00 ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 02/35] Hexagon: Core arch-specific header files Richard Kuo
2011-08-31 13:25 ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 03/35] Hexagon: Add bitops support Richard Kuo
2011-08-31 13:26 ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 04/35] Hexagon: Add atomic ops support Richard Kuo
2011-08-31 13:26 ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 05/35] Hexagon: Add syscalls Richard Kuo
2011-08-31 13:34 ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 06/35] Hexagon: Add processor and system headers Richard Kuo
2011-08-31 13:35 ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 07/35] Hexagon: Add threadinfo Richard Kuo
2011-08-31 13:36 ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 08/35] Hexagon: Add delay functions Richard Kuo
2011-08-31 13:39 ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 09/35] Hexagon: Add checksum functions Richard Kuo
2011-08-30 19:34 ` Joe Perches
2011-08-30 19:52 ` Sam Ravnborg
2011-08-31 14:49 ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 10/35] Hexagon: Add memcpy and memset accelerated functions Richard Kuo
2011-08-31 13:40 ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 11/35] Hexagon: Add hypervisor interface Richard Kuo
2011-08-31 13:41 ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 12/35] Hexagon: Export ksyms defined in assembly files Richard Kuo
2011-08-31 13:41 ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 13/35] Hexagon: Support dynamic module loading Richard Kuo
2011-08-31 13:41 ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 14/35] Hexagon: Add signal functions Richard Kuo
2011-08-31 13:42 ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 15/35] Hexagon: Add init_task and process functions Richard Kuo
2011-08-31 13:45 ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 16/35] Hexagon: Add startup code Richard Kuo
2011-08-31 13:46 ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 17/35] Hexagon: Add interrupts Richard Kuo
2011-08-31 13:50 ` Arnd Bergmann
2011-08-31 16:16 ` Linas Vepstas (Code Aurora)
2011-08-30 19:07 ` [patch v2 18/35] Hexagon: Add time and timer functions Richard Kuo
2011-08-31 14:04 ` Arnd Bergmann
2011-08-30 19:07 ` Richard Kuo [this message]
2011-08-31 14:07 ` [patch v2 19/35] Hexagon: Add ptrace support Arnd Bergmann
2011-08-30 19:07 ` [patch v2 20/35] Hexagon: Provide basic debugging and system trap support Richard Kuo
2011-08-31 14:08 ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 21/35] Hexagon: Add SMP support Richard Kuo
2011-08-30 19:30 ` Joe Perches
2011-08-30 20:50 ` Richard Kuo
2011-08-31 15:00 ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 22/35] Hexagon: Add locking types and functions Richard Kuo
2011-08-31 14:09 ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 23/35] Hexagon: Add user access functions Richard Kuo
2011-08-31 14:10 ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 24/35] Hexagon: Provide basic implementation and/or stubs for I/O routines Richard Kuo
2011-08-31 14:28 ` Arnd Bergmann
2011-08-31 14:47 ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 25/35] Hexagon: Implement basic cache-flush support Richard Kuo
2011-08-31 14:49 ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 26/35] Hexagon: Implement basic TLB management routines for Hexagon Richard Kuo
2011-08-31 14:49 ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 27/35] Hexagon: Provide DMA implementation Richard Kuo
2011-08-31 14:51 ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 28/35] Hexagon: Add ioremap support Richard Kuo
2011-08-31 14:53 ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 29/35] Hexagon: Add page table header files & etc Richard Kuo
2011-08-31 14:57 ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 30/35] Hexagon: Add page-fault support Richard Kuo
2011-08-31 14:58 ` Arnd Bergmann
2011-08-30 19:08 ` [patch v2 31/35] Hexagon: kgdb support files Richard Kuo
2011-08-31 14:58 ` Arnd Bergmann
2011-08-30 19:08 ` [patch v2 32/35] Hexagon: Comet platform support Richard Kuo
2011-08-31 15:00 ` Arnd Bergmann
2011-08-30 19:08 ` [patch v2 33/35] Hexagon: Add configuration and makefiles for the Hexagon architecture Richard Kuo
2011-08-31 14:59 ` Arnd Bergmann
2011-08-30 19:08 ` [patch v2 34/35] Hexagon: Add basic stacktrace functionality for " Richard Kuo
2011-08-31 14:59 ` Arnd Bergmann
2011-08-30 19:08 ` [patch v2 35/35] Hexagon: Add self to MAINTAINERS Richard Kuo
2011-08-31 14:59 ` Arnd Bergmann
2011-08-30 20:18 ` [patch v2 00/35] Hexagon: Add support for Qualcomm Hexagon architecture Pekka Enberg
2011-08-30 20:18 ` Pekka Enberg
2011-08-30 20:48 ` Linas Vepstas (Code Aurora)
2011-08-30 20:48 ` Linas Vepstas (Code Aurora)
2011-08-31 15:08 ` Arnd Bergmann
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=20110830190801.540467107@codeaurora.org \
--to=rkuo@codeaurora.org \
--cc=linux-hexagon@vger.kernel.org \
--cc=linux-kernel@vger.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 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.