aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWill Deacon <will.deacon@arm.com>2012-08-25 13:57:28 +0100
committerCatalin Marinas <catalin.marinas@arm.com>2012-09-07 15:54:39 +0100
commit206de37f316dbf133618f9fcf4eb728745ed44f9 (patch)
tree44d444cacfa0a2e80ef40bd59826c1fbae66c18a
parent373a6e24c6152096be1d540469be3aa19bb521c8 (diff)
downloadlinux-aarch64-206de37f316dbf133618f9fcf4eb728745ed44f9.tar.gz
arm64: ptrace: use regset for TLS register
Rather than introduce an arch-specific ptrace request (PTRACE_GET_THREAD_INFO), use a regset to describe the TLS register for AArch64 tasks instead. Signed-off-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
-rw-r--r--arch/arm64/kernel/ptrace.c36
-rw-r--r--include/linux/elf.h1
2 files changed, 33 insertions, 4 deletions
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 0d8453a64cc..97932e8349f 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -344,9 +344,33 @@ static int fpr_set(struct task_struct *target, const struct user_regset *regset,
return ret;
}
+static int tls_get(struct task_struct *target, const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ void *kbuf, void __user *ubuf)
+{
+ unsigned long *tls = &target->thread.tp_value;
+ return user_regset_copyout(&pos, &count, &kbuf, &ubuf, tls, 0, -1);
+}
+
+static int tls_set(struct task_struct *target, const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ void *kbuf, void __user *ubuf)
+{
+ int ret;
+ unsigned long tls;
+
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &tls, 0, -1);
+ if (ret)
+ return ret;
+
+ target->thread.tp_value = tls;
+ return ret;
+}
+
enum aarch64_regset {
REGSET_GPR,
REGSET_FPR,
+ REGSET_TLS,
};
static const struct user_regset aarch64_regsets[] = {
@@ -370,6 +394,14 @@ static const struct user_regset aarch64_regsets[] = {
.get = fpr_get,
.set = fpr_set
},
+ [REGSET_TLS] = {
+ .core_note_type = NT_ARM_TLS,
+ .n = 1,
+ .size = sizeof(void *),
+ .align = sizeof(void *),
+ .get = tls_get,
+ .set = tls_set,
+ },
};
static const struct user_regset_view user_aarch64_view = {
@@ -578,10 +610,6 @@ long arch_ptrace(struct task_struct *child, long request,
unsigned long *datap = (unsigned long __user *)data;
switch (request) {
- case PTRACE_GET_THREAD_AREA:
- ret = put_user(child->thread.tp_value, datap);
- break;
-
#ifdef CONFIG_HAVE_HW_BREAKPOINT
case PTRACE_GETHBPREGS:
ret = ptrace_gethbpregs(child, addr, datap);
diff --git a/include/linux/elf.h b/include/linux/elf.h
index 999b4f52e8e..aef297c4599 100644
--- a/include/linux/elf.h
+++ b/include/linux/elf.h
@@ -388,6 +388,7 @@ typedef struct elf64_shdr {
#define NT_S390_LAST_BREAK 0x306 /* s390 breaking event address */
#define NT_S390_SYSTEM_CALL 0x307 /* s390 system call restart data */
#define NT_ARM_VFP 0x400 /* ARM VFP/NEON registers */
+#define NT_ARM_TLS 0x401 /* ARM TLS register */
/* Note header in a PT_NOTE section */