um: Move uml_postsetup in the init_thread stack
authorThomas Meyer <thomas@m3y3r.de>
Sat, 28 Mar 2015 08:59:46 +0000 (09:59 +0100)
committerRichard Weinberger <richard@nod.at>
Mon, 13 Apr 2015 19:17:44 +0000 (21:17 +0200)
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>
arch/um/include/shared/as-layout.h
arch/um/kernel/um_arch.c
arch/um/os-Linux/skas/process.c

index 41c8c774ec1037ef6a64a34841729cd8c1c07f49..ca1843e1df157b9c40c53cb5a58f50d1f9166c64 100644 (file)
@@ -56,6 +56,7 @@ extern unsigned long brk_start;
 extern unsigned long host_task_size;
 
 extern int linux_main(int argc, char **argv);
+extern void uml_finishsetup(void);
 
 struct siginfo;
 extern void (*sig_info[])(int, struct siginfo *si, struct uml_pt_regs *);
index 926ecdceba86f2697dfe2401b37828aeaea081f7..07f798f4bcee24bfd867e30f9d1d89d6069f5195 100644 (file)
@@ -226,6 +226,16 @@ static struct notifier_block panic_exit_notifier = {
        .priority               = 0
 };
 
+void uml_finishsetup(void)
+{
+       atomic_notifier_chain_register(&panic_notifier_list,
+                                      &panic_exit_notifier);
+
+       uml_postsetup();
+
+       new_thread_handler();
+}
+
 /* Set during early boot */
 unsigned long task_size;
 EXPORT_SYMBOL(task_size);
@@ -326,11 +336,6 @@ int __init linux_main(int argc, char **argv)
                printf("Kernel virtual memory size shrunk to %lu bytes\n",
                       virtmem_size);
 
-       atomic_notifier_chain_register(&panic_notifier_list,
-                                      &panic_exit_notifier);
-
-       uml_postsetup();
-
        stack_protections((unsigned long) &init_thread_info);
        os_flush_stdout();
 
index 50ebeae5cbb3e2ff3131b9be5fb281d61301399b..7a9777570a62c9e52f4c73aaee0e54e8c702bc6a 100644 (file)
@@ -586,7 +586,7 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf)
        n = setjmp(initial_jmpbuf);
        switch (n) {
        case INIT_JMP_NEW_THREAD:
-               (*switch_buf)[0].JB_IP = (unsigned long) new_thread_handler;
+               (*switch_buf)[0].JB_IP = (unsigned long) uml_finishsetup;
                (*switch_buf)[0].JB_SP = (unsigned long) stack +
                        UM_THREAD_SIZE - sizeof(void *);
                break;