diff --git a/arch/um/include/shared/as-layout.h b/arch/um/include/shared/as-layout.h index 02ef258e3395..7c4ccb6d9d37 100644 --- a/arch/um/include/shared/as-layout.h +++ b/arch/um/include/shared/as-layout.h @@ -29,6 +29,7 @@ #ifndef __ASSEMBLER__ +#include #include struct task_struct; @@ -46,7 +47,7 @@ extern unsigned long brk_start; extern unsigned long stub_start; -extern int linux_main(int argc, char **argv, char **envp); +extern void __noreturn linux_main(int argc, char **argv, char **envp); extern void uml_finishsetup(void); struct siginfo; diff --git a/arch/um/include/shared/kern_util.h b/arch/um/include/shared/kern_util.h index 9812efd14ec0..7950d58a4ae8 100644 --- a/arch/um/include/shared/kern_util.h +++ b/arch/um/include/shared/kern_util.h @@ -6,6 +6,7 @@ #ifndef __KERN_UTIL_H__ #define __KERN_UTIL_H__ +#include #include #include @@ -37,7 +38,7 @@ extern void timer_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs extern void uml_pm_wake(void); -extern int start_uml(void); +extern void __noreturn start_uml(void); extern void uml_cleanup(void); extern void do_uml_exitcalls(void); diff --git a/arch/um/include/shared/longjmp.h b/arch/um/include/shared/longjmp.h index c53e43d980c8..b35ed756e3e4 100644 --- a/arch/um/include/shared/longjmp.h +++ b/arch/um/include/shared/longjmp.h @@ -2,11 +2,12 @@ #ifndef __UML_LONGJMP_H #define __UML_LONGJMP_H +#include #include #include extern int setjmp(jmp_buf); -extern void longjmp(jmp_buf, int); +extern void __noreturn longjmp(jmp_buf, int); #define UML_LONGJMP(buf, val) do { \ longjmp(*buf, val); \ diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h index b26e94292fc1..0067c5208c4c 100644 --- a/arch/um/include/shared/os.h +++ b/arch/um/include/shared/os.h @@ -15,6 +15,7 @@ #ifndef __UM_HOST__ #include #else +#include #include #endif @@ -196,6 +197,9 @@ extern int create_mem_file(unsigned long long len); /* tlb.c */ extern void report_enomem(void); +/* main.c */ +extern void __noreturn os_exit(bool reboot); + /* process.c */ pid_t os_reap_child(void); extern void os_alarm_process(int pid); @@ -295,7 +299,7 @@ extern int start_userspace(struct mm_id *mm_id); extern void userspace(struct uml_pt_regs *regs); extern void new_thread(void *stack, jmp_buf *buf, void (*handler)(void)); extern void switch_threads(jmp_buf *me, jmp_buf *you); -extern int start_idle_thread(void *stack, jmp_buf *switch_buf); +extern void __noreturn start_idle_thread(void *stack, jmp_buf *switch_buf); extern void initial_thread_cb_skas(void (*proc)(void *), void *arg); extern void halt_skas(void); diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c index dcdce50b4595..f60541df209f 100644 --- a/arch/um/kernel/skas/process.c +++ b/arch/um/kernel/skas/process.c @@ -27,7 +27,7 @@ static int __init start_kernel_proc(void *unused) char cpu_irqstacks[NR_CPUS][THREAD_SIZE] __aligned(THREAD_SIZE); -int __init start_uml(void) +void __init start_uml(void) { stack_protections((unsigned long) &cpu_irqstacks[0]); set_sigstack(cpu_irqstacks[0], THREAD_SIZE); @@ -36,8 +36,8 @@ int __init start_uml(void) init_task.thread.request.thread.proc = start_kernel_proc; init_task.thread.request.thread.arg = NULL; - return start_idle_thread(task_stack_page(&init_task), - &init_task.thread.switch_buf); + start_idle_thread(task_stack_page(&init_task), + &init_task.thread.switch_buf); } static DEFINE_SPINLOCK(initial_jmpbuf_spinlock); diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 13e84e605630..3dbe3acc4833 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -308,7 +308,7 @@ static unsigned long __init get_top_address(char **envp) return PAGE_ALIGN(top_addr + 1); } -int __init linux_main(int argc, char **argv, char **envp) +void __init linux_main(int argc, char **argv, char **envp) { unsigned long avail, diff; unsigned long virtmem_size, max_physmem; @@ -401,7 +401,7 @@ int __init linux_main(int argc, char **argv, char **envp) os_flush_stdout(); - return start_uml(); + start_uml(); } int __init __weak read_initrd(void) diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c index 7e114862a723..ea41188ef2d0 100644 --- a/arch/um/os-Linux/main.c +++ b/arch/um/os-Linux/main.c @@ -100,10 +100,11 @@ static void __init setup_env_path(void) } } +static char **new_argv; + int __init main(int argc, char **argv, char **envp) { - char **new_argv; - int ret, i, err; + int ret, i; /* Disable randomization and re-exec if it was changed successfully */ ret = personality(PER_LINUX | ADDR_NO_RANDOMIZE); @@ -150,7 +151,12 @@ int __init main(int argc, char **argv, char **envp) scan_elf_aux(envp); change_sig(SIGPIPE, 0); - ret = linux_main(argc, argv, envp); + linux_main(argc, argv, envp); +} + +void os_exit(bool reboot) +{ + int err; /* * Disable SIGPROF - I have no idea why libc doesn't do this or turn @@ -183,12 +189,11 @@ int __init main(int argc, char **argv, char **envp) os_info("\n"); /* Reboot */ - if (ret) { + if (reboot) { execvp(new_argv[0], new_argv); perror("Failed to exec kernel"); - ret = 1; } - return uml_exitcode; + exit(uml_exitcode); } extern void *__real_malloc(int); diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index d6c22f8aa06d..bca05a5a7a83 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -816,7 +816,7 @@ static __thread void (*cb_proc)(void *arg); static __thread void *cb_arg; static __thread jmp_buf *cb_back; -int start_idle_thread(void *stack, jmp_buf *switch_buf) +void start_idle_thread(void *stack, jmp_buf *switch_buf) { int n; @@ -843,21 +843,16 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf) break; case INIT_JMP_HALT: kmalloc_ok = 0; - return 0; + os_exit(false); case INIT_JMP_REBOOT: kmalloc_ok = 0; - return 1; + os_exit(true); default: printk(UM_KERN_ERR "Bad sigsetjmp return in %s - %d\n", __func__, n); fatal_sigsegv(); } longjmp(*switch_buf, 1); - - /* unreachable */ - printk(UM_KERN_ERR "impossible long jump!"); - fatal_sigsegv(); - return 0; } void initial_thread_cb_skas(void (*proc)(void *), void *arg)