Commit d256eb8db60e36fc5dd0a27ce8a64f65df31f7b5
1 parent
9473272af3
Exists in
master
and in
7 other branches
[SPARC32]: Use regsets in arch_ptrace().
Signed-off-by: David S. Miller <davem@davemloft.net>
Showing 1 changed file with 47 additions and 68 deletions Side-by-side Diff
arch/sparc/kernel/ptrace.c
... | ... | @@ -322,54 +322,39 @@ |
322 | 322 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) |
323 | 323 | { |
324 | 324 | unsigned long addr2 = current->thread.kregs->u_regs[UREG_I4]; |
325 | - int i, ret; | |
325 | + const struct user_regset_view *view; | |
326 | + int ret; | |
326 | 327 | |
328 | + view = task_user_regset_view(child); | |
329 | + | |
327 | 330 | switch(request) { |
328 | 331 | case PTRACE_GETREGS: { |
329 | 332 | struct pt_regs __user *pregs = (struct pt_regs __user *) addr; |
330 | - struct pt_regs *cregs = child->thread.kregs; | |
331 | 333 | |
332 | - ret = -EFAULT; | |
333 | - if (!access_ok(VERIFY_WRITE, pregs, sizeof(struct pt_regs))) | |
334 | - break; | |
335 | - | |
336 | - __put_user(cregs->psr, (&pregs->psr)); | |
337 | - __put_user(cregs->pc, (&pregs->pc)); | |
338 | - __put_user(cregs->npc, (&pregs->npc)); | |
339 | - __put_user(cregs->y, (&pregs->y)); | |
340 | - for (i = 1; i < 16; i++) | |
341 | - __put_user(cregs->u_regs[i], &pregs->u_regs[i - 1]); | |
342 | - ret = 0; | |
334 | + ret = copy_regset_to_user(child, view, REGSET_GENERAL, | |
335 | + 32 * sizeof(u32), | |
336 | + 4 * sizeof(u32), | |
337 | + &pregs->psr); | |
338 | + if (!ret) | |
339 | + copy_regset_to_user(child, view, REGSET_GENERAL, | |
340 | + 1 * sizeof(u32), | |
341 | + 15 * sizeof(u32), | |
342 | + &pregs->u_regs[0]); | |
343 | 343 | break; |
344 | 344 | } |
345 | 345 | |
346 | 346 | case PTRACE_SETREGS: { |
347 | 347 | struct pt_regs __user *pregs = (struct pt_regs __user *) addr; |
348 | - struct pt_regs *cregs = child->thread.kregs; | |
349 | - unsigned long psr, pc, npc, y; | |
350 | 348 | |
351 | - /* Must be careful, tracing process can only set certain | |
352 | - * bits in the psr. | |
353 | - */ | |
354 | - ret = -EFAULT; | |
355 | - if (!access_ok(VERIFY_READ, pregs, sizeof(struct pt_regs))) | |
356 | - break; | |
357 | - | |
358 | - __get_user(psr, (&pregs->psr)); | |
359 | - __get_user(pc, (&pregs->pc)); | |
360 | - __get_user(npc, (&pregs->npc)); | |
361 | - __get_user(y, (&pregs->y)); | |
362 | - psr &= PSR_ICC; | |
363 | - cregs->psr &= ~PSR_ICC; | |
364 | - cregs->psr |= psr; | |
365 | - if (!((pc | npc) & 3)) { | |
366 | - cregs->pc = pc; | |
367 | - cregs->npc =npc; | |
368 | - } | |
369 | - cregs->y = y; | |
370 | - for (i = 1; i < 16; i++) | |
371 | - __get_user(cregs->u_regs[i], &pregs->u_regs[i-1]); | |
372 | - ret = 0; | |
349 | + ret = copy_regset_from_user(child, view, REGSET_GENERAL, | |
350 | + 32 * sizeof(u32), | |
351 | + 4 * sizeof(u32), | |
352 | + &pregs->psr); | |
353 | + if (!ret) | |
354 | + copy_regset_from_user(child, view, REGSET_GENERAL, | |
355 | + 1 * sizeof(u32), | |
356 | + 15 * sizeof(u32), | |
357 | + &pregs->u_regs[0]); | |
373 | 358 | break; |
374 | 359 | } |
375 | 360 | |
376 | 361 | |
377 | 362 | |
... | ... | @@ -387,23 +372,23 @@ |
387 | 372 | }; |
388 | 373 | struct fps __user *fps = (struct fps __user *) addr; |
389 | 374 | |
390 | - ret = -EFAULT; | |
391 | - if (!access_ok(VERIFY_WRITE, fps, sizeof(struct fps))) | |
392 | - break; | |
375 | + ret = copy_regset_to_user(child, view, REGSET_FP, | |
376 | + 0 * sizeof(u32), | |
377 | + 32 * sizeof(u32), | |
378 | + &fps->regs[0]); | |
379 | + if (!ret) | |
380 | + ret = copy_regset_to_user(child, view, REGSET_FP, | |
381 | + 33 * sizeof(u32), | |
382 | + 1 * sizeof(u32), | |
383 | + &fps->fsr); | |
393 | 384 | |
394 | - for (i = 0; i < 32; i++) | |
395 | - __put_user(child->thread.float_regs[i], &fps->regs[i]); | |
396 | - __put_user(child->thread.fsr, (&fps->fsr)); | |
397 | - __put_user(child->thread.fpqdepth, (&fps->fpqd)); | |
398 | - __put_user(0, (&fps->flags)); | |
399 | - __put_user(0, (&fps->extra)); | |
400 | - for (i = 0; i < 16; i++) { | |
401 | - __put_user(child->thread.fpqueue[i].insn_addr, | |
402 | - (&fps->fpq[i].insnaddr)); | |
403 | - __put_user(child->thread.fpqueue[i].insn, | |
404 | - &fps->fpq[i].insn); | |
385 | + if (!ret) { | |
386 | + if (__put_user(0, &fps->fpqd) || | |
387 | + __put_user(0, &fps->flags) || | |
388 | + __put_user(0, &fps->extra) || | |
389 | + clear_user(fps->fpq, sizeof(fps->fpq))) | |
390 | + ret = -EFAULT; | |
405 | 391 | } |
406 | - ret = 0; | |
407 | 392 | break; |
408 | 393 | } |
409 | 394 | |
... | ... | @@ -421,21 +406,15 @@ |
421 | 406 | }; |
422 | 407 | struct fps __user *fps = (struct fps __user *) addr; |
423 | 408 | |
424 | - ret = -EFAULT; | |
425 | - if (!access_ok(VERIFY_READ, fps, sizeof(struct fps))) | |
426 | - break; | |
427 | - | |
428 | - copy_from_user(&child->thread.float_regs[0], &fps->regs[0], | |
429 | - (32 * sizeof(unsigned long))); | |
430 | - __get_user(child->thread.fsr, (&fps->fsr)); | |
431 | - __get_user(child->thread.fpqdepth, (&fps->fpqd)); | |
432 | - for (i = 0; i < 16; i++) { | |
433 | - __get_user(child->thread.fpqueue[i].insn_addr, | |
434 | - (&fps->fpq[i].insnaddr)); | |
435 | - __get_user(child->thread.fpqueue[i].insn, | |
436 | - &fps->fpq[i].insn); | |
437 | - } | |
438 | - ret = 0; | |
409 | + ret = copy_regset_from_user(child, view, REGSET_FP, | |
410 | + 0 * sizeof(u32), | |
411 | + 32 * sizeof(u32), | |
412 | + &fps->regs[0]); | |
413 | + if (!ret) | |
414 | + ret = copy_regset_from_user(child, view, REGSET_FP, | |
415 | + 33 * sizeof(u32), | |
416 | + 1 * sizeof(u32), | |
417 | + &fps->fsr); | |
439 | 418 | break; |
440 | 419 | } |
441 | 420 |