summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnshuman Khandual <khandual@linux.vnet.ibm.com>2016-07-28 10:57:43 +0800
committerMichael Ellerman <mpe@ellerman.id.au>2016-08-01 11:15:23 +1000
commitcf89d4e1b181bda27a5d52f4afd239ea07e84eb0 (patch)
tree0e3bfda868eb78f5c26d9645a57a53d322f1bedc
parentfa439810cc1b3c927ec24ede17d02467e1b143a1 (diff)
powerpc/ptrace: Enable support for EBB registers
This patch enables support for EBB state registers related ELF core note NT_PPC_EBB based ptrace requests through PTRACE_GETREGSET, PTRACE_SETREGSET calls. This is achieved through adding one new register sets REGSET_EBB in powerpc corresponding to the ELF core note sections added in this regard. It also implements the get, set and active functions for this new register sets added. Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com> Signed-off-by: Simon Guo <wei.guo.simon@gmail.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-rw-r--r--arch/powerpc/include/uapi/asm/elf.h1
-rw-r--r--arch/powerpc/kernel/ptrace.c75
2 files changed, 76 insertions, 0 deletions
diff --git a/arch/powerpc/include/uapi/asm/elf.h b/arch/powerpc/include/uapi/asm/elf.h
index e703c646163b..8c4d71a59259 100644
--- a/arch/powerpc/include/uapi/asm/elf.h
+++ b/arch/powerpc/include/uapi/asm/elf.h
@@ -94,6 +94,7 @@
#define ELF_NVMX 34 /* includes all vector registers */
#define ELF_NVSX 32 /* includes all VSX registers */
#define ELF_NTMSPRREG 3 /* include tfhar, tfiar, texasr */
+#define ELF_NEBB 3 /* includes ebbrr, ebbhr, bescr */
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 a1e166ae4b14..7942f9c575ef 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -1760,6 +1760,70 @@ static int tar_set(struct task_struct *target,
&target->thread.tar, 0, sizeof(u64));
return ret;
}
+
+static int ebb_active(struct task_struct *target,
+ const struct user_regset *regset)
+{
+ if (!cpu_has_feature(CPU_FTR_ARCH_207S))
+ return -ENODEV;
+
+ if (target->thread.used_ebb)
+ return regset->n;
+
+ return 0;
+}
+
+static int ebb_get(struct task_struct *target,
+ const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ void *kbuf, void __user *ubuf)
+{
+ /* Build tests */
+ BUILD_BUG_ON(TSO(ebbrr) + sizeof(unsigned long) != TSO(ebbhr));
+ BUILD_BUG_ON(TSO(ebbhr) + sizeof(unsigned long) != TSO(bescr));
+
+ if (!cpu_has_feature(CPU_FTR_ARCH_207S))
+ return -ENODEV;
+
+ if (!target->thread.used_ebb)
+ return -ENODATA;
+
+ return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ &target->thread.ebbrr, 0, 3 * sizeof(unsigned long));
+}
+
+static int ebb_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 = 0;
+
+ /* Build tests */
+ BUILD_BUG_ON(TSO(ebbrr) + sizeof(unsigned long) != TSO(ebbhr));
+ BUILD_BUG_ON(TSO(ebbhr) + sizeof(unsigned long) != TSO(bescr));
+
+ if (!cpu_has_feature(CPU_FTR_ARCH_207S))
+ return -ENODEV;
+
+ if (target->thread.used_ebb)
+ return -ENODATA;
+
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &target->thread.ebbrr, 0, sizeof(unsigned long));
+
+ if (!ret)
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &target->thread.ebbhr, sizeof(unsigned long),
+ 2 * sizeof(unsigned long));
+
+ if (!ret)
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &target->thread.bescr,
+ 2 * sizeof(unsigned long), 3 * sizeof(unsigned long));
+
+ return ret;
+}
#endif
/*
* These are our native regset flavors.
@@ -1792,6 +1856,7 @@ enum powerpc_regset {
#endif
#ifdef CONFIG_PPC_BOOK3S_64
REGSET_TAR, /* TAR register */
+ REGSET_EBB, /* EBB registers */
#endif
};
@@ -1887,6 +1952,11 @@ static const struct user_regset native_regsets[] = {
.size = sizeof(u64), .align = sizeof(u64),
.get = tar_get, .set = tar_set
},
+ [REGSET_EBB] = {
+ .core_note_type = NT_PPC_EBB, .n = ELF_NEBB,
+ .size = sizeof(u64), .align = sizeof(u64),
+ .active = ebb_active, .get = ebb_get, .set = ebb_set
+ },
#endif
};
@@ -2173,6 +2243,11 @@ static const struct user_regset compat_regsets[] = {
.size = sizeof(u64), .align = sizeof(u64),
.get = tar_get, .set = tar_set
},
+ [REGSET_EBB] = {
+ .core_note_type = NT_PPC_EBB, .n = ELF_NEBB,
+ .size = sizeof(u64), .align = sizeof(u64),
+ .active = ebb_active, .get = ebb_get, .set = ebb_set
+ },
#endif
};