aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/kernel/ptrace.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/blackfin/kernel/ptrace.c')
-rw-r--r--arch/blackfin/kernel/ptrace.c87
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
178void 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. */