diff options
author | Roland McGrath <roland@redhat.com> | 2007-12-20 06:57:48 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2008-02-07 04:38:56 -0500 |
commit | a4e4b175b6028ebfb2217e0ca1fa0487dc73ccc4 (patch) | |
tree | 10034d7d6d04bb1f20d524f80d8d954973deb215 /arch | |
parent | 3caf06c6e0656b25f694e3d414191cedcecf76ce (diff) |
[POWERPC] Use user_regset accessors for SPE regs
This implements user_regset-style accessors for the powerpc SPE data,
and rewrites the existing ptrace code in terms of those calls.
Signed-off-by: Roland McGrath <roland@redhat.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/kernel/ptrace.c | 90 |
1 files changed, 57 insertions, 33 deletions
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index 7cdf35a7c833..8c25b0033650 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c | |||
@@ -272,55 +272,79 @@ static int set_vrregs(struct task_struct *task, unsigned long __user *data) | |||
272 | * } | 272 | * } |
273 | */ | 273 | */ |
274 | 274 | ||
275 | /* | 275 | static int evr_active(struct task_struct *target, |
276 | * Get contents of SPE register state in task TASK. | 276 | const struct user_regset *regset) |
277 | */ | ||
278 | static int get_evrregs(unsigned long *data, struct task_struct *task) | ||
279 | { | 277 | { |
280 | int i; | 278 | flush_spe_to_thread(target); |
279 | return target->thread.used_spe ? regset->n : 0; | ||
280 | } | ||
281 | 281 | ||
282 | if (!access_ok(VERIFY_WRITE, data, 35 * sizeof(unsigned long))) | 282 | static int evr_get(struct task_struct *target, const struct user_regset *regset, |
283 | return -EFAULT; | 283 | unsigned int pos, unsigned int count, |
284 | void *kbuf, void __user *ubuf) | ||
285 | { | ||
286 | int ret; | ||
284 | 287 | ||
285 | /* copy SPEFSCR */ | 288 | flush_spe_to_thread(target); |
286 | if (__put_user(task->thread.spefscr, &data[34])) | ||
287 | return -EFAULT; | ||
288 | 289 | ||
289 | /* copy SPE registers EVR[0] .. EVR[31] */ | 290 | ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, |
290 | for (i = 0; i < 32; i++, data++) | 291 | &target->thread.evr, |
291 | if (__put_user(task->thread.evr[i], data)) | 292 | 0, sizeof(target->thread.evr)); |
292 | return -EFAULT; | ||
293 | 293 | ||
294 | /* copy ACC */ | 294 | BUILD_BUG_ON(offsetof(struct thread_struct, acc) + sizeof(u64) != |
295 | if (__put_user64(task->thread.acc, (unsigned long long *)data)) | 295 | offsetof(struct thread_struct, spefscr)); |
296 | return -EFAULT; | ||
297 | 296 | ||
298 | return 0; | 297 | if (!ret) |
298 | ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, | ||
299 | &target->thread.acc, | ||
300 | sizeof(target->thread.evr), -1); | ||
301 | |||
302 | return ret; | ||
303 | } | ||
304 | |||
305 | static int evr_set(struct task_struct *target, const struct user_regset *regset, | ||
306 | unsigned int pos, unsigned int count, | ||
307 | const void *kbuf, const void __user *ubuf) | ||
308 | { | ||
309 | int ret; | ||
310 | |||
311 | flush_spe_to_thread(target); | ||
312 | |||
313 | ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, | ||
314 | &target->thread.evr, | ||
315 | 0, sizeof(target->thread.evr)); | ||
316 | |||
317 | BUILD_BUG_ON(offsetof(struct thread_struct, acc) + sizeof(u64) != | ||
318 | offsetof(struct thread_struct, spefscr)); | ||
319 | |||
320 | if (!ret) | ||
321 | ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, | ||
322 | &target->thread.acc, | ||
323 | sizeof(target->thread.evr), -1); | ||
324 | |||
325 | return ret; | ||
299 | } | 326 | } |
300 | 327 | ||
301 | /* | 328 | /* |
302 | * Write contents of SPE register state into task TASK. | 329 | * Get contents of SPE register state in task TASK. |
303 | */ | 330 | */ |
304 | static int set_evrregs(struct task_struct *task, unsigned long *data) | 331 | static int get_evrregs(unsigned long __user *data, struct task_struct *task) |
305 | { | 332 | { |
306 | int i; | 333 | if (!access_ok(VERIFY_WRITE, data, 35 * sizeof(u32))) |
307 | |||
308 | if (!access_ok(VERIFY_READ, data, 35 * sizeof(unsigned long))) | ||
309 | return -EFAULT; | 334 | return -EFAULT; |
310 | 335 | ||
311 | /* copy SPEFSCR */ | 336 | return evr_get(task, NULL, 0, 35 * sizeof(u32), NULL, data); |
312 | if (__get_user(task->thread.spefscr, &data[34])) | 337 | } |
313 | return -EFAULT; | ||
314 | 338 | ||
315 | /* copy SPE registers EVR[0] .. EVR[31] */ | 339 | /* |
316 | for (i = 0; i < 32; i++, data++) | 340 | * Write contents of SPE register state into task TASK. |
317 | if (__get_user(task->thread.evr[i], data)) | 341 | */ |
318 | return -EFAULT; | 342 | static int set_evrregs(struct task_struct *task, unsigned long *data) |
319 | /* copy ACC */ | 343 | { |
320 | if (__get_user64(task->thread.acc, (unsigned long long*)data)) | 344 | if (!access_ok(VERIFY_READ, data, 35 * sizeof(u32))) |
321 | return -EFAULT; | 345 | return -EFAULT; |
322 | 346 | ||
323 | return 0; | 347 | return evr_set(task, NULL, 0, 35 * sizeof(u32), NULL, data); |
324 | } | 348 | } |
325 | #endif /* CONFIG_SPE */ | 349 | #endif /* CONFIG_SPE */ |
326 | 350 | ||