diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2007-06-04 01:15:41 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2007-06-14 08:29:56 -0400 |
commit | acd89828484db6371202f5d292781ae6f832eda2 (patch) | |
tree | dff9b004db1d108ece5154b708b273723907d041 /arch/powerpc/kernel/ptrace.c | |
parent | 0b3d5c48a98f7bd2d38962f5a67b480ac5656fb9 (diff) |
[POWERPC] ptrace cleanups
The powerpc ptrace code has some weirdness, like a ptrace-common.h file that
is actually ppc64 only and some of the 32 bits code ifdef'ed inside ptrace.c.
There are also separate implementations for things like get/set_vrregs for
32 and 64 bits which is totally unnecessary.
This patch cleans that up a bit by having a ptrace-common.h which contains
really common code (and makes a lot more code common), and ptrace-ppc32.h and
ptrace-ppc64.h files that contain the few remaining different bits.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/kernel/ptrace.c')
-rw-r--r-- | arch/powerpc/kernel/ptrace.c | 198 |
1 files changed, 4 insertions, 194 deletions
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index 36db6f5cb54c..da53b0d4114b 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c | |||
@@ -36,208 +36,18 @@ | |||
36 | #include <asm/system.h> | 36 | #include <asm/system.h> |
37 | 37 | ||
38 | #ifdef CONFIG_PPC64 | 38 | #ifdef CONFIG_PPC64 |
39 | #include "ptrace-common.h" | 39 | #include "ptrace-ppc64.h" |
40 | #endif | ||
41 | |||
42 | #ifdef CONFIG_PPC32 | ||
43 | /* | ||
44 | * Set of msr bits that gdb can change on behalf of a process. | ||
45 | */ | ||
46 | #if defined(CONFIG_40x) || defined(CONFIG_BOOKE) | ||
47 | #define MSR_DEBUGCHANGE 0 | ||
48 | #else | 40 | #else |
49 | #define MSR_DEBUGCHANGE (MSR_SE | MSR_BE) | 41 | #include "ptrace-ppc32.h" |
50 | #endif | 42 | #endif |
51 | #endif /* CONFIG_PPC32 */ | 43 | |
44 | #include "ptrace-common.h" | ||
52 | 45 | ||
53 | /* | 46 | /* |
54 | * does not yet catch signals sent when the child dies. | 47 | * does not yet catch signals sent when the child dies. |
55 | * in exit.c or in signal.c. | 48 | * in exit.c or in signal.c. |
56 | */ | 49 | */ |
57 | 50 | ||
58 | #ifdef CONFIG_PPC32 | ||
59 | /* | ||
60 | * Get contents of register REGNO in task TASK. | ||
61 | */ | ||
62 | static inline unsigned long get_reg(struct task_struct *task, int regno) | ||
63 | { | ||
64 | if (regno < sizeof(struct pt_regs) / sizeof(unsigned long) | ||
65 | && task->thread.regs != NULL) | ||
66 | return ((unsigned long *)task->thread.regs)[regno]; | ||
67 | return (0); | ||
68 | } | ||
69 | |||
70 | /* | ||
71 | * Write contents of register REGNO in task TASK. | ||
72 | */ | ||
73 | static inline int put_reg(struct task_struct *task, int regno, | ||
74 | unsigned long data) | ||
75 | { | ||
76 | if (regno <= PT_MQ && task->thread.regs != NULL) { | ||
77 | if (regno == PT_MSR) | ||
78 | data = (data & MSR_DEBUGCHANGE) | ||
79 | | (task->thread.regs->msr & ~MSR_DEBUGCHANGE); | ||
80 | ((unsigned long *)task->thread.regs)[regno] = data; | ||
81 | return 0; | ||
82 | } | ||
83 | return -EIO; | ||
84 | } | ||
85 | |||
86 | #ifdef CONFIG_ALTIVEC | ||
87 | /* | ||
88 | * Get contents of AltiVec register state in task TASK | ||
89 | */ | ||
90 | static inline int get_vrregs(unsigned long __user *data, struct task_struct *task) | ||
91 | { | ||
92 | int i, j; | ||
93 | |||
94 | if (!access_ok(VERIFY_WRITE, data, 133 * sizeof(unsigned long))) | ||
95 | return -EFAULT; | ||
96 | |||
97 | /* copy AltiVec registers VR[0] .. VR[31] */ | ||
98 | for (i = 0; i < 32; i++) | ||
99 | for (j = 0; j < 4; j++, data++) | ||
100 | if (__put_user(task->thread.vr[i].u[j], data)) | ||
101 | return -EFAULT; | ||
102 | |||
103 | /* copy VSCR */ | ||
104 | for (i = 0; i < 4; i++, data++) | ||
105 | if (__put_user(task->thread.vscr.u[i], data)) | ||
106 | return -EFAULT; | ||
107 | |||
108 | /* copy VRSAVE */ | ||
109 | if (__put_user(task->thread.vrsave, data)) | ||
110 | return -EFAULT; | ||
111 | |||
112 | return 0; | ||
113 | } | ||
114 | |||
115 | /* | ||
116 | * Write contents of AltiVec register state into task TASK. | ||
117 | */ | ||
118 | static inline int set_vrregs(struct task_struct *task, unsigned long __user *data) | ||
119 | { | ||
120 | int i, j; | ||
121 | |||
122 | if (!access_ok(VERIFY_READ, data, 133 * sizeof(unsigned long))) | ||
123 | return -EFAULT; | ||
124 | |||
125 | /* copy AltiVec registers VR[0] .. VR[31] */ | ||
126 | for (i = 0; i < 32; i++) | ||
127 | for (j = 0; j < 4; j++, data++) | ||
128 | if (__get_user(task->thread.vr[i].u[j], data)) | ||
129 | return -EFAULT; | ||
130 | |||
131 | /* copy VSCR */ | ||
132 | for (i = 0; i < 4; i++, data++) | ||
133 | if (__get_user(task->thread.vscr.u[i], data)) | ||
134 | return -EFAULT; | ||
135 | |||
136 | /* copy VRSAVE */ | ||
137 | if (__get_user(task->thread.vrsave, data)) | ||
138 | return -EFAULT; | ||
139 | |||
140 | return 0; | ||
141 | } | ||
142 | #endif | ||
143 | |||
144 | #ifdef CONFIG_SPE | ||
145 | |||
146 | /* | ||
147 | * For get_evrregs/set_evrregs functions 'data' has the following layout: | ||
148 | * | ||
149 | * struct { | ||
150 | * u32 evr[32]; | ||
151 | * u64 acc; | ||
152 | * u32 spefscr; | ||
153 | * } | ||
154 | */ | ||
155 | |||
156 | /* | ||
157 | * Get contents of SPE register state in task TASK. | ||
158 | */ | ||
159 | static inline int get_evrregs(unsigned long *data, struct task_struct *task) | ||
160 | { | ||
161 | int i; | ||
162 | |||
163 | if (!access_ok(VERIFY_WRITE, data, 35 * sizeof(unsigned long))) | ||
164 | return -EFAULT; | ||
165 | |||
166 | /* copy SPEFSCR */ | ||
167 | if (__put_user(task->thread.spefscr, &data[34])) | ||
168 | return -EFAULT; | ||
169 | |||
170 | /* copy SPE registers EVR[0] .. EVR[31] */ | ||
171 | for (i = 0; i < 32; i++, data++) | ||
172 | if (__put_user(task->thread.evr[i], data)) | ||
173 | return -EFAULT; | ||
174 | |||
175 | /* copy ACC */ | ||
176 | if (__put_user64(task->thread.acc, (unsigned long long *)data)) | ||
177 | return -EFAULT; | ||
178 | |||
179 | return 0; | ||
180 | } | ||
181 | |||
182 | /* | ||
183 | * Write contents of SPE register state into task TASK. | ||
184 | */ | ||
185 | static inline int set_evrregs(struct task_struct *task, unsigned long *data) | ||
186 | { | ||
187 | int i; | ||
188 | |||
189 | if (!access_ok(VERIFY_READ, data, 35 * sizeof(unsigned long))) | ||
190 | return -EFAULT; | ||
191 | |||
192 | /* copy SPEFSCR */ | ||
193 | if (__get_user(task->thread.spefscr, &data[34])) | ||
194 | return -EFAULT; | ||
195 | |||
196 | /* copy SPE registers EVR[0] .. EVR[31] */ | ||
197 | for (i = 0; i < 32; i++, data++) | ||
198 | if (__get_user(task->thread.evr[i], data)) | ||
199 | return -EFAULT; | ||
200 | /* copy ACC */ | ||
201 | if (__get_user64(task->thread.acc, (unsigned long long*)data)) | ||
202 | return -EFAULT; | ||
203 | |||
204 | return 0; | ||
205 | } | ||
206 | #endif /* CONFIG_SPE */ | ||
207 | |||
208 | static inline void | ||
209 | set_single_step(struct task_struct *task) | ||
210 | { | ||
211 | struct pt_regs *regs = task->thread.regs; | ||
212 | |||
213 | if (regs != NULL) { | ||
214 | #if defined(CONFIG_40x) || defined(CONFIG_BOOKE) | ||
215 | task->thread.dbcr0 = DBCR0_IDM | DBCR0_IC; | ||
216 | regs->msr |= MSR_DE; | ||
217 | #else | ||
218 | regs->msr |= MSR_SE; | ||
219 | #endif | ||
220 | } | ||
221 | set_tsk_thread_flag(task, TIF_SINGLESTEP); | ||
222 | } | ||
223 | |||
224 | static inline void | ||
225 | clear_single_step(struct task_struct *task) | ||
226 | { | ||
227 | struct pt_regs *regs = task->thread.regs; | ||
228 | |||
229 | if (regs != NULL) { | ||
230 | #if defined(CONFIG_40x) || defined(CONFIG_BOOKE) | ||
231 | task->thread.dbcr0 = 0; | ||
232 | regs->msr &= ~MSR_DE; | ||
233 | #else | ||
234 | regs->msr &= ~MSR_SE; | ||
235 | #endif | ||
236 | } | ||
237 | clear_tsk_thread_flag(task, TIF_SINGLESTEP); | ||
238 | } | ||
239 | #endif /* CONFIG_PPC32 */ | ||
240 | |||
241 | /* | 51 | /* |
242 | * Called by kernel/ptrace.c when detaching.. | 52 | * Called by kernel/ptrace.c when detaching.. |
243 | * | 53 | * |