Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Thomas Meyer and committed by
Richard Weinberger
33bbc306 04a41849

+12 -6
+1
arch/um/include/shared/as-layout.h
··· 56 56 extern unsigned long host_task_size; 57 57 58 58 extern int linux_main(int argc, char **argv); 59 + extern void uml_finishsetup(void); 59 60 60 61 struct siginfo; 61 62 extern void (*sig_info[])(int, struct siginfo *si, struct uml_pt_regs *);
+10 -5
arch/um/kernel/um_arch.c
··· 226 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 239 /* Set during early boot */ 230 240 unsigned long task_size; 231 241 EXPORT_SYMBOL(task_size); ··· 335 325 if (virtmem_size < physmem_size) 336 326 printf("Kernel virtual memory size shrunk to %lu bytes\n", 337 327 virtmem_size); 338 - 339 - atomic_notifier_chain_register(&panic_notifier_list, 340 - &panic_exit_notifier); 341 - 342 - uml_postsetup(); 343 328 344 329 stack_protections((unsigned long) &init_thread_info); 345 330 os_flush_stdout();
+1 -1
arch/um/os-Linux/skas/process.c
··· 586 586 n = setjmp(initial_jmpbuf); 587 587 switch (n) { 588 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 590 (*switch_buf)[0].JB_SP = (unsigned long) stack + 591 591 UM_THREAD_SIZE - sizeof(void *); 592 592 break;