aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorRoland McGrath <roland@redhat.com>2007-12-20 06:57:48 -0500
committerPaul Mackerras <paulus@samba.org>2008-02-07 04:38:56 -0500
commita4e4b175b6028ebfb2217e0ca1fa0487dc73ccc4 (patch)
tree10034d7d6d04bb1f20d524f80d8d954973deb215 /arch
parent3caf06c6e0656b25f694e3d414191cedcecf76ce (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.c90
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/* 275static int evr_active(struct task_struct *target,
276 * Get contents of SPE register state in task TASK. 276 const struct user_regset *regset)
277 */
278static 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))) 282static 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
305static 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 */
304static int set_evrregs(struct task_struct *task, unsigned long *data) 331static 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; 342static 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