aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/ptrace.c
diff options
context:
space:
mode:
authorRoland McGrath <roland@redhat.com>2007-12-20 06:57:51 -0500
committerPaul Mackerras <paulus@samba.org>2008-02-07 04:38:56 -0500
commit26f7713020129e556e494fd36b2db1e651e33ba3 (patch)
tree3c066f2eeb71a2742c9e3b99666a2603d935bdd0 /arch/powerpc/kernel/ptrace.c
parenta4e4b175b6028ebfb2217e0ca1fa0487dc73ccc4 (diff)
[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.c45
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 @@
60#define PT_MAX_PUT_REG PT_CCR 60#define PT_MAX_PUT_REG PT_CCR
61#endif 61#endif
62 62
63static unsigned long get_user_msr(struct task_struct *task)
64{
65 return task->thread.regs->msr | task->thread.fpexc_mode;
66}
67
68static int set_user_msr(struct task_struct *task, unsigned long msr)
69{
70 task->thread.regs->msr &= ~MSR_DEBUGCHANGE;
71 task->thread.regs->msr |= msr & MSR_DEBUGCHANGE;
72 return 0;
73}
74
75/*
76 * We prevent mucking around with the reserved area of trap
77 * which are used internally by the kernel.
78 */
79static int set_user_trap(struct task_struct *task, unsigned long trap)
80{
81 task->thread.regs->trap = trap & 0xfff0;
82 return 0;
83}
84
63/* 85/*
64 * Get contents of register REGNO in task TASK. 86 * Get contents of register REGNO in task TASK.
65 */ 87 */
66unsigned long ptrace_get_reg(struct task_struct *task, int regno) 88unsigned long ptrace_get_reg(struct task_struct *task, int regno)
67{ 89{
68 unsigned long tmp = 0;
69
70 if (task->thread.regs == NULL) 90 if (task->thread.regs == NULL)
71 return -EIO; 91 return -EIO;
72 92
73 if (regno == PT_MSR) { 93 if (regno == PT_MSR)
74 tmp = ((unsigned long *)task->thread.regs)[PT_MSR]; 94 return get_user_msr(task);
75 return tmp | task->thread.fpexc_mode;
76 }
77 95
78 if (regno < (sizeof(struct pt_regs) / sizeof(unsigned long))) 96 if (regno < (sizeof(struct pt_regs) / sizeof(unsigned long)))
79 return ((unsigned long *)task->thread.regs)[regno]; 97 return ((unsigned long *)task->thread.regs)[regno];
@@ -89,15 +107,12 @@ int ptrace_put_reg(struct task_struct *task, int regno, unsigned long data)
89 if (task->thread.regs == NULL) 107 if (task->thread.regs == NULL)
90 return -EIO; 108 return -EIO;
91 109
92 if (regno <= PT_MAX_PUT_REG || regno == PT_TRAP) { 110 if (regno == PT_MSR)
93 if (regno == PT_MSR) 111 return set_user_msr(task, data);
94 data = (data & MSR_DEBUGCHANGE) 112 if (regno == PT_TRAP)
95 | (task->thread.regs->msr & ~MSR_DEBUGCHANGE); 113 return set_user_trap(task, data);
96 /* We prevent mucking around with the reserved area of trap 114
97 * which are used internally by the kernel 115 if (regno <= PT_MAX_PUT_REG) {
98 */
99 if (regno == PT_TRAP)
100 data &= 0xfff0;
101 ((unsigned long *)task->thread.regs)[regno] = data; 116 ((unsigned long *)task->thread.regs)[regno] = data;
102 return 0; 117 return 0;
103 } 118 }