aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/entry_32.S
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-09 23:02:25 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-09 23:02:25 -0400
commit42859eea96ba6beabfb0369a1eeffa3c7d2bd9cb (patch)
treefa38aeda0d6e7a4c48a882b166b8643594a1ad50 /arch/x86/kernel/entry_32.S
parentf59b51fe3d3092c08d7d554ecb40db24011b2ebc (diff)
parentf322220d6159455da2b5a8a596d802c8695fed30 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal
Pull generic execve() changes from Al Viro: "This introduces the generic kernel_thread() and kernel_execve() functions, and switches x86, arm, alpha, um and s390 over to them." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal: (26 commits) s390: convert to generic kernel_execve() s390: switch to generic kernel_thread() s390: fold kernel_thread_helper() into ret_from_fork() s390: fold execve_tail() into start_thread(), convert to generic sys_execve() um: switch to generic kernel_thread() x86, um/x86: switch to generic sys_execve and kernel_execve x86: split ret_from_fork alpha: introduce ret_from_kernel_execve(), switch to generic kernel_execve() alpha: switch to generic kernel_thread() alpha: switch to generic sys_execve() arm: get rid of execve wrapper, switch to generic execve() implementation arm: optimized current_pt_regs() arm: introduce ret_from_kernel_execve(), switch to generic kernel_execve() arm: split ret_from_fork, simplify kernel_thread() [based on patch by rmk] generic sys_execve() generic kernel_execve() new helper: current_pt_regs() preparation for generic kernel_thread() um: kill thread->forking um: let signal_delivered() do SIGTRAP on singlestepping into handler ...
Diffstat (limited to 'arch/x86/kernel/entry_32.S')
-rw-r--r--arch/x86/kernel/entry_32.S26
1 files changed, 18 insertions, 8 deletions
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index 0750e3ba87c0..8f9ed1afde8f 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -299,6 +299,13 @@ 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)
303 movl %eax, %esp
304 movl $0,PT_EAX(%esp)
305 GET_THREAD_INFO(%ebp)
306 jmp syscall_exit
307END(ret_from_kernel_execve)
308
302/* 309/*
303 * Interrupt exit functions should be protected against kprobes 310 * Interrupt exit functions should be protected against kprobes
304 */ 311 */
@@ -323,8 +330,7 @@ ret_from_intr:
323 andl $(X86_EFLAGS_VM | SEGMENT_RPL_MASK), %eax 330 andl $(X86_EFLAGS_VM | SEGMENT_RPL_MASK), %eax
324#else 331#else
325 /* 332 /*
326 * We can be coming here from a syscall done in the kernel space, 333 * We can be coming here from child spawned by kernel_thread().
327 * e.g. a failed kernel_execve().
328 */ 334 */
329 movl PT_CS(%esp), %eax 335 movl PT_CS(%esp), %eax
330 andl $SEGMENT_RPL_MASK, %eax 336 andl $SEGMENT_RPL_MASK, %eax
@@ -732,7 +738,6 @@ ENDPROC(ptregs_##name)
732PTREGSCALL1(iopl) 738PTREGSCALL1(iopl)
733PTREGSCALL0(fork) 739PTREGSCALL0(fork)
734PTREGSCALL0(vfork) 740PTREGSCALL0(vfork)
735PTREGSCALL3(execve)
736PTREGSCALL2(sigaltstack) 741PTREGSCALL2(sigaltstack)
737PTREGSCALL0(sigreturn) 742PTREGSCALL0(sigreturn)
738PTREGSCALL0(rt_sigreturn) 743PTREGSCALL0(rt_sigreturn)
@@ -1015,15 +1020,20 @@ END(spurious_interrupt_bug)
1015 */ 1020 */
1016 .popsection 1021 .popsection
1017 1022
1018ENTRY(kernel_thread_helper) 1023ENTRY(ret_from_kernel_thread)
1019 pushl $0 # fake return address for unwinder
1020 CFI_STARTPROC 1024 CFI_STARTPROC
1021 movl %edi,%eax 1025 pushl_cfi %eax
1022 call *%esi 1026 call schedule_tail
1027 GET_THREAD_INFO(%ebp)
1028 popl_cfi %eax
1029 pushl_cfi $0x0202 # Reset kernel eflags
1030 popfl_cfi
1031 movl PT_EBP(%esp),%eax
1032 call *PT_EBX(%esp)
1023 call do_exit 1033 call do_exit
1024 ud2 # padding for call trace 1034 ud2 # padding for call trace
1025 CFI_ENDPROC 1035 CFI_ENDPROC
1026ENDPROC(kernel_thread_helper) 1036ENDPROC(ret_from_kernel_thread)
1027 1037
1028#ifdef CONFIG_XEN 1038#ifdef CONFIG_XEN
1029/* Xen doesn't set %esp to be precisely what the normal sysenter 1039/* Xen doesn't set %esp to be precisely what the normal sysenter