This patch enables get and set of miscellaneous debug registers through
ptrace PTRACE_GETREGSET-PTRACE_SETREGSET interface by implementing new
powerpc specific register set REGSET_MISC support corresponding to the
new ELF core note NT_PPC_MISC added previously in this regard.

Signed-off-by: Anshuman Khandual <khand...@linux.vnet.ibm.com>
---
 arch/powerpc/include/uapi/asm/elf.h |   1 +
 arch/powerpc/kernel/ptrace.c        | 133 ++++++++++++++++++++++++++++++++++++
 2 files changed, 134 insertions(+)

diff --git a/arch/powerpc/include/uapi/asm/elf.h 
b/arch/powerpc/include/uapi/asm/elf.h
index fdc8e2f..a41bd98 100644
--- a/arch/powerpc/include/uapi/asm/elf.h
+++ b/arch/powerpc/include/uapi/asm/elf.h
@@ -93,6 +93,7 @@
 #define ELF_NFPREG     33      /* includes fpscr */
 #define ELF_NVMX       34      /* includes all vector registers */
 #define ELF_NTMSPRREG  7       /* includes TM sprs, org_msr, dscr, tar, ppr */
+#define ELF_NMISCREG   3       /* includes dscr, tar, ppr */
 
 typedef unsigned long elf_greg_t64;
 typedef elf_greg_t64 elf_gregset_t64[ELF_NGREG];
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index b14397c..38a1147 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -1371,6 +1371,122 @@ static int tm_cvmx_set(struct task_struct *target,
 }
 #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
 
+#ifdef CONFIG_PPC64
+/**
+ * get_misc_dbg() - get MISC debug registers
+ * @target:    The target task.
+ * @regset:    The user regset structure.
+ * @pos:       The buffer position.
+ * @count:     Number of bytes to copy.
+ * @kbuf:      Kernel buffer to copy from.
+ * @ubuf:      User buffer to copy into.
+ *
+ * This function gets various miscellaneous debug registers which includes
+ * DSCR, PPR and TAR. The userspace intarface buffer layout is as follows.
+ *
+ * struct {
+ *     unsigned long dscr;
+ *     unsigned long ppr;
+ *     unsigned long tar;
+ * };
+ *
+ * The data element 'tar' in the structure will be valid only if the kernel
+ * has CONFIG_PPC_BOOK3S_64 config option enabled.
+ */
+static int get_misc_dbg(struct task_struct *target,
+                       const struct user_regset *regset, unsigned int pos,
+                       unsigned int count, void *kbuf, void __user *ubuf)
+{
+       int ret;
+
+       /* Build test */
+       BUILD_BUG_ON(TSO(dscr) + 2 * sizeof(unsigned long) != TSO(ppr));
+
+#ifdef CONFIG_PPC_BOOK3S_64
+       BUILD_BUG_ON(TSO(ppr) + sizeof(unsigned long) != TSO(tar));
+#endif
+
+       /* DSCR register */
+       ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+                                       &target->thread.dscr, 0,
+                                       sizeof(unsigned long));
+
+       /* PPR register */
+       if (!ret)
+               ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+                                               &target->thread.ppr,
+                                               sizeof(unsigned long),
+                                               2 * sizeof(unsigned long));
+
+#ifdef CONFIG_PPC_BOOK3S_64
+       /* TAR register */
+       if (!ret)
+               ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+                                               &target->thread.tar,
+                                               2 * sizeof(unsigned long),
+                                               3 * sizeof(unsigned long));
+#endif
+       return ret;
+}
+
+/**
+ * set_misc_dbg() - set MISC debug registers
+ * @target:    The target task.
+ * @regset:    The user regset structure.
+ * @pos:       The buffer position.
+ * @count:     Number of bytes to copy.
+ * @kbuf:      Kernel buffer to copy into.
+ * @ubuf:      User buffer to copy from.
+ *
+ * This function sets various miscellaneous debug registers which includes
+ * DSCR, PPR and TAR. The userspace intarface buffer layout is as follows.
+ *
+ * struct {
+ *     unsigned long dscr;
+ *     unsigned long ppr;
+ *     unsigned long tar;
+ * };
+ *
+ * The data element 'tar' in the structure will be valid only if the kernel
+ * has CONFIG_PPC_BOOK3S_64 config option enabled.
+ */
+static int set_misc_dbg(struct task_struct *target,
+                       const struct user_regset *regset, unsigned int pos,
+                       unsigned int count, const void *kbuf,
+                       const void __user *ubuf)
+{
+       int ret;
+
+       /* Build test */
+       BUILD_BUG_ON(TSO(dscr) + 2 * sizeof(unsigned long) != TSO(ppr));
+
+#ifdef CONFIG_PPC_BOOK3S_64
+       BUILD_BUG_ON(TSO(ppr) + sizeof(unsigned long) != TSO(tar));
+#endif
+
+       /* DSCR register */
+       ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+                                       &target->thread.dscr, 0,
+                                       sizeof(unsigned long));
+
+       /* PPR register */
+       if (!ret)
+               ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+                                               &target->thread.ppr,
+                                               sizeof(unsigned long),
+                                               2 * sizeof(unsigned long));
+#ifdef CONFIG_PPC_BOOK3S_64
+       /* TAR register */
+       if (!ret)
+               ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+                                               &target->thread.tar,
+                                               2 * sizeof(unsigned long),
+                                               3 * sizeof(unsigned long));
+#endif
+       return ret;
+}
+#endif /* CONFIG_PPC64 */
+
 /*
  * These are our native regset flavors.
  */
@@ -1392,6 +1508,9 @@ enum powerpc_regset {
        REGSET_TM_CFPR,         /* TM checkpointed FPR registers */
        REGSET_TM_CVMX,         /* TM checkpointed VMX registers */
 #endif
+#ifdef CONFIG_PPC64
+       REGSET_MISC             /* Miscellaneous debug registers */
+#endif
 };
 
 static const struct user_regset native_regsets[] = {
@@ -1448,6 +1567,13 @@ static const struct user_regset native_regsets[] = {
                .active = tm_cvmx_active, .get = tm_cvmx_get, .set = tm_cvmx_set
        },
 #endif
+#ifdef CONFIG_PPC64
+       [REGSET_MISC] = {
+               .core_note_type = NT_PPC_MISC, .n = ELF_NMISCREG,
+               .size = sizeof(u64), .align = sizeof(u64),
+               .get = get_misc_dbg, .set = set_misc_dbg
+       },
+#endif
 };
 
 static const struct user_regset_view user_ppc_native_view = {
@@ -1694,6 +1820,13 @@ static const struct user_regset compat_regsets[] = {
                .active = tm_cvmx_active, .get = tm_cvmx_get, .set = tm_cvmx_set
        },
 #endif
+#ifdef CONFIG_PPC64
+       [REGSET_MISC] = {
+               .core_note_type = NT_PPC_MISC, .n = ELF_NMISCREG,
+               .size = sizeof(u64), .align = sizeof(u64),
+               .get = get_misc_dbg, .set = set_misc_dbg
+       },
+#endif
 };
 
 static const struct user_regset_view user_ppc_compat_view = {
-- 
1.9.3

_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Reply via email to