summaryrefslogtreecommitdiff
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)
return sp & ~0xf;
}
#endif
+
+unsigned long get_wchan(struct task_struct *p)
+{
+ unsigned long stack_page, sp, ip;
+ bool seen_sched = 0;
+
+ if ((p == NULL) || (p == current) || (p->state == TASK_RUNNING))
+ return 0;
+
+ stack_page = (unsigned long) task_stack_page(p);
+ /* Bail if the process has no kernel stack for some reason */
+ if (stack_page == 0)
+ return 0;
+
+ sp = p->thread.switch_buf->JB_SP;
+ /*
+ * Bail if the stack pointer is below the bottom of the kernel
+ * stack for some reason
+ */
+ if (sp < stack_page)
+ return 0;
+
+ while (sp < stack_page + THREAD_SIZE) {
+ ip = *((unsigned long *) sp);
+ if (in_sched_functions(ip))
+ /* Ignore everything until we're above the scheduler */
+ seen_sched = 1;
+ else if (kernel_text_address(ip) && seen_sched)
+ return ip;
+
+ sp += sizeof(unsigned long);
+ }
+
+ return 0;
+}
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[];
#define KSTK_REG(tsk, reg) get_thread_reg(reg, &tsk->thread.switch_buf)
-#define get_wchan(p) (0)
+extern unsigned long get_wchan(struct task_struct *p);
#endif