diff options
author | Roland McGrath <roland@redhat.com> | 2007-12-20 14:57:51 +0300 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2008-02-07 12:38:56 +0300 |
commit | 26f7713020129e556e494fd36b2db1e651e33ba3 (patch) | |
tree | 3c066f2eeb71a2742c9e3b99666a2603d935bdd0 /arch/powerpc/kernel/ptrace.c | |
parent | a4e4b175b6028ebfb2217e0ca1fa0487dc73ccc4 (diff) | |
download | linux-26f7713020129e556e494fd36b2db1e651e33ba3.tar.xz |
[POWERPC] ptrace accessors for special regs MSR and TRAP
This isolates the ptrace code for the special-case registers msr and trap
from the ptrace-layout dispatch code. This should inline away completely.
It cleanly separates the low-level machine magic that has to be done for
deep reasons, from the superficial details of the ptrace interface.
Signed-off-by: Roland McGrath <roland@redhat.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/kernel/ptrace.c')
-rw-r--r-- | arch/powerpc/kernel/ptrace.c | 45 |
1 files changed, 30 insertions, 15 deletions
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index 8c25b0033650..4edc1186f6ac 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c @@ -60,20 +60,38 @@ #define PT_MAX_PUT_REG PT_CCR #endif +static unsigned long get_user_msr(struct task_struct *task) +{ + return task->thread.regs->msr | task->thread.fpexc_mode; +} + +static int set_user_msr(struct task_struct *task, unsigned long msr) +{ + task->thread.regs->msr &= ~MSR_DEBUGCHANGE; + task->thread.regs->msr |= msr & MSR_DEBUGCHANGE; + return 0; +} + +/* + * We prevent mucking around with the reserved area of trap + * which are used internally by the kernel. + */ +static int set_user_trap(struct task_struct *task, unsigned long trap) +{ + task->thread.regs->trap = trap & 0xfff0; + return 0; +} + /* * Get contents of register REGNO in task TASK. */ unsigned long ptrace_get_reg(struct task_struct *task, int regno) { - unsigned long tmp = 0; - if (task->thread.regs == NULL) return -EIO; - if (regno == PT_MSR) { - tmp = ((unsigned long *)task->thread.regs)[PT_MSR]; - return tmp | task->thread.fpexc_mode; - } + if (regno == PT_MSR) + return get_user_msr(task); if (regno < (sizeof(struct pt_regs) / sizeof(unsigned long))) return ((unsigned long *)task->thread.regs)[regno]; @@ -89,15 +107,12 @@ int ptrace_put_reg(struct task_struct *task, int regno, unsigned long data) if (task->thread.regs == NULL) return -EIO; - if (regno <= PT_MAX_PUT_REG || regno == PT_TRAP) { - if (regno == PT_MSR) - data = (data & MSR_DEBUGCHANGE) - | (task->thread.regs->msr & ~MSR_DEBUGCHANGE); - /* We prevent mucking around with the reserved area of trap - * which are used internally by the kernel - */ - if (regno == PT_TRAP) - data &= 0xfff0; + if (regno == PT_MSR) + return set_user_msr(task, data); + if (regno == PT_TRAP) + return set_user_trap(task, data); + + if (regno <= PT_MAX_PUT_REG) { ((unsigned long *)task->thread.regs)[regno] = data; return 0; } |