diff options
author | Thomas Meyer <thomas@m3y3r.de> | 2015-03-28 04:59:46 -0400 |
---|---|---|
committer | Richard Weinberger <richard@nod.at> | 2015-04-13 15:17:44 -0400 |
commit | 33bbc3065414722065a20cbdbeaf352173e72f39 (patch) | |
tree | f4cf1b3df0f7a23f80a9d14129ec8f8c1f14ad19 /arch | |
parent | 04a418495e0852263d77c4fb82adf470feaafef3 (diff) |
um: Move uml_postsetup in the init_thread stack
atomic_notifier_chain_register() and uml_postsetup() do call kernel code
that rely on the "current" kernel macro and a valid task_struct resp.
thread_info struct. Give those functions a valid stack by moving
uml_postsetup() in the init_thread stack. This moves enables a panic()
call in this early code to generate a valid stacktrace, instead of
crashing.
E.g. when an UML kernel is started with an initrd but too few physical
memory the panic() call get's actually processed.
Signed-off-by: Thomas Meyer <thomas@m3y3r.de>
Signed-off-by: Richard Weinberger <richard@nod.at>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/um/include/shared/as-layout.h | 1 | ||||
-rw-r--r-- | arch/um/kernel/um_arch.c | 15 | ||||
-rw-r--r-- | arch/um/os-Linux/skas/process.c | 2 |
3 files changed, 12 insertions, 6 deletions
diff --git a/arch/um/include/shared/as-layout.h b/arch/um/include/shared/as-layout.h index 41c8c774ec10..ca1843e1df15 100644 --- a/arch/um/include/shared/as-layout.h +++ b/arch/um/include/shared/as-layout.h | |||
@@ -56,6 +56,7 @@ extern unsigned long brk_start; | |||
56 | extern unsigned long host_task_size; | 56 | extern unsigned long host_task_size; |
57 | 57 | ||
58 | extern int linux_main(int argc, char **argv); | 58 | extern int linux_main(int argc, char **argv); |
59 | extern void uml_finishsetup(void); | ||
59 | 60 | ||
60 | struct siginfo; | 61 | struct siginfo; |
61 | extern void (*sig_info[])(int, struct siginfo *si, struct uml_pt_regs *); | 62 | extern void (*sig_info[])(int, struct siginfo *si, struct uml_pt_regs *); |
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 926ecdceba86..07f798f4bcee 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c | |||
@@ -226,6 +226,16 @@ static struct notifier_block panic_exit_notifier = { | |||
226 | .priority = 0 | 226 | .priority = 0 |
227 | }; | 227 | }; |
228 | 228 | ||
229 | void uml_finishsetup(void) | ||
230 | { | ||
231 | atomic_notifier_chain_register(&panic_notifier_list, | ||
232 | &panic_exit_notifier); | ||
233 | |||
234 | uml_postsetup(); | ||
235 | |||
236 | new_thread_handler(); | ||
237 | } | ||
238 | |||
229 | /* Set during early boot */ | 239 | /* Set during early boot */ |
230 | unsigned long task_size; | 240 | unsigned long task_size; |
231 | EXPORT_SYMBOL(task_size); | 241 | EXPORT_SYMBOL(task_size); |
@@ -326,11 +336,6 @@ int __init linux_main(int argc, char **argv) | |||
326 | printf("Kernel virtual memory size shrunk to %lu bytes\n", | 336 | printf("Kernel virtual memory size shrunk to %lu bytes\n", |
327 | virtmem_size); | 337 | virtmem_size); |
328 | 338 | ||
329 | atomic_notifier_chain_register(&panic_notifier_list, | ||
330 | &panic_exit_notifier); | ||
331 | |||
332 | uml_postsetup(); | ||
333 | |||
334 | stack_protections((unsigned long) &init_thread_info); | 339 | stack_protections((unsigned long) &init_thread_info); |
335 | os_flush_stdout(); | 340 | os_flush_stdout(); |
336 | 341 | ||
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 50ebeae5cbb3..7a9777570a62 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c | |||
@@ -586,7 +586,7 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf) | |||
586 | n = setjmp(initial_jmpbuf); | 586 | n = setjmp(initial_jmpbuf); |
587 | switch (n) { | 587 | switch (n) { |
588 | case INIT_JMP_NEW_THREAD: | 588 | case INIT_JMP_NEW_THREAD: |
589 | (*switch_buf)[0].JB_IP = (unsigned long) new_thread_handler; | 589 | (*switch_buf)[0].JB_IP = (unsigned long) uml_finishsetup; |
590 | (*switch_buf)[0].JB_SP = (unsigned long) stack + | 590 | (*switch_buf)[0].JB_SP = (unsigned long) stack + |
591 | UM_THREAD_SIZE - sizeof(void *); | 591 | UM_THREAD_SIZE - sizeof(void *); |
592 | break; | 592 | break; |