aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-12 21:05:52 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-12 21:05:52 -0400
commit4e21fc138bfd7fe625ff5dc81541399aaf9d429b (patch)
tree43bedf14d2eee7711b8241dcfd6bd7b8737d9bd5
parent8418263e3547ed3816475e4c55a77004f0426ee6 (diff)
parent5522be6a4624a5f505555569e4d9cee946630686 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal
Pull third pile of kernel_execve() patches from Al Viro: "The last bits of infrastructure for kernel_thread() et.al., with alpha/arm/x86 use of those. Plus sanitizing the asm glue and do_notify_resume() on alpha, fixing the "disabled irq while running task_work stuff" breakage there. At that point the rest of kernel_thread/kernel_execve/sys_execve work can be done independently for different architectures. The only pending bits that do depend on having all architectures converted are restrictred to fs/* and kernel/* - that'll obviously have to wait for the next cycle. I thought we'd have to wait for all of them done before we start eliminating the longjump-style insanity in kernel_execve(), but it turned out there's a very simple way to do that without flagday-style changes." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal: alpha: switch to saner kernel_execve() semantics arm: switch to saner kernel_execve() semantics x86, um: convert to saner kernel_execve() semantics infrastructure for saner ret_from_kernel_thread semantics make sure that kernel_thread() callbacks call do_exit() themselves make sure that we always have a return path from kernel_execve() ppc: eeh_event should just use kthread_run() don't bother with kernel_thread/kernel_execve for launching linuxrc alpha: get rid of switch_stack argument of do_work_pending() alpha: don't bother passing switch_stack separately from regs alpha: take SIGPENDING/NOTIFY_RESUME loop into signal.c alpha: simplify TIF_NEED_RESCHED handling
-rw-r--r--arch/Kconfig3
-rw-r--r--arch/alpha/Kconfig1
-rw-r--r--arch/alpha/include/asm/unistd.h1
-rw-r--r--arch/alpha/kernel/entry.S87
-rw-r--r--arch/alpha/kernel/signal.c48
-rw-r--r--arch/arm/Kconfig1
-rw-r--r--arch/arm/include/asm/unistd.h1
-rw-r--r--arch/arm/kernel/entry-common.S29
-rw-r--r--arch/arm/kernel/process.c5
-rw-r--r--arch/powerpc/platforms/pseries/eeh_event.c5
-rw-r--r--arch/um/include/asm/processor-generic.h2
-rw-r--r--arch/um/include/shared/os.h1
-rw-r--r--arch/um/kernel/exec.c5
-rw-r--r--arch/um/kernel/process.c10
-rw-r--r--arch/um/os-Linux/process.c13
-rw-r--r--arch/x86/Kconfig1
-rw-r--r--arch/x86/include/asm/unistd.h1
-rw-r--r--arch/x86/kernel/entry_32.S31
-rw-r--r--arch/x86/kernel/entry_64.S24
-rw-r--r--arch/x86/um/Kconfig1
-rw-r--r--include/linux/syscalls.h8
-rw-r--r--init/do_mounts_initrd.c41
-rw-r--r--init/main.c33
-rw-r--r--kernel/kmod.c7
-rw-r--r--kernel/kthread.c1
25 files changed, 137 insertions, 223 deletions
diff --git a/arch/Kconfig b/arch/Kconfig
index 26a28419cafc..a79a1ad8bb96 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -274,6 +274,9 @@ config ARCH_WANT_OLD_COMPAT_IPC
274config GENERIC_KERNEL_THREAD 274config GENERIC_KERNEL_THREAD
275 bool 275 bool
276 276
277config GENERIC_KERNEL_EXECVE
278 bool
279
277config HAVE_ARCH_SECCOMP_FILTER 280config HAVE_ARCH_SECCOMP_FILTER
278 bool 281 bool
279 help 282 help
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index 7da91246e279..7a08cfb80ee8 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -21,6 +21,7 @@ config ALPHA
21 select GENERIC_STRNCPY_FROM_USER 21 select GENERIC_STRNCPY_FROM_USER
22 select GENERIC_STRNLEN_USER 22 select GENERIC_STRNLEN_USER
23 select GENERIC_KERNEL_THREAD 23 select GENERIC_KERNEL_THREAD
24 select GENERIC_KERNEL_EXECVE
24 help 25 help
25 The Alpha is a 64-bit general-purpose processor designed and 26 The Alpha is a 64-bit general-purpose processor designed and
26 marketed by the Digital Equipment Corporation of blessed memory, 27 marketed by the Digital Equipment Corporation of blessed memory,
diff --git a/arch/alpha/include/asm/unistd.h b/arch/alpha/include/asm/unistd.h
index 3cb6c1188984..7826e227e4d0 100644
--- a/arch/alpha/include/asm/unistd.h
+++ b/arch/alpha/include/asm/unistd.h
@@ -482,7 +482,6 @@
482#define __ARCH_WANT_SYS_SIGPENDING 482#define __ARCH_WANT_SYS_SIGPENDING
483#define __ARCH_WANT_SYS_RT_SIGSUSPEND 483#define __ARCH_WANT_SYS_RT_SIGSUSPEND
484#define __ARCH_WANT_SYS_EXECVE 484#define __ARCH_WANT_SYS_EXECVE
485#define __ARCH_WANT_KERNEL_EXECVE
486 485
487/* "Conditional" syscalls. What we want is 486/* "Conditional" syscalls. What we want is
488 487
diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S
index 2a359c9ee3cd..a7607832dd4f 100644
--- a/arch/alpha/kernel/entry.S
+++ b/arch/alpha/kernel/entry.S
@@ -311,7 +311,7 @@ entSys:
311 311
312 .align 4 312 .align 4
313ret_from_sys_call: 313ret_from_sys_call:
314 cmovne $26, 0, $19 /* $19 = 0 => non-restartable */ 314 cmovne $26, 0, $18 /* $18 = 0 => non-restartable */
315 ldq $0, SP_OFF($sp) 315 ldq $0, SP_OFF($sp)
316 and $0, 8, $0 316 and $0, 8, $0
317 beq $0, ret_to_kernel 317 beq $0, ret_to_kernel
@@ -320,8 +320,8 @@ ret_to_user:
320 sampling and the rti. */ 320 sampling and the rti. */
321 lda $16, 7 321 lda $16, 7
322 call_pal PAL_swpipl 322 call_pal PAL_swpipl
323 ldl $5, TI_FLAGS($8) 323 ldl $17, TI_FLAGS($8)
324 and $5, _TIF_WORK_MASK, $2 324 and $17, _TIF_WORK_MASK, $2
325 bne $2, work_pending 325 bne $2, work_pending
326restore_all: 326restore_all:
327 RESTORE_ALL 327 RESTORE_ALL
@@ -341,10 +341,10 @@ $syscall_error:
341 * frame to indicate that a negative return value wasn't an 341 * frame to indicate that a negative return value wasn't an
342 * error number.. 342 * error number..
343 */ 343 */
344 ldq $19, 0($sp) /* old syscall nr (zero if success) */ 344 ldq $18, 0($sp) /* old syscall nr (zero if success) */
345 beq $19, $ret_success 345 beq $18, $ret_success
346 346
347 ldq $20, 72($sp) /* .. and this a3 */ 347 ldq $19, 72($sp) /* .. and this a3 */
348 subq $31, $0, $0 /* with error in v0 */ 348 subq $31, $0, $0 /* with error in v0 */
349 addq $31, 1, $1 /* set a3 for errno return */ 349 addq $31, 1, $1 /* set a3 for errno return */
350 stq $0, 0($sp) 350 stq $0, 0($sp)
@@ -362,51 +362,35 @@ $ret_success:
362 * Do all cleanup when returning from all interrupts and system calls. 362 * Do all cleanup when returning from all interrupts and system calls.
363 * 363 *
364 * Arguments: 364 * Arguments:
365 * $5: TI_FLAGS.
366 * $8: current. 365 * $8: current.
367 * $19: The old syscall number, or zero if this is not a return 366 * $17: TI_FLAGS.
367 * $18: The old syscall number, or zero if this is not a return
368 * from a syscall that errored and is possibly restartable. 368 * from a syscall that errored and is possibly restartable.
369 * $20: The old a3 value 369 * $19: The old a3 value
370 */ 370 */
371 371
372 .align 4 372 .align 4
373 .ent work_pending 373 .ent work_pending
374work_pending: 374work_pending:
375 and $5, _TIF_NEED_RESCHED, $2 375 and $17, _TIF_NOTIFY_RESUME | _TIF_SIGPENDING, $2
376 beq $2, $work_notifysig 376 bne $2, $work_notifysig
377 377
378$work_resched: 378$work_resched:
379 subq $sp, 16, $sp 379 /*
380 stq $19, 0($sp) /* save syscall nr */ 380 * We can get here only if we returned from syscall without SIGPENDING
381 stq $20, 8($sp) /* and error indication (a3) */ 381 * or got through work_notifysig already. Either case means no syscall
382 * restarts for us, so let $18 and $19 burn.
383 */
382 jsr $26, schedule 384 jsr $26, schedule
383 ldq $19, 0($sp) 385 mov 0, $18
384 ldq $20, 8($sp) 386 br ret_to_user
385 addq $sp, 16, $sp
386 /* Make sure need_resched and sigpending don't change between
387 sampling and the rti. */
388 lda $16, 7
389 call_pal PAL_swpipl
390 ldl $5, TI_FLAGS($8)
391 and $5, _TIF_WORK_MASK, $2
392 beq $2, restore_all
393 and $5, _TIF_NEED_RESCHED, $2
394 bne $2, $work_resched
395 387
396$work_notifysig: 388$work_notifysig:
397 mov $sp, $16 389 mov $sp, $16
398 bsr $1, do_switch_stack 390 bsr $1, do_switch_stack
399 mov $sp, $17 391 jsr $26, do_work_pending
400 mov $5, $18
401 mov $19, $9 /* save old syscall number */
402 mov $20, $10 /* save old a3 */
403 and $5, _TIF_SIGPENDING, $2
404 cmovne $2, 0, $9 /* we don't want double syscall restarts */
405 jsr $26, do_notify_resume
406 mov $9, $19
407 mov $10, $20
408 bsr $1, undo_switch_stack 392 bsr $1, undo_switch_stack
409 br ret_to_user 393 br restore_all
410.end work_pending 394.end work_pending
411 395
412/* 396/*
@@ -454,9 +438,9 @@ $strace_success:
454 438
455 .align 3 439 .align 3
456$strace_error: 440$strace_error:
457 ldq $19, 0($sp) /* old syscall nr (zero if success) */ 441 ldq $18, 0($sp) /* old syscall nr (zero if success) */
458 beq $19, $strace_success 442 beq $18, $strace_success
459 ldq $20, 72($sp) /* .. and this a3 */ 443 ldq $19, 72($sp) /* .. and this a3 */
460 444
461 subq $31, $0, $0 /* with error in v0 */ 445 subq $31, $0, $0 /* with error in v0 */
462 addq $31, 1, $1 /* set a3 for errno return */ 446 addq $31, 1, $1 /* set a3 for errno return */
@@ -464,11 +448,11 @@ $strace_error:
464 stq $1, 72($sp) /* a3 for return */ 448 stq $1, 72($sp) /* a3 for return */
465 449
466 bsr $1, do_switch_stack 450 bsr $1, do_switch_stack
467 mov $19, $9 /* save old syscall number */ 451 mov $18, $9 /* save old syscall number */
468 mov $20, $10 /* save old a3 */ 452 mov $19, $10 /* save old a3 */
469 jsr $26, syscall_trace_leave 453 jsr $26, syscall_trace_leave
470 mov $9, $19 454 mov $9, $18
471 mov $10, $20 455 mov $10, $19
472 bsr $1, undo_switch_stack 456 bsr $1, undo_switch_stack
473 457
474 mov $31, $26 /* tell "ret_from_sys_call" we can restart */ 458 mov $31, $26 /* tell "ret_from_sys_call" we can restart */
@@ -619,24 +603,9 @@ ret_from_kernel_thread:
619 mov $9, $27 603 mov $9, $27
620 mov $10, $16 604 mov $10, $16
621 jsr $26, ($9) 605 jsr $26, ($9)
622 ldgp $gp, 0($26)
623 mov $0, $16
624 mov $31, $26
625 jmp $31, sys_exit
626.end ret_from_kernel_thread
627
628 .globl ret_from_kernel_execve
629 .align 4
630 .ent ret_from_kernel_execve
631ret_from_kernel_execve:
632 mov $16, $sp
633 /* Avoid the HAE being gratuitously wrong, to avoid restoring it. */
634 ldq $2, alpha_mv+HAE_CACHE
635 stq $2, 152($sp) /* HAE */
636 mov $31, $19 /* to disable syscall restarts */ 606 mov $31, $19 /* to disable syscall restarts */
637 br $31, ret_to_user 607 br $31, ret_to_user
638 608.end ret_from_kernel_thread
639.end ret_from_kernel_execve
640 609
641 610
642/* 611/*
diff --git a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c
index a8c97d42ec8e..32575f85507d 100644
--- a/arch/alpha/kernel/signal.c
+++ b/arch/alpha/kernel/signal.c
@@ -298,8 +298,9 @@ get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
298 298
299static long 299static long
300setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, 300setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
301 struct switch_stack *sw, unsigned long mask, unsigned long sp) 301 unsigned long mask, unsigned long sp)
302{ 302{
303 struct switch_stack *sw = (struct switch_stack *)regs - 1;
303 long i, err = 0; 304 long i, err = 0;
304 305
305 err |= __put_user(on_sig_stack((unsigned long)sc), &sc->sc_onstack); 306 err |= __put_user(on_sig_stack((unsigned long)sc), &sc->sc_onstack);
@@ -354,7 +355,7 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
354 355
355static int 356static int
356setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, 357setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
357 struct pt_regs *regs, struct switch_stack * sw) 358 struct pt_regs *regs)
358{ 359{
359 unsigned long oldsp, r26, err = 0; 360 unsigned long oldsp, r26, err = 0;
360 struct sigframe __user *frame; 361 struct sigframe __user *frame;
@@ -364,7 +365,7 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
364 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 365 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
365 return -EFAULT; 366 return -EFAULT;
366 367
367 err |= setup_sigcontext(&frame->sc, regs, sw, set->sig[0], oldsp); 368 err |= setup_sigcontext(&frame->sc, regs, set->sig[0], oldsp);
368 if (err) 369 if (err)
369 return -EFAULT; 370 return -EFAULT;
370 371
@@ -401,7 +402,7 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
401 402
402static int 403static int
403setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 404setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
404 sigset_t *set, struct pt_regs *regs, struct switch_stack * sw) 405 sigset_t *set, struct pt_regs *regs)
405{ 406{
406 unsigned long oldsp, r26, err = 0; 407 unsigned long oldsp, r26, err = 0;
407 struct rt_sigframe __user *frame; 408 struct rt_sigframe __user *frame;
@@ -420,7 +421,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
420 err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp); 421 err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
421 err |= __put_user(sas_ss_flags(oldsp), &frame->uc.uc_stack.ss_flags); 422 err |= __put_user(sas_ss_flags(oldsp), &frame->uc.uc_stack.ss_flags);
422 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); 423 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
423 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, sw, 424 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs,
424 set->sig[0], oldsp); 425 set->sig[0], oldsp);
425 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); 426 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
426 if (err) 427 if (err)
@@ -464,15 +465,15 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
464 */ 465 */
465static inline void 466static inline void
466handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, 467handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
467 struct pt_regs * regs, struct switch_stack *sw) 468 struct pt_regs * regs)
468{ 469{
469 sigset_t *oldset = sigmask_to_save(); 470 sigset_t *oldset = sigmask_to_save();
470 int ret; 471 int ret;
471 472
472 if (ka->sa.sa_flags & SA_SIGINFO) 473 if (ka->sa.sa_flags & SA_SIGINFO)
473 ret = setup_rt_frame(sig, ka, info, oldset, regs, sw); 474 ret = setup_rt_frame(sig, ka, info, oldset, regs);
474 else 475 else
475 ret = setup_frame(sig, ka, oldset, regs, sw); 476 ret = setup_frame(sig, ka, oldset, regs);
476 477
477 if (ret) { 478 if (ret) {
478 force_sigsegv(sig, current); 479 force_sigsegv(sig, current);
@@ -519,8 +520,7 @@ syscall_restart(unsigned long r0, unsigned long r19,
519 * all (if we get here from anything but a syscall return, it will be 0) 520 * all (if we get here from anything but a syscall return, it will be 0)
520 */ 521 */
521static void 522static void
522do_signal(struct pt_regs * regs, struct switch_stack * sw, 523do_signal(struct pt_regs *regs, unsigned long r0, unsigned long r19)
523 unsigned long r0, unsigned long r19)
524{ 524{
525 siginfo_t info; 525 siginfo_t info;
526 int signr; 526 int signr;
@@ -537,7 +537,7 @@ do_signal(struct pt_regs * regs, struct switch_stack * sw,
537 /* Whee! Actually deliver the signal. */ 537 /* Whee! Actually deliver the signal. */
538 if (r0) 538 if (r0)
539 syscall_restart(r0, r19, regs, &ka); 539 syscall_restart(r0, r19, regs, &ka);
540 handle_signal(signr, &ka, &info, regs, sw); 540 handle_signal(signr, &ka, &info, regs);
541 if (single_stepping) 541 if (single_stepping)
542 ptrace_set_bpt(current); /* re-set bpt */ 542 ptrace_set_bpt(current); /* re-set bpt */
543 return; 543 return;
@@ -568,15 +568,23 @@ do_signal(struct pt_regs * regs, struct switch_stack * sw,
568} 568}
569 569
570void 570void
571do_notify_resume(struct pt_regs *regs, struct switch_stack *sw, 571do_work_pending(struct pt_regs *regs, unsigned long thread_flags,
572 unsigned long thread_info_flags,
573 unsigned long r0, unsigned long r19) 572 unsigned long r0, unsigned long r19)
574{ 573{
575 if (thread_info_flags & _TIF_SIGPENDING) 574 do {
576 do_signal(regs, sw, r0, r19); 575 if (thread_flags & _TIF_NEED_RESCHED) {
577 576 schedule();
578 if (thread_info_flags & _TIF_NOTIFY_RESUME) { 577 } else {
579 clear_thread_flag(TIF_NOTIFY_RESUME); 578 local_irq_enable();
580 tracehook_notify_resume(regs); 579 if (thread_flags & _TIF_SIGPENDING) {
581 } 580 do_signal(regs, r0, r19);
581 r0 = 0;
582 } else {
583 clear_thread_flag(TIF_NOTIFY_RESUME);
584 tracehook_notify_resume(regs);
585 }
586 }
587 local_irq_disable();
588 thread_flags = current_thread_info()->flags;
589 } while (thread_flags & _TIF_WORK_MASK);
582} 590}
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 767aae8277fa..431c3753145a 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -53,6 +53,7 @@ config ARM
53 select GENERIC_STRNLEN_USER 53 select GENERIC_STRNLEN_USER
54 select DCACHE_WORD_ACCESS if (CPU_V6 || CPU_V6K || CPU_V7) && !CPU_BIG_ENDIAN 54 select DCACHE_WORD_ACCESS if (CPU_V6 || CPU_V6K || CPU_V7) && !CPU_BIG_ENDIAN
55 select GENERIC_KERNEL_THREAD 55 select GENERIC_KERNEL_THREAD
56 select GENERIC_KERNEL_EXECVE
56 help 57 help
57 The ARM series is a line of low-power-consumption RISC chip designs 58 The ARM series is a line of low-power-consumption RISC chip designs
58 licensed by ARM Ltd and targeted at embedded applications and 59 licensed by ARM Ltd and targeted at embedded applications and
diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h
index f259921edfe9..91819ad54424 100644
--- a/arch/arm/include/asm/unistd.h
+++ b/arch/arm/include/asm/unistd.h
@@ -479,7 +479,6 @@
479#define __ARCH_WANT_SYS_SOCKETCALL 479#define __ARCH_WANT_SYS_SOCKETCALL
480#endif 480#endif
481#define __ARCH_WANT_SYS_EXECVE 481#define __ARCH_WANT_SYS_EXECVE
482#define __ARCH_WANT_KERNEL_EXECVE
483 482
484/* 483/*
485 * "Conditional" syscalls 484 * "Conditional" syscalls
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index e340fa1db203..417bac1846bd 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -86,35 +86,14 @@ ENDPROC(ret_to_user)
86 */ 86 */
87ENTRY(ret_from_fork) 87ENTRY(ret_from_fork)
88 bl schedule_tail 88 bl schedule_tail
89 cmp r5, #0
90 movne r0, r4
91 movne lr, pc
92 movne pc, r5
89 get_thread_info tsk 93 get_thread_info tsk
90 mov why, #1
91 b ret_slow_syscall 94 b ret_slow_syscall
92ENDPROC(ret_from_fork) 95ENDPROC(ret_from_fork)
93 96
94ENTRY(ret_from_kernel_thread)
95 UNWIND(.fnstart)
96 UNWIND(.cantunwind)
97 bl schedule_tail
98 mov r0, r4
99 adr lr, BSYM(1f) @ kernel threads should not exit
100 mov pc, r5
1011: bl do_exit
102 nop
103 UNWIND(.fnend)
104ENDPROC(ret_from_kernel_thread)
105
106/*
107 * turn a kernel thread into userland process
108 * use: ret_from_kernel_execve(struct pt_regs *normal)
109 */
110ENTRY(ret_from_kernel_execve)
111 mov why, #0 @ not a syscall
112 str why, [r0, #S_R0] @ ... and we want 0 in ->ARM_r0 as well
113 get_thread_info tsk @ thread structure
114 mov sp, r0 @ stack pointer just under pt_regs
115 b ret_slow_syscall
116ENDPROC(ret_from_kernel_execve)
117
118 .equ NR_syscalls,0 97 .equ NR_syscalls,0
119#define CALL(x) .equ NR_syscalls,NR_syscalls+1 98#define CALL(x) .equ NR_syscalls,NR_syscalls+1
120#include "calls.S" 99#include "calls.S"
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index f98c17ff1957..90084a6de35a 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -373,7 +373,6 @@ void release_thread(struct task_struct *dead_task)
373} 373}
374 374
375asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); 375asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
376asmlinkage void ret_from_kernel_thread(void) __asm__("ret_from_kernel_thread");
377 376
378int 377int
379copy_thread(unsigned long clone_flags, unsigned long stack_start, 378copy_thread(unsigned long clone_flags, unsigned long stack_start,
@@ -388,13 +387,13 @@ copy_thread(unsigned long clone_flags, unsigned long stack_start,
388 *childregs = *regs; 387 *childregs = *regs;
389 childregs->ARM_r0 = 0; 388 childregs->ARM_r0 = 0;
390 childregs->ARM_sp = stack_start; 389 childregs->ARM_sp = stack_start;
391 thread->cpu_context.pc = (unsigned long)ret_from_fork;
392 } else { 390 } else {
391 memset(childregs, 0, sizeof(struct pt_regs));
393 thread->cpu_context.r4 = stk_sz; 392 thread->cpu_context.r4 = stk_sz;
394 thread->cpu_context.r5 = stack_start; 393 thread->cpu_context.r5 = stack_start;
395 thread->cpu_context.pc = (unsigned long)ret_from_kernel_thread;
396 childregs->ARM_cpsr = SVC_MODE; 394 childregs->ARM_cpsr = SVC_MODE;
397 } 395 }
396 thread->cpu_context.pc = (unsigned long)ret_from_fork;
398 thread->cpu_context.sp = (unsigned long)childregs; 397 thread->cpu_context.sp = (unsigned long)childregs;
399 398
400 clear_ptrace_hw_breakpoint(p); 399 clear_ptrace_hw_breakpoint(p);
diff --git a/arch/powerpc/platforms/pseries/eeh_event.c b/arch/powerpc/platforms/pseries/eeh_event.c
index 51faaac8abe6..185bedd926df 100644
--- a/arch/powerpc/platforms/pseries/eeh_event.c
+++ b/arch/powerpc/platforms/pseries/eeh_event.c
@@ -23,6 +23,7 @@
23#include <linux/pci.h> 23#include <linux/pci.h>
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <linux/workqueue.h> 25#include <linux/workqueue.h>
26#include <linux/kthread.h>
26#include <asm/eeh_event.h> 27#include <asm/eeh_event.h>
27#include <asm/ppc-pci.h> 28#include <asm/ppc-pci.h>
28 29
@@ -59,8 +60,6 @@ static int eeh_event_handler(void * dummy)
59 struct eeh_event *event; 60 struct eeh_event *event;
60 struct eeh_pe *pe; 61 struct eeh_pe *pe;
61 62
62 set_task_comm(current, "eehd");
63
64 spin_lock_irqsave(&eeh_eventlist_lock, flags); 63 spin_lock_irqsave(&eeh_eventlist_lock, flags);
65 event = NULL; 64 event = NULL;
66 65
@@ -108,7 +107,7 @@ static int eeh_event_handler(void * dummy)
108 */ 107 */
109static void eeh_thread_launcher(struct work_struct *dummy) 108static void eeh_thread_launcher(struct work_struct *dummy)
110{ 109{
111 if (kernel_thread(eeh_event_handler, NULL, CLONE_KERNEL) < 0) 110 if (IS_ERR(kthread_run(eeh_event_handler, NULL, "eehd")))
112 printk(KERN_ERR "Failed to start EEH daemon\n"); 111 printk(KERN_ERR "Failed to start EEH daemon\n");
113} 112}
114 113
diff --git a/arch/um/include/asm/processor-generic.h b/arch/um/include/asm/processor-generic.h
index 1e82e954e978..c03cd5a02364 100644
--- a/arch/um/include/asm/processor-generic.h
+++ b/arch/um/include/asm/processor-generic.h
@@ -26,7 +26,6 @@ struct thread_struct {
26 jmp_buf *fault_catcher; 26 jmp_buf *fault_catcher;
27 struct task_struct *prev_sched; 27 struct task_struct *prev_sched;
28 unsigned long temp_stack; 28 unsigned long temp_stack;
29 jmp_buf *exec_buf;
30 struct arch_thread arch; 29 struct arch_thread arch;
31 jmp_buf switch_buf; 30 jmp_buf switch_buf;
32 int mm_count; 31 int mm_count;
@@ -54,7 +53,6 @@ struct thread_struct {
54 .fault_addr = NULL, \ 53 .fault_addr = NULL, \
55 .prev_sched = NULL, \ 54 .prev_sched = NULL, \
56 .temp_stack = 0, \ 55 .temp_stack = 0, \
57 .exec_buf = NULL, \
58 .arch = INIT_ARCH_THREAD, \ 56 .arch = INIT_ARCH_THREAD, \
59 .request = { 0 } \ 57 .request = { 0 } \
60} 58}
diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h
index 44883049c11d..95feaa47a2fb 100644
--- a/arch/um/include/shared/os.h
+++ b/arch/um/include/shared/os.h
@@ -191,7 +191,6 @@ extern int os_getpid(void);
191extern int os_getpgrp(void); 191extern int os_getpgrp(void);
192 192
193extern void init_new_thread_signals(void); 193extern void init_new_thread_signals(void);
194extern int run_kernel_thread(int (*fn)(void *), void *arg, jmp_buf **jmp_ptr);
195 194
196extern int os_map_memory(void *virt, int fd, unsigned long long off, 195extern int os_map_memory(void *virt, int fd, unsigned long long off,
197 unsigned long len, int r, int w, int x); 196 unsigned long len, int r, int w, int x);
diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c
index ab019c7f0b57..3a8ece7d09ca 100644
--- a/arch/um/kernel/exec.c
+++ b/arch/um/kernel/exec.c
@@ -47,8 +47,3 @@ void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp)
47#endif 47#endif
48} 48}
49EXPORT_SYMBOL(start_thread); 49EXPORT_SYMBOL(start_thread);
50
51void __noreturn ret_from_kernel_execve(struct pt_regs *unused)
52{
53 UML_LONGJMP(current->thread.exec_buf, 1);
54}
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
index 30629783b3e0..b6d699cdd557 100644
--- a/arch/um/kernel/process.c
+++ b/arch/um/kernel/process.c
@@ -135,14 +135,10 @@ void new_thread_handler(void)
135 arg = current->thread.request.u.thread.arg; 135 arg = current->thread.request.u.thread.arg;
136 136
137 /* 137 /*
138 * The return value is 1 if the kernel thread execs a process, 138 * callback returns only if the kernel thread execs a process
139 * 0 if it just exits
140 */ 139 */
141 n = run_kernel_thread(fn, arg, &current->thread.exec_buf); 140 n = fn(arg);
142 if (n == 1) 141 userspace(&current->thread.regs.regs);
143 userspace(&current->thread.regs.regs);
144 else
145 do_exit(0);
146} 142}
147 143
148/* Called magically, see new_thread_handler above */ 144/* Called magically, see new_thread_handler above */
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
index 162bea3d91b2..b8f34c9e53ae 100644
--- a/arch/um/os-Linux/process.c
+++ b/arch/um/os-Linux/process.c
@@ -244,16 +244,3 @@ void init_new_thread_signals(void)
244 signal(SIGWINCH, SIG_IGN); 244 signal(SIGWINCH, SIG_IGN);
245 signal(SIGTERM, SIG_DFL); 245 signal(SIGTERM, SIG_DFL);
246} 246}
247
248int run_kernel_thread(int (*fn)(void *), void *arg, jmp_buf **jmp_ptr)
249{
250 jmp_buf buf;
251 int n;
252
253 *jmp_ptr = &buf;
254 n = UML_SETJMP(&buf);
255 if (n != 0)
256 return n;
257 (*fn)(arg);
258 return 0;
259}
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 42d2c35a5bbd..70071b19eb98 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -109,6 +109,7 @@ config X86
109 select HAVE_RCU_USER_QS if X86_64 109 select HAVE_RCU_USER_QS if X86_64
110 select HAVE_IRQ_TIME_ACCOUNTING 110 select HAVE_IRQ_TIME_ACCOUNTING
111 select GENERIC_KERNEL_THREAD 111 select GENERIC_KERNEL_THREAD
112 select GENERIC_KERNEL_EXECVE
112 113
113config INSTRUCTION_DECODER 114config INSTRUCTION_DECODER
114 def_bool y 115 def_bool y
diff --git a/arch/x86/include/asm/unistd.h b/arch/x86/include/asm/unistd.h
index 55d155560fdf..16f3fc6ebf2e 100644
--- a/arch/x86/include/asm/unistd.h
+++ b/arch/x86/include/asm/unistd.h
@@ -51,7 +51,6 @@
51# define __ARCH_WANT_SYS_UTIME 51# define __ARCH_WANT_SYS_UTIME
52# define __ARCH_WANT_SYS_WAITPID 52# define __ARCH_WANT_SYS_WAITPID
53# define __ARCH_WANT_SYS_EXECVE 53# define __ARCH_WANT_SYS_EXECVE
54# define __ARCH_WANT_KERNEL_EXECVE
55 54
56/* 55/*
57 * "Conditional" syscalls 56 * "Conditional" syscalls
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index 2c6340796fe9..a1193aef6d7d 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -299,12 +299,20 @@ ENTRY(ret_from_fork)
299 CFI_ENDPROC 299 CFI_ENDPROC
300END(ret_from_fork) 300END(ret_from_fork)
301 301
302ENTRY(ret_from_kernel_execve) 302ENTRY(ret_from_kernel_thread)
303 movl %eax, %esp 303 CFI_STARTPROC
304 movl $0,PT_EAX(%esp) 304 pushl_cfi %eax
305 call schedule_tail
305 GET_THREAD_INFO(%ebp) 306 GET_THREAD_INFO(%ebp)
307 popl_cfi %eax
308 pushl_cfi $0x0202 # Reset kernel eflags
309 popfl_cfi
310 movl PT_EBP(%esp),%eax
311 call *PT_EBX(%esp)
312 movl $0,PT_EAX(%esp)
306 jmp syscall_exit 313 jmp syscall_exit
307END(ret_from_kernel_execve) 314 CFI_ENDPROC
315ENDPROC(ret_from_kernel_thread)
308 316
309/* 317/*
310 * Interrupt exit functions should be protected against kprobes 318 * Interrupt exit functions should be protected against kprobes
@@ -1015,21 +1023,6 @@ END(spurious_interrupt_bug)
1015 */ 1023 */
1016 .popsection 1024 .popsection
1017 1025
1018ENTRY(ret_from_kernel_thread)
1019 CFI_STARTPROC
1020 pushl_cfi %eax
1021 call schedule_tail
1022 GET_THREAD_INFO(%ebp)
1023 popl_cfi %eax
1024 pushl_cfi $0x0202 # Reset kernel eflags
1025 popfl_cfi
1026 movl PT_EBP(%esp),%eax
1027 call *PT_EBX(%esp)
1028 call do_exit
1029 ud2 # padding for call trace
1030 CFI_ENDPROC
1031ENDPROC(ret_from_kernel_thread)
1032
1033#ifdef CONFIG_XEN 1026#ifdef CONFIG_XEN
1034/* Xen doesn't set %esp to be precisely what the normal sysenter 1027/* Xen doesn't set %esp to be precisely what the normal sysenter
1035 entrypoint expects, so fix it up before using the normal path. */ 1028 entrypoint expects, so fix it up before using the normal path. */
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index cdc790c78f32..0c58952d64e8 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -563,15 +563,13 @@ ENTRY(ret_from_fork)
563 jmp ret_from_sys_call # go to the SYSRET fastpath 563 jmp ret_from_sys_call # go to the SYSRET fastpath
564 564
5651: 5651:
566 subq $REST_SKIP, %rsp # move the stack pointer back 566 subq $REST_SKIP, %rsp # leave space for volatiles
567 CFI_ADJUST_CFA_OFFSET REST_SKIP 567 CFI_ADJUST_CFA_OFFSET REST_SKIP
568 movq %rbp, %rdi 568 movq %rbp, %rdi
569 call *%rbx 569 call *%rbx
570 # exit 570 movl $0, RAX(%rsp)
571 mov %eax, %edi 571 RESTORE_REST
572 call do_exit 572 jmp int_ret_from_sys_call
573 ud2 # padding for call trace
574
575 CFI_ENDPROC 573 CFI_ENDPROC
576END(ret_from_fork) 574END(ret_from_fork)
577 575
@@ -1326,20 +1324,6 @@ bad_gs:
1326 jmp 2b 1324 jmp 2b
1327 .previous 1325 .previous
1328 1326
1329ENTRY(ret_from_kernel_execve)
1330 movq %rdi, %rsp
1331 movl $0, RAX(%rsp)
1332 // RESTORE_REST
1333 movq 0*8(%rsp), %r15
1334 movq 1*8(%rsp), %r14
1335 movq 2*8(%rsp), %r13
1336 movq 3*8(%rsp), %r12
1337 movq 4*8(%rsp), %rbp
1338 movq 5*8(%rsp), %rbx
1339 addq $(6*8), %rsp
1340 jmp int_ret_from_sys_call
1341END(ret_from_kernel_execve)
1342
1343/* Call softirq on interrupt stack. Interrupts are off. */ 1327/* Call softirq on interrupt stack. Interrupts are off. */
1344ENTRY(call_softirq) 1328ENTRY(call_softirq)
1345 CFI_STARTPROC 1329 CFI_STARTPROC
diff --git a/arch/x86/um/Kconfig b/arch/x86/um/Kconfig
index 30c4eec033af..9fa950df80e5 100644
--- a/arch/x86/um/Kconfig
+++ b/arch/x86/um/Kconfig
@@ -14,6 +14,7 @@ config UML_X86
14 def_bool y 14 def_bool y
15 select GENERIC_FIND_FIRST_BIT 15 select GENERIC_FIND_FIRST_BIT
16 select GENERIC_KERNEL_THREAD 16 select GENERIC_KERNEL_THREAD
17 select GENERIC_KERNEL_EXECVE
17 18
18config 64BIT 19config 64BIT
19 bool "64-bit kernel" if SUBARCH = "x86" 20 bool "64-bit kernel" if SUBARCH = "x86"
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 19439c75c5b2..727f0cd73921 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -827,7 +827,15 @@ asmlinkage long sys_fanotify_mark(int fanotify_fd, unsigned int flags,
827 const char __user *pathname); 827 const char __user *pathname);
828asmlinkage long sys_syncfs(int fd); 828asmlinkage long sys_syncfs(int fd);
829 829
830#ifndef CONFIG_GENERIC_KERNEL_EXECVE
830int kernel_execve(const char *filename, const char *const argv[], const char *const envp[]); 831int kernel_execve(const char *filename, const char *const argv[], const char *const envp[]);
832#else
833#define kernel_execve(filename, argv, envp) \
834 do_execve(filename, \
835 (const char __user *const __user *)argv, \
836 (const char __user *const __user *)envp, \
837 current_pt_regs())
838#endif
831 839
832 840
833asmlinkage long sys_perf_event_open( 841asmlinkage long sys_perf_event_open(
diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c
index 135959a276be..5e4ded51788e 100644
--- a/init/do_mounts_initrd.c
+++ b/init/do_mounts_initrd.c
@@ -16,13 +16,13 @@
16#include <linux/initrd.h> 16#include <linux/initrd.h>
17#include <linux/sched.h> 17#include <linux/sched.h>
18#include <linux/freezer.h> 18#include <linux/freezer.h>
19#include <linux/kmod.h>
19 20
20#include "do_mounts.h" 21#include "do_mounts.h"
21 22
22unsigned long initrd_start, initrd_end; 23unsigned long initrd_start, initrd_end;
23int initrd_below_start_ok; 24int initrd_below_start_ok;
24unsigned int real_root_dev; /* do_proc_dointvec cannot handle kdev_t */ 25unsigned int real_root_dev; /* do_proc_dointvec cannot handle kdev_t */
25static int __initdata old_fd, root_fd;
26static int __initdata mount_initrd = 1; 26static int __initdata mount_initrd = 1;
27 27
28static int __init no_initrd(char *str) 28static int __init no_initrd(char *str)
@@ -33,33 +33,29 @@ static int __init no_initrd(char *str)
33 33
34__setup("noinitrd", no_initrd); 34__setup("noinitrd", no_initrd);
35 35
36static int __init do_linuxrc(void *_shell) 36static int init_linuxrc(struct subprocess_info *info, struct cred *new)
37{ 37{
38 static const char *argv[] = { "linuxrc", NULL, }; 38 sys_unshare(CLONE_FS | CLONE_FILES);
39 extern const char *envp_init[]; 39 /* move initrd over / and chdir/chroot in initrd root */
40 const char *shell = _shell; 40 sys_chdir("/root");
41 41 sys_mount(".", "/", NULL, MS_MOVE, NULL);
42 sys_close(old_fd);sys_close(root_fd); 42 sys_chroot(".");
43 sys_setsid(); 43 sys_setsid();
44 return kernel_execve(shell, argv, envp_init); 44 return 0;
45} 45}
46 46
47static void __init handle_initrd(void) 47static void __init handle_initrd(void)
48{ 48{
49 static char *argv[] = { "linuxrc", NULL, };
50 extern char *envp_init[];
49 int error; 51 int error;
50 int pid;
51 52
52 real_root_dev = new_encode_dev(ROOT_DEV); 53 real_root_dev = new_encode_dev(ROOT_DEV);
53 create_dev("/dev/root.old", Root_RAM0); 54 create_dev("/dev/root.old", Root_RAM0);
54 /* mount initrd on rootfs' /root */ 55 /* mount initrd on rootfs' /root */
55 mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY); 56 mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY);
56 sys_mkdir("/old", 0700); 57 sys_mkdir("/old", 0700);
57 root_fd = sys_open("/", 0, 0); 58 sys_chdir("/old");
58 old_fd = sys_open("/old", 0, 0);
59 /* move initrd over / and chdir/chroot in initrd root */
60 sys_chdir("/root");
61 sys_mount(".", "/", NULL, MS_MOVE, NULL);
62 sys_chroot(".");
63 59
64 /* 60 /*
65 * In case that a resume from disk is carried out by linuxrc or one of 61 * In case that a resume from disk is carried out by linuxrc or one of
@@ -67,27 +63,22 @@ static void __init handle_initrd(void)
67 */ 63 */
68 current->flags |= PF_FREEZER_SKIP; 64 current->flags |= PF_FREEZER_SKIP;
69 65
70 pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD); 66 call_usermodehelper_fns("/linuxrc", argv, envp_init, UMH_WAIT_PROC,
71 if (pid > 0) 67 init_linuxrc, NULL, NULL);
72 while (pid != sys_wait4(-1, NULL, 0, NULL))
73 yield();
74 68
75 current->flags &= ~PF_FREEZER_SKIP; 69 current->flags &= ~PF_FREEZER_SKIP;
76 70
77 /* move initrd to rootfs' /old */ 71 /* move initrd to rootfs' /old */
78 sys_fchdir(old_fd); 72 sys_mount("..", ".", NULL, MS_MOVE, NULL);
79 sys_mount("/", ".", NULL, MS_MOVE, NULL);
80 /* switch root and cwd back to / of rootfs */ 73 /* switch root and cwd back to / of rootfs */
81 sys_fchdir(root_fd); 74 sys_chroot("..");
82 sys_chroot(".");
83 sys_close(old_fd);
84 sys_close(root_fd);
85 75
86 if (new_decode_dev(real_root_dev) == Root_RAM0) { 76 if (new_decode_dev(real_root_dev) == Root_RAM0) {
87 sys_chdir("/old"); 77 sys_chdir("/old");
88 return; 78 return;
89 } 79 }
90 80
81 sys_chdir("/");
91 ROOT_DEV = new_decode_dev(real_root_dev); 82 ROOT_DEV = new_decode_dev(real_root_dev);
92 mount_root(); 83 mount_root();
93 84
diff --git a/init/main.c b/init/main.c
index 313360fe1118..9cf77ab138a6 100644
--- a/init/main.c
+++ b/init/main.c
@@ -69,6 +69,7 @@
69#include <linux/slab.h> 69#include <linux/slab.h>
70#include <linux/perf_event.h> 70#include <linux/perf_event.h>
71#include <linux/file.h> 71#include <linux/file.h>
72#include <linux/ptrace.h>
72 73
73#include <asm/io.h> 74#include <asm/io.h>
74#include <asm/bugs.h> 75#include <asm/bugs.h>
@@ -791,17 +792,17 @@ static void __init do_pre_smp_initcalls(void)
791 do_one_initcall(*fn); 792 do_one_initcall(*fn);
792} 793}
793 794
794static void run_init_process(const char *init_filename) 795static int run_init_process(const char *init_filename)
795{ 796{
796 argv_init[0] = init_filename; 797 argv_init[0] = init_filename;
797 kernel_execve(init_filename, argv_init, envp_init); 798 return kernel_execve(init_filename, argv_init, envp_init);
798} 799}
799 800
800/* This is a non __init function. Force it to be noinline otherwise gcc 801static void __init kernel_init_freeable(void);
801 * makes it inline to init() and it becomes part of init.text section 802
802 */ 803static int __ref kernel_init(void *unused)
803static noinline int init_post(void)
804{ 804{
805 kernel_init_freeable();
805 /* need to finish all async __init code before freeing the memory */ 806 /* need to finish all async __init code before freeing the memory */
806 async_synchronize_full(); 807 async_synchronize_full();
807 free_initmem(); 808 free_initmem();
@@ -813,7 +814,8 @@ static noinline int init_post(void)
813 flush_delayed_fput(); 814 flush_delayed_fput();
814 815
815 if (ramdisk_execute_command) { 816 if (ramdisk_execute_command) {
816 run_init_process(ramdisk_execute_command); 817 if (!run_init_process(ramdisk_execute_command))
818 return 0;
817 printk(KERN_WARNING "Failed to execute %s\n", 819 printk(KERN_WARNING "Failed to execute %s\n",
818 ramdisk_execute_command); 820 ramdisk_execute_command);
819 } 821 }
@@ -825,20 +827,22 @@ static noinline int init_post(void)
825 * trying to recover a really broken machine. 827 * trying to recover a really broken machine.
826 */ 828 */
827 if (execute_command) { 829 if (execute_command) {
828 run_init_process(execute_command); 830 if (!run_init_process(execute_command))
831 return 0;
829 printk(KERN_WARNING "Failed to execute %s. Attempting " 832 printk(KERN_WARNING "Failed to execute %s. Attempting "
830 "defaults...\n", execute_command); 833 "defaults...\n", execute_command);
831 } 834 }
832 run_init_process("/sbin/init"); 835 if (!run_init_process("/sbin/init") ||
833 run_init_process("/etc/init"); 836 !run_init_process("/etc/init") ||
834 run_init_process("/bin/init"); 837 !run_init_process("/bin/init") ||
835 run_init_process("/bin/sh"); 838 !run_init_process("/bin/sh"))
839 return 0;
836 840
837 panic("No init found. Try passing init= option to kernel. " 841 panic("No init found. Try passing init= option to kernel. "
838 "See Linux Documentation/init.txt for guidance."); 842 "See Linux Documentation/init.txt for guidance.");
839} 843}
840 844
841static int __init kernel_init(void * unused) 845static void __init kernel_init_freeable(void)
842{ 846{
843 /* 847 /*
844 * Wait until kthreadd is all set-up. 848 * Wait until kthreadd is all set-up.
@@ -893,7 +897,4 @@ static int __init kernel_init(void * unused)
893 * we're essentially up and running. Get rid of the 897 * we're essentially up and running. Get rid of the
894 * initmem segments and start the user-mode stuff.. 898 * initmem segments and start the user-mode stuff..
895 */ 899 */
896
897 init_post();
898 return 0;
899} 900}
diff --git a/kernel/kmod.c b/kernel/kmod.c
index 6f99aead66c6..1c317e386831 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -37,6 +37,7 @@
37#include <linux/notifier.h> 37#include <linux/notifier.h>
38#include <linux/suspend.h> 38#include <linux/suspend.h>
39#include <linux/rwsem.h> 39#include <linux/rwsem.h>
40#include <linux/ptrace.h>
40#include <asm/uaccess.h> 41#include <asm/uaccess.h>
41 42
42#include <trace/events/module.h> 43#include <trace/events/module.h>
@@ -221,11 +222,13 @@ static int ____call_usermodehelper(void *data)
221 retval = kernel_execve(sub_info->path, 222 retval = kernel_execve(sub_info->path,
222 (const char *const *)sub_info->argv, 223 (const char *const *)sub_info->argv,
223 (const char *const *)sub_info->envp); 224 (const char *const *)sub_info->envp);
225 if (!retval)
226 return 0;
224 227
225 /* Exec failed? */ 228 /* Exec failed? */
226fail: 229fail:
227 sub_info->retval = retval; 230 sub_info->retval = retval;
228 return 0; 231 do_exit(0);
229} 232}
230 233
231static int call_helper(void *data) 234static int call_helper(void *data)
@@ -292,7 +295,7 @@ static int wait_for_helper(void *data)
292 } 295 }
293 296
294 umh_complete(sub_info); 297 umh_complete(sub_info);
295 return 0; 298 do_exit(0);
296} 299}
297 300
298/* This is run by khelper thread */ 301/* This is run by khelper thread */
diff --git a/kernel/kthread.c b/kernel/kthread.c
index 146a6fa96825..29fb60caecb5 100644
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -16,6 +16,7 @@
16#include <linux/mutex.h> 16#include <linux/mutex.h>
17#include <linux/slab.h> 17#include <linux/slab.h>
18#include <linux/freezer.h> 18#include <linux/freezer.h>
19#include <linux/ptrace.h>
19#include <trace/events/sched.h> 20#include <trace/events/sched.h>
20 21
21static DEFINE_SPINLOCK(kthread_create_lock); 22static DEFINE_SPINLOCK(kthread_create_lock);