diff --git a/repos/dde_linux/src/include/lx_emul/task.h b/repos/dde_linux/src/include/lx_emul/task.h index 8aec4517c8..6cc629e857 100644 --- a/repos/dde_linux/src/include/lx_emul/task.h +++ b/repos/dde_linux/src/include/lx_emul/task.h @@ -42,6 +42,8 @@ void lx_emul_task_schedule(int block); void lx_emul_task_name(struct task_struct * task, const char * name); +void *lx_emul_task_stack(struct task_struct const * task); + #ifdef __cplusplus } #endif diff --git a/repos/dde_linux/src/include/lx_kit/task.h b/repos/dde_linux/src/include/lx_kit/task.h index 263dac2993..c75a0eb506 100644 --- a/repos/dde_linux/src/include/lx_kit/task.h +++ b/repos/dde_linux/src/include/lx_kit/task.h @@ -73,6 +73,7 @@ class Lx_kit::Task : public Genode::List::Element Name name() const; void * lx_task() const; int pid() const; + void * stack() const; void block(); void unblock(); diff --git a/repos/dde_linux/src/lib/lx_emul/shadow/kernel/fork.c b/repos/dde_linux/src/lib/lx_emul/shadow/kernel/fork.c index 485260dd77..61f5d3a09d 100644 --- a/repos/dde_linux/src/lib/lx_emul/shadow/kernel/fork.c +++ b/repos/dde_linux/src/lib/lx_emul/shadow/kernel/fork.c @@ -77,13 +77,22 @@ pid_t kernel_thread(int (* fn)(void *),void * arg,unsigned long flags) .signal = signal, }; +#ifndef CONFIG_THREAD_INFO_IN_TASK + /* On arm, the 'thread_info' is hidden behind 'task->stack', we must + * therefore initialise the member before calling 'task_thread_info()'. */ task->stack = kmalloc(sizeof(struct thread_info), THREADINFO_GFP); +#endif #ifndef CONFIG_X86 task_thread_info(task)->preempt_count = 0; #endif lx_emul_task_create(task, "kthread", task->pid, fn, arg); + +#ifdef CONFIG_THREAD_INFO_IN_TASK + task->stack = lx_emul_task_stack(task); +#endif + return task->pid; err_task: diff --git a/repos/dde_linux/src/lib/lx_emul/task.cc b/repos/dde_linux/src/lib/lx_emul/task.cc index 800f3ae54d..350d121a27 100644 --- a/repos/dde_linux/src/lib/lx_emul/task.cc +++ b/repos/dde_linux/src/lib/lx_emul/task.cc @@ -87,3 +87,16 @@ extern "C" void lx_emul_task_name(struct task_struct * t, const char * name) { Lx_kit::env().scheduler.task((void*)t).name(name); } + + +extern "C" void * lx_emul_task_stack(struct task_struct const * t) +{ + void * ret = nullptr; + + Lx_kit::env().scheduler.for_each_task([&] (Lx_kit::Task const & task) { + if (t == task.lx_task()) + ret = task.stack(); + }); + + return ret; +} diff --git a/repos/dde_linux/src/lib/lx_kit/task.cc b/repos/dde_linux/src/lib/lx_kit/task.cc index 727cb8ac0b..1cf1102aa7 100644 --- a/repos/dde_linux/src/lib/lx_kit/task.cc +++ b/repos/dde_linux/src/lib/lx_kit/task.cc @@ -50,6 +50,9 @@ Task::Type Task::type() const { return _type; } void * Task::lx_task() const { return _lx_task; } +void * Task::stack() const { return _stack; } + + int Task::pid() const { return _pid; }