diff options
-rw-r--r-- | arch/blackfin/kernel/ptrace.c | 87 |
1 files changed, 37 insertions, 50 deletions
diff --git a/arch/blackfin/kernel/ptrace.c b/arch/blackfin/kernel/ptrace.c index b3f4ac792cf1..e8172eece047 100644 --- a/arch/blackfin/kernel/ptrace.c +++ b/arch/blackfin/kernel/ptrace.c | |||
@@ -175,6 +175,13 @@ static inline int is_user_addr_valid(struct task_struct *child, | |||
175 | return -EIO; | 175 | return -EIO; |
176 | } | 176 | } |
177 | 177 | ||
178 | void ptrace_enable(struct task_struct *child) | ||
179 | { | ||
180 | unsigned long tmp; | ||
181 | tmp = get_reg(child, PT_SYSCFG) | (TRACE_BITS); | ||
182 | put_reg(child, PT_SYSCFG, tmp); | ||
183 | } | ||
184 | |||
178 | /* | 185 | /* |
179 | * Called by kernel/ptrace.c when detaching.. | 186 | * Called by kernel/ptrace.c when detaching.. |
180 | * | 187 | * |
@@ -347,29 +354,22 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
347 | break; | 354 | break; |
348 | 355 | ||
349 | case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ | 356 | case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ |
350 | case PTRACE_CONT: | 357 | case PTRACE_CONT: /* restart after signal. */ |
351 | { /* restart after signal. */ | 358 | pr_debug("ptrace: syscall/cont\n"); |
352 | long tmp; | ||
353 | |||
354 | pr_debug("ptrace: syscall/cont\n"); | ||
355 | 359 | ||
356 | ret = -EIO; | 360 | ret = -EIO; |
357 | if (!valid_signal(data)) | 361 | if (!valid_signal(data)) |
358 | break; | ||
359 | if (request == PTRACE_SYSCALL) | ||
360 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | ||
361 | else | ||
362 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | ||
363 | |||
364 | child->exit_code = data; | ||
365 | /* make sure the single step bit is not set. */ | ||
366 | tmp = get_reg(child, PT_SYSCFG) & ~(TRACE_BITS); | ||
367 | put_reg(child, PT_SYSCFG, tmp); | ||
368 | pr_debug("ptrace: before wake_up_process\n"); | ||
369 | wake_up_process(child); | ||
370 | ret = 0; | ||
371 | break; | 362 | break; |
372 | } | 363 | if (request == PTRACE_SYSCALL) |
364 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | ||
365 | else | ||
366 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | ||
367 | child->exit_code = data; | ||
368 | ptrace_disable(child); | ||
369 | pr_debug("ptrace: before wake_up_process\n"); | ||
370 | wake_up_process(child); | ||
371 | ret = 0; | ||
372 | break; | ||
373 | 373 | ||
374 | /* | 374 | /* |
375 | * make the child exit. Best I can do is send it a sigkill. | 375 | * make the child exit. Best I can do is send it a sigkill. |
@@ -377,38 +377,25 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
377 | * exit. | 377 | * exit. |
378 | */ | 378 | */ |
379 | case PTRACE_KILL: | 379 | case PTRACE_KILL: |
380 | { | 380 | ret = 0; |
381 | long tmp; | 381 | if (child->exit_state == EXIT_ZOMBIE) /* already dead */ |
382 | ret = 0; | ||
383 | if (child->exit_state == EXIT_ZOMBIE) /* already dead */ | ||
384 | break; | ||
385 | child->exit_code = SIGKILL; | ||
386 | /* make sure the single step bit is not set. */ | ||
387 | tmp = get_reg(child, PT_SYSCFG) & ~(TRACE_BITS); | ||
388 | put_reg(child, PT_SYSCFG, tmp); | ||
389 | wake_up_process(child); | ||
390 | break; | 382 | break; |
391 | } | 383 | child->exit_code = SIGKILL; |
392 | 384 | ptrace_disable(child); | |
393 | case PTRACE_SINGLESTEP: | 385 | wake_up_process(child); |
394 | { /* set the trap flag. */ | 386 | break; |
395 | long tmp; | ||
396 | |||
397 | pr_debug("ptrace: single step\n"); | ||
398 | ret = -EIO; | ||
399 | if (!valid_signal(data)) | ||
400 | break; | ||
401 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | ||
402 | |||
403 | tmp = get_reg(child, PT_SYSCFG) | (TRACE_BITS); | ||
404 | put_reg(child, PT_SYSCFG, tmp); | ||
405 | 387 | ||
406 | child->exit_code = data; | 388 | case PTRACE_SINGLESTEP: /* set the trap flag. */ |
407 | /* give it a chance to run. */ | 389 | pr_debug("ptrace: single step\n"); |
408 | wake_up_process(child); | 390 | ret = -EIO; |
409 | ret = 0; | 391 | if (!valid_signal(data)) |
410 | break; | 392 | break; |
411 | } | 393 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
394 | ptrace_enable(child); | ||
395 | child->exit_code = data; | ||
396 | wake_up_process(child); | ||
397 | ret = 0; | ||
398 | break; | ||
412 | 399 | ||
413 | case PTRACE_GETREGS: | 400 | case PTRACE_GETREGS: |
414 | /* Get all gp regs from the child. */ | 401 | /* Get all gp regs from the child. */ |