diff options
author | Will Deacon <will.deacon@arm.com> | 2012-08-25 13:57:28 +0100 |
---|---|---|
committer | Catalin Marinas <catalin.marinas@arm.com> | 2012-09-07 15:54:39 +0100 |
commit | 206de37f316dbf133618f9fcf4eb728745ed44f9 (patch) | |
tree | 44d444cacfa0a2e80ef40bd59826c1fbae66c18a | |
parent | 373a6e24c6152096be1d540469be3aa19bb521c8 (diff) | |
download | linux-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.c | 36 | ||||
-rw-r--r-- | include/linux/elf.h | 1 |
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 */ |