diff options
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/sparc/kernel/ptrace.c | 115 |
1 files changed, 47 insertions, 68 deletions
diff --git a/arch/sparc/kernel/ptrace.c b/arch/sparc/kernel/ptrace.c index 1c0d5363f720..5b54f11f4e59 100644 --- a/arch/sparc/kernel/ptrace.c +++ b/arch/sparc/kernel/ptrace.c | |||
| @@ -322,54 +322,39 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *task) | |||
| 322 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) | 322 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) |
| 323 | { | 323 | { |
| 324 | unsigned long addr2 = current->thread.kregs->u_regs[UREG_I4]; | 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; | ||
| 327 | |||
| 328 | view = task_user_regset_view(child); | ||
| 326 | 329 | ||
| 327 | switch(request) { | 330 | switch(request) { |
| 328 | case PTRACE_GETREGS: { | 331 | case PTRACE_GETREGS: { |
| 329 | struct pt_regs __user *pregs = (struct pt_regs __user *) addr; | 332 | struct pt_regs __user *pregs = (struct pt_regs __user *) addr; |
| 330 | struct pt_regs *cregs = child->thread.kregs; | ||
| 331 | |||
| 332 | ret = -EFAULT; | ||
| 333 | if (!access_ok(VERIFY_WRITE, pregs, sizeof(struct pt_regs))) | ||
| 334 | break; | ||
| 335 | 333 | ||
| 336 | __put_user(cregs->psr, (&pregs->psr)); | 334 | ret = copy_regset_to_user(child, view, REGSET_GENERAL, |
| 337 | __put_user(cregs->pc, (&pregs->pc)); | 335 | 32 * sizeof(u32), |
| 338 | __put_user(cregs->npc, (&pregs->npc)); | 336 | 4 * sizeof(u32), |
| 339 | __put_user(cregs->y, (&pregs->y)); | 337 | &pregs->psr); |
| 340 | for (i = 1; i < 16; i++) | 338 | if (!ret) |
| 341 | __put_user(cregs->u_regs[i], &pregs->u_regs[i - 1]); | 339 | copy_regset_to_user(child, view, REGSET_GENERAL, |
| 342 | ret = 0; | 340 | 1 * sizeof(u32), |
| 341 | 15 * sizeof(u32), | ||
| 342 | &pregs->u_regs[0]); | ||
| 343 | break; | 343 | break; |
| 344 | } | 344 | } |
| 345 | 345 | ||
| 346 | case PTRACE_SETREGS: { | 346 | case PTRACE_SETREGS: { |
| 347 | struct pt_regs __user *pregs = (struct pt_regs __user *) addr; | 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 | |||
| 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 | 348 | ||
| 358 | __get_user(psr, (&pregs->psr)); | 349 | ret = copy_regset_from_user(child, view, REGSET_GENERAL, |
| 359 | __get_user(pc, (&pregs->pc)); | 350 | 32 * sizeof(u32), |
| 360 | __get_user(npc, (&pregs->npc)); | 351 | 4 * sizeof(u32), |
| 361 | __get_user(y, (&pregs->y)); | 352 | &pregs->psr); |
| 362 | psr &= PSR_ICC; | 353 | if (!ret) |
| 363 | cregs->psr &= ~PSR_ICC; | 354 | copy_regset_from_user(child, view, REGSET_GENERAL, |
| 364 | cregs->psr |= psr; | 355 | 1 * sizeof(u32), |
| 365 | if (!((pc | npc) & 3)) { | 356 | 15 * sizeof(u32), |
| 366 | cregs->pc = pc; | 357 | &pregs->u_regs[0]); |
| 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; | ||
| 373 | break; | 358 | break; |
| 374 | } | 359 | } |
| 375 | 360 | ||
| @@ -387,23 +372,23 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
| 387 | }; | 372 | }; |
| 388 | struct fps __user *fps = (struct fps __user *) addr; | 373 | struct fps __user *fps = (struct fps __user *) addr; |
| 389 | 374 | ||
| 390 | ret = -EFAULT; | 375 | ret = copy_regset_to_user(child, view, REGSET_FP, |
| 391 | if (!access_ok(VERIFY_WRITE, fps, sizeof(struct fps))) | 376 | 0 * sizeof(u32), |
| 392 | break; | 377 | 32 * sizeof(u32), |
| 393 | 378 | &fps->regs[0]); | |
| 394 | for (i = 0; i < 32; i++) | 379 | if (!ret) |
| 395 | __put_user(child->thread.float_regs[i], &fps->regs[i]); | 380 | ret = copy_regset_to_user(child, view, REGSET_FP, |
| 396 | __put_user(child->thread.fsr, (&fps->fsr)); | 381 | 33 * sizeof(u32), |
| 397 | __put_user(child->thread.fpqdepth, (&fps->fpqd)); | 382 | 1 * sizeof(u32), |
| 398 | __put_user(0, (&fps->flags)); | 383 | &fps->fsr); |
| 399 | __put_user(0, (&fps->extra)); | 384 | |
| 400 | for (i = 0; i < 16; i++) { | 385 | if (!ret) { |
| 401 | __put_user(child->thread.fpqueue[i].insn_addr, | 386 | if (__put_user(0, &fps->fpqd) || |
| 402 | (&fps->fpq[i].insnaddr)); | 387 | __put_user(0, &fps->flags) || |
| 403 | __put_user(child->thread.fpqueue[i].insn, | 388 | __put_user(0, &fps->extra) || |
| 404 | &fps->fpq[i].insn); | 389 | clear_user(fps->fpq, sizeof(fps->fpq))) |
| 390 | ret = -EFAULT; | ||
| 405 | } | 391 | } |
| 406 | ret = 0; | ||
| 407 | break; | 392 | break; |
| 408 | } | 393 | } |
| 409 | 394 | ||
| @@ -421,21 +406,15 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
| 421 | }; | 406 | }; |
| 422 | struct fps __user *fps = (struct fps __user *) addr; | 407 | struct fps __user *fps = (struct fps __user *) addr; |
| 423 | 408 | ||
| 424 | ret = -EFAULT; | 409 | ret = copy_regset_from_user(child, view, REGSET_FP, |
| 425 | if (!access_ok(VERIFY_READ, fps, sizeof(struct fps))) | 410 | 0 * sizeof(u32), |
| 426 | break; | 411 | 32 * sizeof(u32), |
| 427 | 412 | &fps->regs[0]); | |
| 428 | copy_from_user(&child->thread.float_regs[0], &fps->regs[0], | 413 | if (!ret) |
| 429 | (32 * sizeof(unsigned long))); | 414 | ret = copy_regset_from_user(child, view, REGSET_FP, |
| 430 | __get_user(child->thread.fsr, (&fps->fsr)); | 415 | 33 * sizeof(u32), |
| 431 | __get_user(child->thread.fpqdepth, (&fps->fpqd)); | 416 | 1 * sizeof(u32), |
| 432 | for (i = 0; i < 16; i++) { | 417 | &fps->fsr); |
| 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; | ||
| 439 | break; | 418 | break; |
| 440 | } | 419 | } |
| 441 | 420 | ||
