aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/um/kernel/process.c35
-rw-r--r--include/asm-um/processor-generic.h2
2 files changed, 36 insertions, 1 deletions
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
index 0eae00b3e588..c7ea7f2a8945 100644
--- a/arch/um/kernel/process.c
+++ b/arch/um/kernel/process.c
@@ -459,3 +459,38 @@ unsigned long arch_align_stack(unsigned long sp)
459 return sp & ~0xf; 459 return sp & ~0xf;
460} 460}
461#endif 461#endif
462
463unsigned long get_wchan(struct task_struct *p)
464{
465 unsigned long stack_page, sp, ip;
466 bool seen_sched = 0;
467
468 if ((p == NULL) || (p == current) || (p->state == TASK_RUNNING))
469 return 0;
470
471 stack_page = (unsigned long) task_stack_page(p);
472 /* Bail if the process has no kernel stack for some reason */
473 if (stack_page == 0)
474 return 0;
475
476 sp = p->thread.switch_buf->JB_SP;
477 /*
478 * Bail if the stack pointer is below the bottom of the kernel
479 * stack for some reason
480 */
481 if (sp < stack_page)
482 return 0;
483
484 while (sp < stack_page + THREAD_SIZE) {
485 ip = *((unsigned long *) sp);
486 if (in_sched_functions(ip))
487 /* Ignore everything until we're above the scheduler */
488 seen_sched = 1;
489 else if (kernel_text_address(ip) && seen_sched)
490 return ip;
491
492 sp += sizeof(unsigned long);
493 }
494
495 return 0;
496}
diff --git a/include/asm-um/processor-generic.h b/include/asm-um/processor-generic.h
index 78c0599cc80c..057a76d41569 100644
--- a/include/asm-um/processor-generic.h
+++ b/include/asm-um/processor-generic.h
@@ -128,6 +128,6 @@ extern struct cpuinfo_um cpu_data[];
128 128
129 129
130#define KSTK_REG(tsk, reg) get_thread_reg(reg, &tsk->thread.switch_buf) 130#define KSTK_REG(tsk, reg) get_thread_reg(reg, &tsk->thread.switch_buf)
131#define get_wchan(p) (0) 131extern unsigned long get_wchan(struct task_struct *p);
132 132
133#endif 133#endif