]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge remote-tracking branch 'signal/for-next'
authorStephen Rothwell <sfr@canb.auug.org.au>
Wed, 3 Oct 2012 06:36:00 +0000 (16:36 +1000)
committerStephen Rothwell <sfr@canb.auug.org.au>
Wed, 3 Oct 2012 06:36:00 +0000 (16:36 +1000)
Conflicts:
arch/alpha/Kconfig
arch/arm/Kconfig
arch/arm/include/asm/thread_info.h
arch/c6x/Kconfig
arch/cris/include/asm/Kbuild
arch/h8300/include/asm/Kbuild
arch/m32r/include/asm/Kbuild
arch/m68k/Kconfig
arch/mn10300/Kconfig
arch/powerpc/Kconfig
arch/s390/Kconfig
arch/um/kernel/exec.c
arch/x86/Kconfig
arch/x86/kernel/process_32.c
arch/x86/kernel/signal.c
fs/exec.c

193 files changed:
arch/Kconfig
arch/alpha/Kconfig
arch/alpha/include/asm/Kbuild
arch/alpha/include/asm/exec.h [deleted file]
arch/alpha/include/asm/processor.h
arch/alpha/include/asm/thread_info.h
arch/alpha/include/asm/unistd.h
arch/alpha/kernel/alpha_ksyms.c
arch/alpha/kernel/entry.S
arch/alpha/kernel/process.c
arch/alpha/kernel/ptrace.c
arch/arm/Kconfig
arch/arm/include/asm/processor.h
arch/arm/include/asm/ptrace.h
arch/arm/include/asm/system.h
arch/arm/include/asm/thread_info.h
arch/arm/include/asm/unistd.h
arch/arm/kernel/calls.S
arch/arm/kernel/entry-common.S
arch/arm/kernel/process.c
arch/arm/kernel/signal.c
arch/arm/kernel/sys_arm.c
arch/avr32/include/asm/Kbuild
arch/avr32/include/asm/exec.h [deleted file]
arch/avr32/include/asm/thread_info.h
arch/avr32/kernel/signal.c
arch/blackfin/include/asm/thread_info.h
arch/blackfin/kernel/signal.c
arch/c6x/Kconfig
arch/c6x/include/asm/Kbuild
arch/c6x/include/asm/exec.h [deleted file]
arch/c6x/include/asm/processor.h
arch/c6x/include/asm/syscalls.h
arch/c6x/include/asm/thread_info.h
arch/c6x/include/asm/unistd.h
arch/c6x/kernel/asm-offsets.c
arch/c6x/kernel/entry.S
arch/c6x/kernel/process.c
arch/cris/include/asm/Kbuild
arch/cris/include/asm/exec.h [deleted file]
arch/cris/include/asm/thread_info.h
arch/frv/Kconfig
arch/frv/include/asm/Kbuild
arch/frv/include/asm/exec.h [deleted file]
arch/frv/include/asm/processor.h
arch/frv/include/asm/ptrace.h
arch/frv/include/asm/thread_info.h
arch/frv/include/asm/unistd.h
arch/frv/kernel/Makefile
arch/frv/kernel/entry.S
arch/frv/kernel/frv_ksyms.c
arch/frv/kernel/kernel_execve.S [deleted file]
arch/frv/kernel/kernel_thread.S [deleted file]
arch/frv/kernel/process.c
arch/frv/kernel/signal.c
arch/h8300/include/asm/Kbuild
arch/h8300/include/asm/exec.h [deleted file]
arch/h8300/include/asm/thread_info.h
arch/h8300/kernel/signal.c
arch/hexagon/include/asm/thread_info.h
arch/hexagon/kernel/signal.c
arch/hexagon/kernel/syscall.c
arch/ia64/include/asm/Kbuild
arch/ia64/include/asm/exec.h [deleted file]
arch/ia64/include/asm/thread_info.h
arch/ia64/kernel/signal.c
arch/m32r/include/asm/Kbuild
arch/m32r/include/asm/exec.h [deleted file]
arch/m32r/include/asm/thread_info.h
arch/m32r/kernel/signal.c
arch/m68k/Kconfig
arch/m68k/include/asm/Kbuild
arch/m68k/include/asm/exec.h [deleted file]
arch/m68k/include/asm/processor.h
arch/m68k/include/asm/ptrace.h
arch/m68k/include/asm/unistd.h
arch/m68k/kernel/entry.S
arch/m68k/kernel/process.c
arch/m68k/kernel/sys_m68k.c
arch/microblaze/include/asm/Kbuild
arch/microblaze/include/asm/exec.h [deleted file]
arch/microblaze/include/asm/thread_info.h
arch/microblaze/kernel/signal.c
arch/mips/include/asm/thread_info.h
arch/mn10300/Kconfig
arch/mn10300/include/asm/Kbuild
arch/mn10300/include/asm/exec.h [deleted file]
arch/mn10300/include/asm/frame.inc
arch/mn10300/include/asm/processor.h
arch/mn10300/include/asm/ptrace.h
arch/mn10300/include/asm/thread_info.h
arch/mn10300/include/asm/unistd.h
arch/mn10300/kernel/Makefile
arch/mn10300/kernel/entry.S
arch/mn10300/kernel/internal.h
arch/mn10300/kernel/kernel_execve.S [deleted file]
arch/mn10300/kernel/kthread.S [deleted file]
arch/mn10300/kernel/process.c
arch/mn10300/kernel/signal.c
arch/openrisc/include/asm/thread_info.h
arch/parisc/hpux/gate.S
arch/parisc/include/asm/Kbuild
arch/parisc/include/asm/exec.h [deleted file]
arch/parisc/include/asm/thread_info.h
arch/parisc/kernel/signal.c
arch/parisc/kernel/syscall.S
arch/powerpc/Kconfig
arch/powerpc/include/asm/processor.h
arch/powerpc/include/asm/ptrace.h
arch/powerpc/include/asm/syscalls.h
arch/powerpc/include/asm/thread_info.h
arch/powerpc/include/asm/unistd.h
arch/powerpc/kernel/entry_32.S
arch/powerpc/kernel/entry_64.S
arch/powerpc/kernel/misc.S
arch/powerpc/kernel/misc_32.S
arch/powerpc/kernel/misc_64.S
arch/powerpc/kernel/ppc_ksyms.c
arch/powerpc/kernel/process.c
arch/powerpc/kernel/signal_32.c
arch/powerpc/kernel/sys_ppc32.c
arch/s390/Kconfig
arch/s390/include/asm/processor.h
arch/s390/include/asm/thread_info.h
arch/s390/include/asm/unistd.h
arch/s390/kernel/compat_linux.c
arch/s390/kernel/compat_linux.h
arch/s390/kernel/compat_wrapper.S
arch/s390/kernel/entry.S
arch/s390/kernel/entry.h
arch/s390/kernel/entry64.S
arch/s390/kernel/process.c
arch/score/include/asm/thread_info.h
arch/score/kernel/signal.c
arch/sh/include/asm/Kbuild
arch/sh/include/asm/exec.h [deleted file]
arch/sh/include/asm/thread_info.h
arch/sh/kernel/signal_32.c
arch/sh/kernel/signal_64.c
arch/sparc/include/asm/Kbuild
arch/sparc/include/asm/exec.h [deleted file]
arch/sparc/include/asm/thread_info_32.h
arch/sparc/include/asm/thread_info_64.h
arch/tile/include/asm/Kbuild
arch/tile/include/asm/exec.h [deleted file]
arch/tile/kernel/compat_signal.c
arch/tile/kernel/signal.c
arch/um/include/asm/processor-generic.h
arch/um/include/asm/thread_info.h
arch/um/kernel/exec.c
arch/um/kernel/internal.h [deleted file]
arch/um/kernel/process.c
arch/um/kernel/syscall.c
arch/unicore32/include/asm/Kbuild
arch/unicore32/include/asm/exec.h [deleted file]
arch/unicore32/include/asm/thread_info.h
arch/unicore32/kernel/entry.S
arch/unicore32/kernel/signal.c
arch/unicore32/kernel/sys.c
arch/x86/Kconfig
arch/x86/ia32/ia32entry.S
arch/x86/ia32/sys_ia32.c
arch/x86/include/asm/processor.h
arch/x86/include/asm/sys_ia32.h
arch/x86/include/asm/syscalls.h
arch/x86/include/asm/thread_info.h
arch/x86/include/asm/unistd.h
arch/x86/kernel/Makefile
arch/x86/kernel/asm-offsets.c
arch/x86/kernel/entry_32.S
arch/x86/kernel/entry_64.S
arch/x86/kernel/process.c
arch/x86/kernel/process_32.c
arch/x86/kernel/process_64.c
arch/x86/kernel/signal.c
arch/x86/kernel/sys_i386_32.c [deleted file]
arch/x86/kernel/vm86_32.c
arch/x86/syscalls/syscall_32.tbl
arch/x86/um/Kconfig
arch/x86/um/sys_call_table_32.c
arch/xtensa/include/asm/Kbuild
arch/xtensa/include/asm/exec.h [deleted file]
arch/xtensa/include/asm/thread_info.h
arch/xtensa/kernel/signal.c
fs/binfmt_elf.c
fs/binfmt_elf_fdpic.c
fs/exec.c
include/linux/binfmts.h
include/linux/compat.h
include/linux/ptrace.h
include/linux/sched.h
kernel/fork.c
kernel/sched/core.c

index 8ee5ccf234e31b78c9c17ee060421240c0a6f8be..d1b1e05583437bf41ca02ad7dd6cfc0bfc536452 100644 (file)
@@ -271,6 +271,9 @@ config ARCH_WANT_OLD_COMPAT_IPC
        select ARCH_WANT_COMPAT_IPC_PARSE_VERSION
        bool
 
+config GENERIC_KERNEL_THREAD
+       bool
+
 config HAVE_ARCH_SECCOMP_FILTER
        bool
        help
index 7e3710c0cce5a4c2ef51b8a889a061979a0b9b24..6ac8f6e512f6f6a49949bd0378a6d848b8da8ecc 100644 (file)
@@ -22,6 +22,7 @@ config ALPHA
        select GENERIC_STRNLEN_USER
        select HAVE_MOD_ARCH_SPECIFIC
        select MODULES_USE_ELF_RELA
+       select GENERIC_KERNEL_THREAD
        help
          The Alpha is a 64-bit general-purpose processor designed and
          marketed by the Digital Equipment Corporation of blessed memory,
index e423defed91e30cb68bf51863fe105caffe7f016..3bae7c9a0477cade57e125b628dcc324fff12600 100644 (file)
@@ -8,3 +8,4 @@ header-y += pal.h
 header-y += reg.h
 header-y += regdef.h
 header-y += sysinfo.h
+generic-y += exec.h
diff --git a/arch/alpha/include/asm/exec.h b/arch/alpha/include/asm/exec.h
deleted file mode 100644 (file)
index 4a5a41f..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __ALPHA_EXEC_H
-#define __ALPHA_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* __ALPHA_EXEC_H */
index e37b887b3d9f636fdcb0b4615a8c648dfc3d364f..6cb7fe85c4b567adad3516a74c5b862a32a50a5e 100644 (file)
@@ -49,9 +49,6 @@ extern void start_thread(struct pt_regs *, unsigned long, unsigned long);
 /* Free all resources held by a thread. */
 extern void release_thread(struct task_struct *);
 
-/* Create a kernel thread without removing it from tasklists.  */
-extern long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
-
 unsigned long get_wchan(struct task_struct *p);
 
 #define KSTK_EIP(tsk) (task_pt_regs(tsk)->pc)
index 28335bd40e406d54557fc17d7dbc15eae88d1a8d..4554ecbff7c6527be35fea7d20e255cc0770b653 100644 (file)
@@ -84,7 +84,6 @@ register struct thread_info *__current_thread_info __asm__("$8");
 #define _TIF_SIGPENDING                (1<<TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED      (1<<TIF_NEED_RESCHED)
 #define _TIF_POLLING_NRFLAG    (1<<TIF_POLLING_NRFLAG)
-#define _TIF_RESTORE_SIGMASK   (1<<TIF_RESTORE_SIGMASK)
 #define _TIF_NOTIFY_RESUME     (1<<TIF_NOTIFY_RESUME)
 
 /* Work to do on interrupt/exception return.  */
@@ -117,5 +116,7 @@ register struct thread_info *__current_thread_info __asm__("$8");
                 (int __user *)(value));                                \
        })
 
+#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
+
 #endif /* __KERNEL__ */
 #endif /* _ALPHA_THREAD_INFO_H */
index a31a78eac9b99962cf6b55df76b1066cdcaf7b2b..3cb6c1188984f0e9de8816d420a9a9e55fe1f93d 100644 (file)
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_RT_SIGSUSPEND
+#define __ARCH_WANT_SYS_EXECVE
+#define __ARCH_WANT_KERNEL_EXECVE
 
 /* "Conditional" syscalls.  What we want is
 
index 15fa821d09cd38ff58ea5390439617ee2ff4a2eb..89566b346c0f802bd5bfe0c817bd2fee9bd39d3e 100644 (file)
@@ -50,9 +50,6 @@ EXPORT_SYMBOL(alpha_read_fp_reg_s);
 EXPORT_SYMBOL(alpha_write_fp_reg);
 EXPORT_SYMBOL(alpha_write_fp_reg_s);
 
-/* entry.S */
-EXPORT_SYMBOL(kernel_thread);
-
 /* Networking helper routines. */
 EXPORT_SYMBOL(csum_tcpudp_magic);
 EXPORT_SYMBOL(ip_compute_csum);
index ec0da0567ab515e6203d2310a9d960be7d4fc0e7..2a359c9ee3cd88a341550c57f34177288ee61ecd 100644 (file)
@@ -418,11 +418,10 @@ $work_notifysig:
 strace:
        /* set up signal stack, call syscall_trace */
        bsr     $1, do_switch_stack
-       jsr     $26, syscall_trace
+       jsr     $26, syscall_trace_enter /* returns the syscall number */
        bsr     $1, undo_switch_stack
 
-       /* get the system call number and the arguments back.. */
-       ldq     $0, 0($sp)
+       /* get the arguments back.. */
        ldq     $16, SP_OFF+24($sp)
        ldq     $17, SP_OFF+32($sp)
        ldq     $18, SP_OFF+40($sp)
@@ -449,7 +448,7 @@ $strace_success:
        stq     $0, 0($sp)              /* save return value */
 
        bsr     $1, do_switch_stack
-       jsr     $26, syscall_trace
+       jsr     $26, syscall_trace_leave
        bsr     $1, undo_switch_stack
        br      $31, ret_from_sys_call
 
@@ -467,7 +466,7 @@ $strace_error:
        bsr     $1, do_switch_stack
        mov     $19, $9         /* save old syscall number */
        mov     $20, $10        /* save old a3 */
-       jsr     $26, syscall_trace
+       jsr     $26, syscall_trace_leave
        mov     $9, $19
        mov     $10, $20
        bsr     $1, undo_switch_stack
@@ -609,59 +608,35 @@ ret_from_fork:
 .end ret_from_fork
 
 /*
- * kernel_thread(fn, arg, clone_flags)
+ * ... and new kernel threads - here
  */
        .align 4
-       .globl  kernel_thread
-       .ent    kernel_thread
-kernel_thread:
-       /* We can be called from a module.  */
-       ldgp    $gp, 0($27)
-       .prologue 1
-       subq    $sp, SP_OFF+6*8, $sp
-       br      $1, 2f          /* load start address */
-
-       /* We've now "returned" from a fake system call.  */
-       unop
-       blt     $0, 1f          /* error?  */
-       ldi     $1, 0x3fff
-       beq     $20, 1f         /* parent or child?  */
-
-       bic     $sp, $1, $8     /* in child.  */
-       jsr     $26, ($27)
+       .globl  ret_from_kernel_thread
+       .ent    ret_from_kernel_thread
+ret_from_kernel_thread:
+       mov     $17, $16
+       jsr     $26, schedule_tail
+       mov     $9, $27
+       mov     $10, $16
+       jsr     $26, ($9)
        ldgp    $gp, 0($26)
        mov     $0, $16
        mov     $31, $26
        jmp     $31, sys_exit
+.end ret_from_kernel_thread
 
-1:     ret                     /* in parent.  */
-
-       .align 4
-2:     /* Fake a system call stack frame, as we can't do system calls
-          from kernel space.  Note that we store FN and ARG as they
-          need to be set up in the child for the call.  Also store $8
-          and $26 for use in the parent.  */
-       stq     $31, SP_OFF($sp)        /* ps */
-       stq     $1, SP_OFF+8($sp)       /* pc */
-       stq     $gp, SP_OFF+16($sp)     /* gp */
-       stq     $16, 136($sp)           /* $27; FN for child */
-       stq     $17, SP_OFF+24($sp)     /* $16; ARG for child */
-       stq     $8, 64($sp)             /* $8 */
-       stq     $26, 128($sp)           /* $26 */
+       .globl  ret_from_kernel_execve
+       .align  4
+       .ent    ret_from_kernel_execve
+ret_from_kernel_execve:
+       mov     $16, $sp
        /* Avoid the HAE being gratuitously wrong, to avoid restoring it.  */
        ldq     $2, alpha_mv+HAE_CACHE
        stq     $2, 152($sp)            /* HAE */
+       mov     $31, $19                /* to disable syscall restarts */
+       br      $31, ret_to_user
 
-       /* Shuffle FLAGS to the front; add CLONE_VM.  */
-       ldi     $1, CLONE_VM|CLONE_UNTRACED
-       or      $18, $1, $16
-       bsr     $26, sys_clone
-
-       /* We don't actually care for a3 success widgetry in the kernel.
-          Not for positive errno values.  */
-       stq     $0, 0($sp)              /* $0 */
-       br      ret_to_kernel
-.end kernel_thread
+.end   ret_from_kernel_execve
 
 \f
 /*
@@ -722,7 +697,7 @@ sys_sigreturn:
        lda     $sp, -SWITCH_STACK_SIZE($sp)
        jsr     $26, do_sigreturn
        bne     $9, 1f
-       jsr     $26, syscall_trace
+       jsr     $26, syscall_trace_leave
 1:     br      $1, undo_switch_stack
        br      ret_from_sys_call
 .end sys_sigreturn
@@ -739,20 +714,11 @@ sys_rt_sigreturn:
        lda     $sp, -SWITCH_STACK_SIZE($sp)
        jsr     $26, do_rt_sigreturn
        bne     $9, 1f
-       jsr     $26, syscall_trace
+       jsr     $26, syscall_trace_leave
 1:     br      $1, undo_switch_stack
        br      ret_from_sys_call
 .end sys_rt_sigreturn
 
-       .align  4
-       .globl  sys_execve
-       .ent    sys_execve
-sys_execve:
-       .prologue 0
-       mov     $sp, $19
-       jmp     $31, do_sys_execve
-.end sys_execve
-
        .align  4
        .globl  alpha_ni_syscall
        .ent    alpha_ni_syscall
index 83638aa096d562d803a8ffb3632dbb971db6da3d..4054e0ffe2b25a1055deb3946167755dc73fb201 100644 (file)
@@ -263,33 +263,35 @@ alpha_vfork(struct pt_regs *regs)
 
 /*
  * Copy an alpha thread..
- *
- * Note the "stack_offset" stuff: when returning to kernel mode, we need
- * to have some extra stack-space for the kernel stack that still exists
- * after the "ret_from_fork".  When returning to user mode, we only want
- * the space needed by the syscall stack frame (ie "struct pt_regs").
- * Use the passed "regs" pointer to determine how much space we need
- * for a kernel fork().
  */
 
 int
 copy_thread(unsigned long clone_flags, unsigned long usp,
-           unsigned long unused,
+           unsigned long arg,
            struct task_struct * p, struct pt_regs * regs)
 {
        extern void ret_from_fork(void);
+       extern void ret_from_kernel_thread(void);
 
        struct thread_info *childti = task_thread_info(p);
-       struct pt_regs * childregs;
-       struct switch_stack * childstack, *stack;
-       unsigned long stack_offset, settls;
-
-       stack_offset = PAGE_SIZE - sizeof(struct pt_regs);
-       if (!(regs->ps & 8))
-               stack_offset = (PAGE_SIZE-1) & (unsigned long) regs;
-       childregs = (struct pt_regs *)
-         (stack_offset + PAGE_SIZE + task_stack_page(p));
-               
+       struct pt_regs *childregs = task_pt_regs(p);
+       struct switch_stack *childstack, *stack;
+       unsigned long settls;
+
+       childstack = ((struct switch_stack *) childregs) - 1;
+       if (unlikely(!regs)) {
+               /* kernel thread */
+               memset(childstack, 0,
+                       sizeof(struct switch_stack) + sizeof(struct pt_regs));
+               childstack->r26 = (unsigned long) ret_from_kernel_thread;
+               childstack->r9 = usp;   /* function */
+               childstack->r10 = arg;
+               childregs->hae = alpha_mv.hae_cache,
+               childti->pcb.usp = 0;
+               childti->pcb.ksp = (unsigned long) childstack;
+               childti->pcb.flags = 1; /* set FEN, clear everything else */
+               return 0;
+       }
        *childregs = *regs;
        settls = regs->r20;
        childregs->r0 = 0;
@@ -297,7 +299,6 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
        childregs->r20 = 1;     /* OSF/1 has some strange fork() semantics.  */
        regs->r20 = 0;
        stack = ((struct switch_stack *) regs) - 1;
-       childstack = ((struct switch_stack *) childregs) - 1;
        *childstack = *stack;
        childstack->r26 = (unsigned long) ret_from_fork;
        childti->pcb.usp = usp;
@@ -385,27 +386,6 @@ dump_elf_task_fp(elf_fpreg_t *dest, struct task_struct *task)
 }
 EXPORT_SYMBOL(dump_elf_task_fp);
 
-/*
- * sys_execve() executes a new program.
- */
-asmlinkage int
-do_sys_execve(const char __user *ufilename,
-             const char __user *const __user *argv,
-             const char __user *const __user *envp, struct pt_regs *regs)
-{
-       int error;
-       char *filename;
-
-       filename = getname(ufilename);
-       error = PTR_ERR(filename);
-       if (IS_ERR(filename))
-               goto out;
-       error = do_execve(filename, argv, envp, regs);
-       putname(filename);
-out:
-       return error;
-}
-
 /*
  * Return saved PC of a blocked thread.  This assumes the frame
  * pointer is the 6th saved long on the kernel stack and that the
@@ -459,22 +439,3 @@ get_wchan(struct task_struct *p)
        }
        return pc;
 }
-
-int kernel_execve(const char *path, const char *const argv[], const char *const envp[])
-{
-       /* Avoid the HAE being gratuitously wrong, which would cause us
-          to do the whole turn off interrupts thing and restore it.  */
-       struct pt_regs regs = {.hae = alpha_mv.hae_cache};
-       int err = do_execve(path, argv, envp, &regs);
-       if (!err) {
-               struct pt_regs *p = current_pt_regs();
-               /* copy regs to normal position and off to userland we go... */
-               *p = regs;
-               __asm__ __volatile__ (
-                       "mov    %0, $sp;"
-                       "br     $31, ret_from_sys_call"
-                       : : "r"(p));
-       }
-       return err;
-}
-EXPORT_SYMBOL(kernel_execve);
index 54616f496aedb27629d298329a43ff8447113300..2a4a80ff4a2064262ea04298dee0a3d6e12f66be 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/user.h>
 #include <linux/security.h>
 #include <linux/signal.h>
+#include <linux/tracehook.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
@@ -312,25 +313,18 @@ long arch_ptrace(struct task_struct *child, long request,
        return ret;
 }
 
+asmlinkage unsigned long syscall_trace_enter(void)
+{
+       unsigned long ret = 0;
+       if (test_thread_flag(TIF_SYSCALL_TRACE) &&
+           tracehook_report_syscall_entry(current_pt_regs()))
+               ret = -1UL;
+       return ret ?: current_pt_regs()->r0;
+}
+
 asmlinkage void
-syscall_trace(void)
+syscall_trace_leave(void)
 {
-       if (!test_thread_flag(TIF_SYSCALL_TRACE))
-               return;
-       if (!(current->ptrace & PT_PTRACED))
-               return;
-       /* The 0x80 provides a way for the tracing parent to distinguish
-          between a syscall stop and SIGTRAP delivery */
-       ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
-                                ? 0x80 : 0));
-
-       /*
-        * This isn't the same as continuing with a signal, but it will do
-        * for normal use.  strace only continues with a signal if the
-        * stopping signal is not SIGTRAP.  -brl
-        */
-       if (current->exit_code) {
-               send_sig(current->exit_code, current, 1);
-               current->exit_code = 0;
-       }
+       if (test_thread_flag(TIF_SYSCALL_TRACE))
+               tracehook_report_syscall_exit(current_pt_regs(), 0);
 }
index 6434a3ca79e5e3d8c6b9c39cd6470a2ff61bae89..e85f2b635bc37d7f15523bca0c661d131dd690ac 100644 (file)
@@ -52,6 +52,7 @@ config ARM
        select DCACHE_WORD_ACCESS if (CPU_V6 || CPU_V6K || CPU_V7) && !CPU_BIG_ENDIAN
        select HAVE_MOD_ARCH_SPECIFIC if ARM_UNWIND
        select MODULES_USE_ELF_REL
+       select GENERIC_KERNEL_THREAD
        help
          The ARM series is a line of low-power-consumption RISC chip designs
          licensed by ARM Ltd and targeted at embedded applications and
index 99afa7498260cdad985eaf9c74fd713095dd09f6..06e7d509eaac218864cc9d089ce9e6f4177c22f9 100644 (file)
@@ -85,11 +85,6 @@ unsigned long get_wchan(struct task_struct *p);
 #define cpu_relax()                    barrier()
 #endif
 
-/*
- * Create a new kernel thread
- */
-extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
-
 #define task_pt_regs(p) \
        ((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1)
 
index 91ef6c231c478901f4c0fc39369ea158100b9f64..142d6ae4123150453d99aa9566767555afaa76f4 100644 (file)
@@ -255,6 +255,11 @@ static inline unsigned long user_stack_pointer(struct pt_regs *regs)
        return regs->ARM_sp;
 }
 
+#define current_pt_regs(void) ({                               \
+       register unsigned long sp asm ("sp");                   \
+       (struct pt_regs *)((sp | (THREAD_SIZE - 1)) - 7) - 1;   \
+})
+
 #endif /* __KERNEL__ */
 
 #endif /* __ASSEMBLY__ */
index 74542c52f9befa1d5f614b3d223291f0d4a0d2c4..368165e33c1ce5f012c3a7ee29b253a66f7c07e1 100644 (file)
@@ -2,7 +2,6 @@
 #include <asm/barrier.h>
 #include <asm/compiler.h>
 #include <asm/cmpxchg.h>
-#include <asm/exec.h>
 #include <asm/switch_to.h>
 #include <asm/system_info.h>
 #include <asm/system_misc.h>
index f71cdab18b87589beb5d4df33bcae80483e71536..8477b4c1d39fb3fe43c21691d1ad46846a947e89 100644 (file)
@@ -151,7 +151,6 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *,
 #define TIF_SYSCALL_TRACE      8
 #define TIF_SYSCALL_AUDIT      9
 #define TIF_SYSCALL_TRACEPOINT 10
-#define TIF_POLLING_NRFLAG     16
 #define TIF_USING_IWMMXT       17
 #define TIF_MEMDIE             18      /* is terminating due to OOM killer */
 #define TIF_RESTORE_SIGMASK    20
@@ -164,7 +163,6 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *,
 #define _TIF_SYSCALL_TRACE     (1 << TIF_SYSCALL_TRACE)
 #define _TIF_SYSCALL_AUDIT     (1 << TIF_SYSCALL_AUDIT)
 #define _TIF_SYSCALL_TRACEPOINT        (1 << TIF_SYSCALL_TRACEPOINT)
-#define _TIF_POLLING_NRFLAG    (1 << TIF_POLLING_NRFLAG)
 #define _TIF_USING_IWMMXT      (1 << TIF_USING_IWMMXT)
 #define _TIF_SECCOMP           (1 << TIF_SECCOMP)
 
index d9ff5cc3a5060177be581772cf22ead601ad4f65..f259921edfe9a124ee68169a3455f35b45cdde8f 100644 (file)
 #define __ARCH_WANT_OLD_READDIR
 #define __ARCH_WANT_SYS_SOCKETCALL
 #endif
+#define __ARCH_WANT_SYS_EXECVE
+#define __ARCH_WANT_KERNEL_EXECVE
 
 /*
  * "Conditional" syscalls
index e337879595e565e5666cbd8ac0c40a4a72908c0e..831cd38c8d997b32f895fa077f3745c08879d99d 100644 (file)
@@ -20,7 +20,7 @@
                CALL(sys_creat)
                CALL(sys_link)
 /* 10 */       CALL(sys_unlink)
-               CALL(sys_execve_wrapper)
+               CALL(sys_execve)
                CALL(sys_chdir)
                CALL(OBSOLETE(sys_time))        /* used by libc4 */
                CALL(sys_mknod)
index f45987037bf1c4467396799a117245cfede3d0d1..e340fa1db203ea0dd5d78ca9a2e19e7cacf2395e 100644 (file)
@@ -91,6 +91,30 @@ ENTRY(ret_from_fork)
        b       ret_slow_syscall
 ENDPROC(ret_from_fork)
 
+ENTRY(ret_from_kernel_thread)
+ UNWIND(.fnstart)
+ UNWIND(.cantunwind)
+       bl      schedule_tail
+       mov     r0, r4
+       adr     lr, BSYM(1f)    @ kernel threads should not exit
+       mov     pc, r5
+1:     bl      do_exit
+       nop
+ UNWIND(.fnend)
+ENDPROC(ret_from_kernel_thread)
+
+/*
+ * turn a kernel thread into userland process
+ * use: ret_from_kernel_execve(struct pt_regs *normal)
+ */
+ENTRY(ret_from_kernel_execve)
+       mov     why, #0                 @ not a syscall
+       str     why, [r0, #S_R0]        @ ... and we want 0 in ->ARM_r0 as well
+       get_thread_info tsk             @ thread structure
+       mov     sp, r0                  @ stack pointer just under pt_regs
+       b       ret_slow_syscall
+ENDPROC(ret_from_kernel_execve)
+
        .equ NR_syscalls,0
 #define CALL(x) .equ NR_syscalls,NR_syscalls+1
 #include "calls.S"
@@ -517,11 +541,6 @@ sys_vfork_wrapper:
                b       sys_vfork
 ENDPROC(sys_vfork_wrapper)
 
-sys_execve_wrapper:
-               add     r3, sp, #S_OFF
-               b       sys_execve
-ENDPROC(sys_execve_wrapper)
-
 sys_clone_wrapper:
                add     ip, sp, #S_OFF
                str     ip, [sp, #4]
index 04eea22d7958637f17456c7e2f37ac7b71e8e182..f98c17ff1957cc921c1e7a7459802f03e539a8de 100644 (file)
@@ -373,6 +373,7 @@ void release_thread(struct task_struct *dead_task)
 }
 
 asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
+asmlinkage void ret_from_kernel_thread(void) __asm__("ret_from_kernel_thread");
 
 int
 copy_thread(unsigned long clone_flags, unsigned long stack_start,
@@ -381,13 +382,20 @@ copy_thread(unsigned long clone_flags, unsigned long stack_start,
        struct thread_info *thread = task_thread_info(p);
        struct pt_regs *childregs = task_pt_regs(p);
 
-       *childregs = *regs;
-       childregs->ARM_r0 = 0;
-       childregs->ARM_sp = stack_start;
-
        memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save));
+
+       if (likely(regs)) {
+               *childregs = *regs;
+               childregs->ARM_r0 = 0;
+               childregs->ARM_sp = stack_start;
+               thread->cpu_context.pc = (unsigned long)ret_from_fork;
+       } else {
+               thread->cpu_context.r4 = stk_sz;
+               thread->cpu_context.r5 = stack_start;
+               thread->cpu_context.pc = (unsigned long)ret_from_kernel_thread;
+               childregs->ARM_cpsr = SVC_MODE;
+       }
        thread->cpu_context.sp = (unsigned long)childregs;
-       thread->cpu_context.pc = (unsigned long)ret_from_fork;
 
        clear_ptrace_hw_breakpoint(p);
 
@@ -423,63 +431,6 @@ int dump_fpu (struct pt_regs *regs, struct user_fp *fp)
 }
 EXPORT_SYMBOL(dump_fpu);
 
-/*
- * Shuffle the argument into the correct register before calling the
- * thread function.  r4 is the thread argument, r5 is the pointer to
- * the thread function, and r6 points to the exit function.
- */
-extern void kernel_thread_helper(void);
-asm(   ".pushsection .text\n"
-"      .align\n"
-"      .type   kernel_thread_helper, #function\n"
-"kernel_thread_helper:\n"
-#ifdef CONFIG_TRACE_IRQFLAGS
-"      bl      trace_hardirqs_on\n"
-#endif
-"      msr     cpsr_c, r7\n"
-"      mov     r0, r4\n"
-"      mov     lr, r6\n"
-"      mov     pc, r5\n"
-"      .size   kernel_thread_helper, . - kernel_thread_helper\n"
-"      .popsection");
-
-#ifdef CONFIG_ARM_UNWIND
-extern void kernel_thread_exit(long code);
-asm(   ".pushsection .text\n"
-"      .align\n"
-"      .type   kernel_thread_exit, #function\n"
-"kernel_thread_exit:\n"
-"      .fnstart\n"
-"      .cantunwind\n"
-"      bl      do_exit\n"
-"      nop\n"
-"      .fnend\n"
-"      .size   kernel_thread_exit, . - kernel_thread_exit\n"
-"      .popsection");
-#else
-#define kernel_thread_exit     do_exit
-#endif
-
-/*
- * Create a kernel thread.
- */
-pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
-{
-       struct pt_regs regs;
-
-       memset(&regs, 0, sizeof(regs));
-
-       regs.ARM_r4 = (unsigned long)arg;
-       regs.ARM_r5 = (unsigned long)fn;
-       regs.ARM_r6 = (unsigned long)kernel_thread_exit;
-       regs.ARM_r7 = SVC_MODE | PSR_ENDSTATE | PSR_ISETSTATE;
-       regs.ARM_pc = (unsigned long)kernel_thread_helper;
-       regs.ARM_cpsr = regs.ARM_r7 | PSR_I_BIT;
-
-       return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
-}
-EXPORT_SYMBOL(kernel_thread);
-
 unsigned long get_wchan(struct task_struct *p)
 {
        struct stackframe frame;
index f27789e4e38aaad749e05426d042cffe7912b5c7..56f72d257ebdfcdfd8607fcc770eeecc61c24806 100644 (file)
@@ -10,7 +10,6 @@
 #include <linux/errno.h>
 #include <linux/signal.h>
 #include <linux/personality.h>
-#include <linux/freezer.h>
 #include <linux/uaccess.h>
 #include <linux/tracehook.h>
 
index 76cbb055dd05ee2e8620bc1a3f1dc322f1333aeb..c2a898aa57aada4b16cff08ea6da84d797f88ab9 100644 (file)
@@ -59,69 +59,6 @@ asmlinkage int sys_vfork(struct pt_regs *regs)
        return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->ARM_sp, regs, 0, NULL, NULL);
 }
 
-/* sys_execve() executes a new program.
- * This is called indirectly via a small wrapper
- */
-asmlinkage int sys_execve(const char __user *filenamei,
-                         const char __user *const __user *argv,
-                         const char __user *const __user *envp, struct pt_regs *regs)
-{
-       int error;
-       char * filename;
-
-       filename = getname(filenamei);
-       error = PTR_ERR(filename);
-       if (IS_ERR(filename))
-               goto out;
-       error = do_execve(filename, argv, envp, regs);
-       putname(filename);
-out:
-       return error;
-}
-
-int kernel_execve(const char *filename,
-                 const char *const argv[],
-                 const char *const envp[])
-{
-       struct pt_regs regs;
-       int ret;
-
-       memset(&regs, 0, sizeof(struct pt_regs));
-       ret = do_execve(filename,
-                       (const char __user *const __user *)argv,
-                       (const char __user *const __user *)envp, &regs);
-       if (ret < 0)
-               goto out;
-
-       /*
-        * Save argc to the register structure for userspace.
-        */
-       regs.ARM_r0 = ret;
-
-       /*
-        * We were successful.  We won't be returning to our caller, but
-        * instead to user space by manipulating the kernel stack.
-        */
-       asm(    "add    r0, %0, %1\n\t"
-               "mov    r1, %2\n\t"
-               "mov    r2, %3\n\t"
-               "bl     memmove\n\t"    /* copy regs to top of stack */
-               "mov    r8, #0\n\t"     /* not a syscall */
-               "mov    r9, %0\n\t"     /* thread structure */
-               "mov    sp, r0\n\t"     /* reposition stack pointer */
-               "b      ret_to_user"
-               :
-               : "r" (current_thread_info()),
-                 "Ir" (THREAD_START_SP - sizeof(regs)),
-                 "r" (&regs),
-                 "Ir" (sizeof(regs))
-               : "r0", "r1", "r2", "r3", "r8", "r9", "ip", "lr", "memory");
-
- out:
-       return ret;
-}
-EXPORT_SYMBOL(kernel_execve);
-
 /*
  * Since loff_t is a 64 bit type we avoid a lot of ABI hassle
  * with a different argument ordering.
index 3136628ba8d20feba7de4ed07a51261a65c4a3b2..aa47fff70760b4fd0e4a2cf21521483fb4a00a13 100644 (file)
@@ -1,3 +1,4 @@
 include include/asm-generic/Kbuild.asm
 
+generic-y      += exec.h
 header-y       += cachectl.h
diff --git a/arch/avr32/include/asm/exec.h b/arch/avr32/include/asm/exec.h
deleted file mode 100644 (file)
index f467be8..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * Copyright (C) 2004-2006 Atmel Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#ifndef __ASM_AVR32_EXEC_H
-#define __ASM_AVR32_EXEC_H
-
-#define arch_align_stack(x)    (x)
-
-#endif /* __ASM_AVR32_EXEC_H */
index e5deda4691db248781f0d127ca4b383cea4b794d..6dc62e1f94c7801532c9a3bc0be13abe3f8009e4 100644 (file)
@@ -77,8 +77,6 @@ static inline struct thread_info *current_thread_info(void)
 #define TIF_SYSCALL_TRACE       0       /* syscall trace active */
 #define TIF_SIGPENDING          1       /* signal pending */
 #define TIF_NEED_RESCHED        2       /* rescheduling necessary */
-#define TIF_POLLING_NRFLAG      3       /* true if poll_idle() is polling
-                                          TIF_NEED_RESCHED */
 #define TIF_BREAKPOINT         4       /* enter monitor mode on return */
 #define TIF_SINGLE_STEP                5       /* single step in progress */
 #define TIF_MEMDIE             6       /* is terminating due to OOM killer */
@@ -91,10 +89,9 @@ static inline struct thread_info *current_thread_info(void)
 #define _TIF_SYSCALL_TRACE     (1 << TIF_SYSCALL_TRACE)
 #define _TIF_SIGPENDING                (1 << TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED      (1 << TIF_NEED_RESCHED)
-#define _TIF_POLLING_NRFLAG    (1 << TIF_POLLING_NRFLAG)
+#define _TIF_BREAKPOINT                (1 << TIF_BREAKPOINT)
 #define _TIF_SINGLE_STEP       (1 << TIF_SINGLE_STEP)
 #define _TIF_MEMDIE            (1 << TIF_MEMDIE)
-#define _TIF_RESTORE_SIGMASK   (1 << TIF_RESTORE_SIGMASK)
 #define _TIF_CPU_GOING_TO_SLEEP (1 << TIF_CPU_GOING_TO_SLEEP)
 #define _TIF_NOTIFY_RESUME     (1 << TIF_NOTIFY_RESUME)
 
@@ -102,17 +99,14 @@ static inline struct thread_info *current_thread_info(void)
 
 /* work to do on interrupt/exception return */
 #define _TIF_WORK_MASK                         \
-       ((1 << TIF_SIGPENDING)                  \
+       (_TIF_SIGPENDING                        \
         | _TIF_NOTIFY_RESUME                   \
-        | (1 << TIF_NEED_RESCHED)              \
-        | (1 << TIF_POLLING_NRFLAG)            \
-        | (1 << TIF_BREAKPOINT)                \
-        | (1 << TIF_RESTORE_SIGMASK))
+        | _TIF_NEED_RESCHED                    \
+        | _TIF_BREAKPOINT)
 
 /* work to do on any return to userspace */
-#define _TIF_ALLWORK_MASK      (_TIF_WORK_MASK | (1 << TIF_SYSCALL_TRACE) | \
-                                _TIF_NOTIFY_RESUME)
+#define _TIF_ALLWORK_MASK      (_TIF_WORK_MASK | _TIF_SYSCALL_TRACE)
 /* work to do on return from debug mode */
-#define _TIF_DBGWORK_MASK      (_TIF_WORK_MASK & ~(1 << TIF_BREAKPOINT))
+#define _TIF_DBGWORK_MASK      (_TIF_WORK_MASK & ~_TIF_BREAKPOINT)
 
 #endif /* __ASM_AVR32_THREAD_INFO_H */
index d552a854dacccbbc8b5f8131bbdaa2203ffb74fa..5e01c3a40cedfbbd607ce6d23a8477e9bd9da470 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/errno.h>
 #include <linux/ptrace.h>
 #include <linux/unistd.h>
-#include <linux/freezer.h>
 #include <linux/tracehook.h>
 
 #include <asm/uaccess.h>
index 53ad10005ae37db4fbf6c3d6cb21eee6485b8db6..3894005337ba7d8628de4f7de2f9f7dd8f5b603d 100644 (file)
@@ -96,8 +96,6 @@ static inline struct thread_info *current_thread_info(void)
 #define TIF_SYSCALL_TRACE      0       /* syscall trace active */
 #define TIF_SIGPENDING         1       /* signal pending */
 #define TIF_NEED_RESCHED       2       /* rescheduling necessary */
-#define TIF_POLLING_NRFLAG     3       /* true if poll_idle() is polling
-                                          TIF_NEED_RESCHED */
 #define TIF_MEMDIE             4       /* is terminating due to OOM killer */
 #define TIF_RESTORE_SIGMASK    5       /* restore signal mask in do_signal() */
 #define TIF_IRQ_SYNC           7       /* sync pipeline stage */
@@ -108,8 +106,6 @@ static inline struct thread_info *current_thread_info(void)
 #define _TIF_SYSCALL_TRACE     (1<<TIF_SYSCALL_TRACE)
 #define _TIF_SIGPENDING                (1<<TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED      (1<<TIF_NEED_RESCHED)
-#define _TIF_POLLING_NRFLAG    (1<<TIF_POLLING_NRFLAG)
-#define _TIF_RESTORE_SIGMASK   (1<<TIF_RESTORE_SIGMASK)
 #define _TIF_IRQ_SYNC          (1<<TIF_IRQ_SYNC)
 #define _TIF_NOTIFY_RESUME     (1<<TIF_NOTIFY_RESUME)
 #define _TIF_SINGLESTEP                (1<<TIF_SINGLESTEP)
index 6682b73a8523f789bf2e3fa722f068f1ef4ebf79..6ed20a1a4af9619951e560f2de692b15b6f850ba 100644 (file)
@@ -10,7 +10,6 @@
 #include <linux/tty.h>
 #include <linux/personality.h>
 #include <linux/binfmts.h>
-#include <linux/freezer.h>
 #include <linux/uaccess.h>
 #include <linux/tracehook.h>
 
index f6a3648f5ec3c7030a8c4294be4e3bee54a25b6c..20ef56e467b364d930ed42749f22ebb97eeaba2f 100644 (file)
@@ -18,6 +18,7 @@ config C6X
        select OF_EARLY_FLATTREE
        select GENERIC_CLOCKEVENTS
        select MODULES_USE_ELF_RELA
+       select GENERIC_KERNEL_THREAD
 
 config MMU
        def_bool n
index f08e89183cda452844fda74bc27a4db8823647d1..91d6f879bb0bf538edbe21c2b7057e3d32f9c88b 100644 (file)
@@ -12,6 +12,7 @@ generic-y += div64.h
 generic-y += dma.h
 generic-y += emergency-restart.h
 generic-y += errno.h
+generic-y += exec.h
 generic-y += fb.h
 generic-y += fcntl.h
 generic-y += futex.h
diff --git a/arch/c6x/include/asm/exec.h b/arch/c6x/include/asm/exec.h
deleted file mode 100644 (file)
index 0fea482..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _ASM_C6X_EXEC_H
-#define _ASM_C6X_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* _ASM_C6X_EXEC_H */
index c50af7ef1c96a5538252474e6ab37681141583a5..b9eb3da7f278dac858bfb2191094f9fc837ac5c8 100644 (file)
@@ -92,8 +92,6 @@ static inline void release_thread(struct task_struct *dead_task)
 {
 }
 
-extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-
 #define copy_segments(tsk, mm)         do { } while (0)
 #define release_segments(mm)           do { } while (0)
 
index aed53da703c9ae7bb3b78e1b2d285fefd4ecaa0d..e7b8991dc07c69c25425fce66c16306dcede12d1 100644 (file)
@@ -44,11 +44,6 @@ extern int sys_cache_sync(unsigned long s, unsigned long e);
 struct pt_regs;
 
 extern asmlinkage long sys_c6x_clone(struct pt_regs *regs);
-extern asmlinkage long sys_c6x_execve(const char __user *name,
-                                     const char __user *const __user *argv,
-                                     const char __user *const __user *envp,
-                                     struct pt_regs *regs);
-
 
 #include <asm-generic/syscalls.h>
 
index 1710bcbb8d093bda2965d4d7e3c779963eeb6f7f..4c8dc562bd90dce27d0236140434a34120fe33d7 100644 (file)
@@ -97,7 +97,6 @@ struct thread_info *current_thread_info(void)
 #define TIF_NEED_RESCHED       3       /* rescheduling necessary */
 #define TIF_RESTORE_SIGMASK    4       /* restore signal mask in do_signal() */
 
-#define TIF_POLLING_NRFLAG     16      /* true if polling TIF_NEED_RESCHED */
 #define TIF_MEMDIE             17      /* OOM killer killed process */
 
 #define TIF_WORK_MASK          0x00007FFE /* work on irq/exception return */
index 6d54ea4262eb6e538c0c9a55dd513d23578c7360..3c131d5888c11253cabb21cce01edbc2df28e25c 100644 (file)
@@ -16,6 +16,9 @@
 #if !defined(_ASM_C6X_UNISTD_H) || defined(__SYSCALL)
 #define _ASM_C6X_UNISTD_H
 
+#define __ARCH_WANT_KERNEL_EXECVE
+#define __ARCH_WANT_SYS_EXECVE
+
 /* Use the standard ABI for syscalls. */
 #include <asm-generic/unistd.h>
 
index 759ad6d207b620eacd90ce906132492ac1a5ec1e..60f1e437745dd2f60eb5bf5a9c9c2c92326e6b1c 100644 (file)
@@ -116,7 +116,6 @@ void foo(void)
        DEFINE(_TIF_NOTIFY_RESUME, (1<<TIF_NOTIFY_RESUME));
        DEFINE(_TIF_SIGPENDING, (1<<TIF_SIGPENDING));
        DEFINE(_TIF_NEED_RESCHED, (1<<TIF_NEED_RESCHED));
-       DEFINE(_TIF_POLLING_NRFLAG, (1<<TIF_POLLING_NRFLAG));
 
        DEFINE(_TIF_ALLWORK_MASK, TIF_ALLWORK_MASK);
        DEFINE(_TIF_WORK_MASK, TIF_WORK_MASK);
index 30b37e5f4a6110aa9f00a58dc4ca5cf97c7327db..5449c36018fe2d269b2daaa162a25a39bfa53c9b 100644 (file)
@@ -400,6 +400,32 @@ ret_from_fork_2:
        STW     .D2T2   B0,*+SP(REGS_A4+8)
 ENDPROC(ret_from_fork)
 
+ENTRY(ret_from_kernel_thread)
+#ifdef CONFIG_C6X_BIG_KERNEL
+       MVKL    .S1     schedule_tail,A0
+       MVKH    .S1     schedule_tail,A0
+       B       .S2X    A0
+#else
+       B       .S2     schedule_tail
+#endif
+       LDW     .D2T2   *+SP(REGS_A0+8),B10 /* get fn  */
+       ADDKPC  .S2     0f,B3,3
+0:
+       B       .S2     B10                /* call fn */
+       LDW     .D2T1   *+SP(REGS_A1+8),A4 /* get arg */
+       MVKL    .S2     sys_exit,B11
+       MVKH    .S2     sys_exit,B11
+       ADDKPC  .S2     0f,B3,1
+0:
+       BNOP    .S2     B11,5   /* jump to sys_exit */
+ENDPROC(ret_from_kernel_thread)
+
+ENTRY(ret_from_kernel_execve)
+       GET_THREAD_INFO A12
+       BNOP    .S2     syscall_exit,4
+       ADD     .D2X    A4,-8,SP
+ENDPROC(ret_from_kernel_execve)
+
        ;;
        ;; These are the interrupt handlers, responsible for calling __do_IRQ()
        ;; int6 is used for syscalls (see _system_call entry)
@@ -593,13 +619,6 @@ ENTRY(sys_sigaltstack)
        NOP     4
 ENDPROC(sys_sigaltstack)
 
-       ;; kernel_execve
-ENTRY(kernel_execve)
-       MVK     .S2     __NR_execve,B0
-       SWE
-       BNOP    .S2     B3,5
-ENDPROC(kernel_execve)
-
        ;;
        ;; Special system calls
        ;; return address is in B3
@@ -628,29 +647,6 @@ ENTRY(sys_rt_sigreturn)
 #endif
 ENDPROC(sys_rt_sigreturn)
 
-ENTRY(sys_execve)
-       ADDAW   .D2     SP,2,B6         ; put regs addr in 4th parameter
-                                       ; & adjust regs stack addr
-       LDW     .D2T2   *+SP(REGS_B4+8),B4
-
-       ;; c6x_execve(char *name, char **argv,
-       ;;            char **envp, struct pt_regs *regs)
-#ifdef CONFIG_C6X_BIG_KERNEL
- ||    MVKL    .S1     sys_c6x_execve,A0
-       MVKH    .S1     sys_c6x_execve,A0
-       B       .S2X    A0
-#else
- ||    B       .S2     sys_c6x_execve
-#endif
-       STW     .D2T2   B3,*SP--[2]
-       ADDKPC  .S2     ret_from_c6x_execve,B3,3
-
-ret_from_c6x_execve:
-       LDW     .D2T2   *++SP[2],B3
-       NOP     4
-       BNOP    .S2     B3,5
-ENDPROC(sys_execve)
-
 ENTRY(sys_pread_c6x)
        MV      .D2X    A8,B7
 #ifdef CONFIG_C6X_BIG_KERNEL
index 45e924a636a0c6772f0ae31cc27599d31ba437c7..2770d9a9a84edbc4d66b9cbae3e39aff8f001d38 100644 (file)
@@ -25,6 +25,7 @@ void  (*c6x_restart)(void);
 void   (*c6x_halt)(void);
 
 extern asmlinkage void ret_from_fork(void);
+extern asmlinkage void ret_from_kernel_thread(void);
 
 /*
  * power off function, if any
@@ -103,37 +104,6 @@ void machine_power_off(void)
        halt_loop();
 }
 
-static void kernel_thread_helper(int dummy, void *arg, int (*fn)(void *))
-{
-       do_exit(fn(arg));
-}
-
-/*
- * Create a kernel thread
- */
-int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
-{
-       struct pt_regs regs;
-
-       /*
-        * copy_thread sets a4 to zero (child return from fork)
-        * so we can't just set things up to directly return to
-        * fn.
-        */
-       memset(&regs, 0, sizeof(regs));
-       regs.b4 = (unsigned long) arg;
-       regs.a6 = (unsigned long) fn;
-       regs.pc = (unsigned long) kernel_thread_helper;
-       local_save_flags(regs.csr);
-       regs.csr |= 1;
-       regs.tsr = 5; /* Set GEE and GIE in TSR */
-
-       /* Ok, create the new process.. */
-       return do_fork(flags | CLONE_VM | CLONE_UNTRACED, -1, &regs,
-                      0, NULL, NULL);
-}
-EXPORT_SYMBOL(kernel_thread);
-
 void flush_thread(void)
 {
 }
@@ -191,22 +161,24 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
 
        childregs = task_pt_regs(p);
 
-       *childregs = *regs;
-       childregs->a4 = 0;
-
-       if (usp == -1)
+       if (!regs) {
                /* case of  __kernel_thread: we return to supervisor space */
+               memset(childregs, 0, sizeof(struct pt_regs));
                childregs->sp = (unsigned long)(childregs + 1);
-       else
+               p->thread.pc = (unsigned long) ret_from_kernel_thread;
+               childregs->a0 = usp;            /* function */
+               childregs->a1 = ustk_size;      /* argument */
+       } else {
                /* Otherwise use the given stack */
+               *childregs = *regs;
                childregs->sp = usp;
+               p->thread.pc = (unsigned long) ret_from_fork;
+       }
 
        /* Set usp/ksp */
        p->thread.usp = childregs->sp;
-       /* switch_to uses stack to save/restore 14 callee-saved regs */
        thread_saved_ksp(p) = (unsigned long)childregs - 8;
-       p->thread.pc = (unsigned int) ret_from_fork;
-       p->thread.wchan = (unsigned long) ret_from_fork;
+       p->thread.wchan = p->thread.pc;
 #ifdef __DSBT__
        {
                unsigned long dp;
@@ -221,28 +193,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
        return 0;
 }
 
-/*
- * c6x_execve() executes a new program.
- */
-SYSCALL_DEFINE4(c6x_execve, const char __user *, name,
-               const char __user *const __user *, argv,
-               const char __user *const __user *, envp,
-               struct pt_regs *, regs)
-{
-       int error;
-       char *filename;
-
-       filename = getname(name);
-       error = PTR_ERR(filename);
-       if (IS_ERR(filename))
-               goto out;
-
-       error = do_execve(filename, argv, envp, regs);
-       putname(filename);
-out:
-       return error;
-}
-
 unsigned long get_wchan(struct task_struct *p)
 {
        return p->thread.wchan;
index 28b690de797116ca4f5deb292021b75e72924e82..f5ae9de736d37f460d433548108fa59ce7168759 100644 (file)
@@ -9,3 +9,4 @@ header-y += rs485.h
 header-y += sync_serial.h
 
 generic-y += module.h
+generic-y += exec.h
diff --git a/arch/cris/include/asm/exec.h b/arch/cris/include/asm/exec.h
deleted file mode 100644 (file)
index 9665dab..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __ASM_CRIS_EXEC_H
-#define __ASM_CRIS_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* __ASM_CRIS_EXEC_H */
index 5b1c448df5c0caab0dd5e50539547cb72753b177..07c8c40c52b312ddfee756ca8ea5b0619ddb4a65 100644 (file)
@@ -78,15 +78,12 @@ struct thread_info {
 #define TIF_SIGPENDING         2       /* signal pending */
 #define TIF_NEED_RESCHED       3       /* rescheduling necessary */
 #define TIF_RESTORE_SIGMASK    9       /* restore signal mask in do_signal() */
-#define TIF_POLLING_NRFLAG     16      /* true if poll_idle() is polling TIF_NEED_RESCHED */
 #define TIF_MEMDIE             17      /* is terminating due to OOM killer */
 
 #define _TIF_SYSCALL_TRACE     (1<<TIF_SYSCALL_TRACE)
 #define _TIF_NOTIFY_RESUME     (1<<TIF_NOTIFY_RESUME)
 #define _TIF_SIGPENDING                (1<<TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED      (1<<TIF_NEED_RESCHED)
-#define _TIF_RESTORE_SIGMASK   (1<<TIF_RESTORE_SIGMASK)
-#define _TIF_POLLING_NRFLAG    (1<<TIF_POLLING_NRFLAG)
 
 #define _TIF_WORK_MASK         0x0000FFFE      /* work to do on interrupt/exception return */
 #define _TIF_ALLWORK_MASK      0x0000FFFF      /* work to do on any return to u-space */
index 971c0a19facb694706f68722645aa5101afbeea6..a27a1c6f84573257d99b019b087c37825767881e 100644 (file)
@@ -10,6 +10,7 @@ config FRV
        select ARCH_HAVE_NMI_SAFE_CMPXCHG
        select GENERIC_CPU_DEVICES
        select ARCH_WANT_IPC_PARSE_VERSION
+       select GENERIC_KERNEL_THREAD
 
 config ZONE_DMA
        bool
index 5be6663cfee5d921cf90c1fd2ad0cf730f238314..32c16468cf5e74e677edd6e014b9bd1f40b29ce8 100644 (file)
@@ -2,3 +2,4 @@ include include/asm-generic/Kbuild.asm
 
 header-y += registers.h
 header-y += termios.h
+generic-y += exec.h
diff --git a/arch/frv/include/asm/exec.h b/arch/frv/include/asm/exec.h
deleted file mode 100644 (file)
index 65c9130..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/* FR-V CPU executable handling
- *
- * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#ifndef _ASM_EXEC_H
-#define _ASM_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* _ASM_EXEC_H */
index dccb9d162318bf9d9f6d93c0ee54a9a18d0a3158..a34f309e580199b5f573db3f975a199cd74d5372 100644 (file)
@@ -92,14 +92,12 @@ extern struct task_struct *__kernel_current_task;
 
 /*
  * do necessary setup to start up a newly executed thread.
- * - need to discard the frame stacked by init() invoking the execve syscall
  */
 #define start_thread(_regs, _pc, _usp)                 \
 do {                                                   \
-       __frame = __kernel_frame0_ptr;                  \
-       __frame->pc     = (_pc);                        \
-       __frame->psr    &= ~PSR_S;                      \
-       __frame->sp     = (_usp);                       \
+       _regs->pc       = (_pc);                        \
+       _regs->psr      &= ~PSR_S;                      \
+       _regs->sp       = (_usp);                       \
 } while(0)
 
 /* Free all resources held by a thread. */
@@ -107,7 +105,6 @@ static inline void release_thread(struct task_struct *dead_task)
 {
 }
 
-extern asmlinkage int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
 extern asmlinkage void save_user_regs(struct user_context *target);
 extern asmlinkage void *restore_user_regs(const struct user_context *target, ...);
 
index ef6635ca4ecb3f73a4d7bad1cd044d9b0a1e9750..bd534b2d02583e0c3f64a7d8d97f4a2f79d7dbf4 100644 (file)
@@ -76,6 +76,7 @@ register struct pt_regs *__frame asm("gr28");
 #define user_mode(regs)                        (!((regs)->psr & PSR_S))
 #define instruction_pointer(regs)      ((regs)->pc)
 #define user_stack_pointer(regs)       ((regs)->sp)
+#define current_pt_regs()              (__frame)
 
 extern unsigned long user_stack(const struct pt_regs *);
 #define profile_pc(regs) ((regs)->pc)
index 0ff03a33c81e8b193da81f690ce94c0f0c9ad82b..bebd7eadc7720c3e3ddac4fe455a8bef37308042 100644 (file)
@@ -94,7 +94,6 @@ register struct thread_info *__current_thread_info asm("gr15");
 #define TIF_NEED_RESCHED       3       /* rescheduling necessary */
 #define TIF_SINGLESTEP         4       /* restore singlestep on return to user mode */
 #define TIF_RESTORE_SIGMASK    5       /* restore signal mask in do_signal() */
-#define TIF_POLLING_NRFLAG     6       /* true if poll_idle() is polling TIF_NEED_RESCHED */
 #define TIF_MEMDIE             7       /* is terminating due to OOM killer */
 
 #define _TIF_SYSCALL_TRACE     (1 << TIF_SYSCALL_TRACE)
@@ -102,8 +101,6 @@ register struct thread_info *__current_thread_info asm("gr15");
 #define _TIF_SIGPENDING                (1 << TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED      (1 << TIF_NEED_RESCHED)
 #define _TIF_SINGLESTEP                (1 << TIF_SINGLESTEP)
-#define _TIF_RESTORE_SIGMASK   (1 << TIF_RESTORE_SIGMASK)
-#define _TIF_POLLING_NRFLAG    (1 << TIF_POLLING_NRFLAG)
 
 /* work to do on interrupt/exception return */
 #define _TIF_WORK_MASK         \
index 67f23a311db6e3d5a55ef88b3243c7c01705b469..b6b07e55e4731fc2ba547d202657bbac98b08707 100644 (file)
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGACTION
 #define __ARCH_WANT_SYS_RT_SIGSUSPEND
+#define __ARCH_WANT_SYS_EXECVE
+#define __ARCH_WANT_KERNEL_EXECVE
 
 /*
  * "Conditional" syscalls
index ad4087b69968b051ffd557ad6cb8cd2fcc9b40fb..3cbb3294b9f9ae61022e1c38cdf5799f48e34a6e 100644 (file)
@@ -7,8 +7,8 @@ heads-$(CONFIG_MMU)             := head-mmu-fr451.o
 
 extra-y:= head.o vmlinux.lds
 
-obj-y := $(heads-y) entry.o entry-table.o break.o switch_to.o kernel_thread.o \
-        kernel_execve.o process.o traps.o ptrace.o signal.o dma.o \
+obj-y := $(heads-y) entry.o entry-table.o break.o switch_to.o \
+        process.o traps.o ptrace.o signal.o dma.o \
         sys_frv.o time.o setup.o frv_ksyms.o \
         debug-stub.o irq.o sleep.o uaccess.o
 
index 7d5e000fd32e0e4d40c78c2fcec1806f17bb1286..002732960315ee429d3cce6a95c8a0440064c64d 100644 (file)
@@ -863,6 +863,19 @@ ret_from_fork:
        setlos.p        #0,gr8
        bra             __syscall_exit
 
+       .globl          ret_from_kernel_thread
+ret_from_kernel_thread:
+       lddi.p          @(gr28,#REG_GR(8)),gr20
+       call            schedule_tail
+       or.p            gr20,gr20,gr8
+       calll           @(gr21,gr0)
+       bra             sys_exit
+
+       .globl          ret_from_kernel_execve
+ret_from_kernel_execve:
+       ori             gr28,0,sp
+       bra             __syscall_exit
+
 ###################################################################################################
 #
 # Return to user mode is not as complex as all this looks,
index a89803b58b9a970c47c0784ca1be398478de6142..86c516d96dcda69760dd5c86687e027dfadb4bed 100644 (file)
@@ -30,7 +30,6 @@ EXPORT_SYMBOL(ip_fast_csum);
 EXPORT_SYMBOL(local_irq_count);
 EXPORT_SYMBOL(local_bh_count);
 #endif
-EXPORT_SYMBOL(kernel_thread);
 
 EXPORT_SYMBOL(__res_bus_clock_speed_HZ);
 EXPORT_SYMBOL(__page_offset);
diff --git a/arch/frv/kernel/kernel_execve.S b/arch/frv/kernel/kernel_execve.S
deleted file mode 100644 (file)
index 9b074a1..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/* in-kernel program execution
- *
- * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#include <linux/linkage.h>
-#include <asm/unistd.h>
-
-###############################################################################
-#
-# Do a system call from kernel instead of calling sys_execve so we end up with
-# proper pt_regs.
-#
-# int kernel_execve(const char *filename, char *const argv[], char *const envp[])
-#
-# On entry: GR8/GR9/GR10: arguments to function
-# On return: GR8: syscall return.
-#
-###############################################################################
-       .globl          kernel_execve
-       .type           kernel_execve,@function
-kernel_execve:
-       setlos          __NR_execve,gr7
-       tira            gr0,#0
-       bralr
-
-       .size           kernel_execve,.-kernel_execve
diff --git a/arch/frv/kernel/kernel_thread.S b/arch/frv/kernel/kernel_thread.S
deleted file mode 100644 (file)
index f0e5294..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/* kernel_thread.S: kernel thread creation
- *
- * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#include <linux/linkage.h>
-#include <linux/kern_levels.h>
-#include <asm/unistd.h>
-
-#define CLONE_VM       0x00000100      /* set if VM shared between processes */
-
-       .section .rodata
-kernel_thread_emsg:
-       .asciz  KERN_ERR "failed to create kernel thread: error=%d\n"
-
-       .text
-       .balign         4
-
-###############################################################################
-#
-# Create a kernel thread
-#
-# int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
-#
-###############################################################################
-       .globl          kernel_thread
-       .type           kernel_thread,@function
-kernel_thread:
-       or.p            gr8,gr0,gr4
-       or              gr9,gr0,gr5
-
-       # start by forking the current process, but with shared VM
-       setlos.p        #__NR_clone,gr7         ; syscall number
-       ori             gr10,#CLONE_VM,gr8      ; first syscall arg     [clone_flags]
-       sethi.p         #0xe4e4,gr9             ; second syscall arg    [newsp]
-       setlo           #0xe4e4,gr9
-       setlos.p        #0,gr10                 ; third syscall arg     [parent_tidptr]
-       setlos          #0,gr11                 ; fourth syscall arg    [child_tidptr]
-       tira            gr0,#0
-       setlos.p        #4095,gr7
-       andcc           gr8,gr8,gr0,icc0
-       addcc.p         gr8,gr7,gr0,icc1
-       bnelr           icc0,#2
-       bc              icc1,#0,kernel_thread_error
-
-       # now invoke the work function
-       or              gr5,gr0,gr8
-       calll           @(gr4,gr0)
-
-       # and finally exit the thread
-       setlos          #__NR_exit,gr7          ; syscall number
-       tira            gr0,#0
-
-kernel_thread_error:
-       subi            sp,#8,sp
-       movsg           lr,gr4
-       sti             gr8,@(sp,#0)
-       sti.p           gr4,@(sp,#4)
-
-       or              gr8,gr0,gr9
-       sethi.p         %hi(kernel_thread_emsg),gr8
-       setlo           %lo(kernel_thread_emsg),gr8
-
-       call            printk
-
-       ldi             @(sp,#4),gr4
-       ldi             @(sp,#0),gr8
-       subi            sp,#8,sp
-       jmpl            @(gr4,gr0)
-
-       .size           kernel_thread,.-kernel_thread
index 2eb7fa5bf9d8d48386ea7583dd1731dd92eff7a8..655d90d20bb0cad25df015e7bdc9dee6dbf4e37b 100644 (file)
@@ -38,6 +38,7 @@
 #include "local.h"
 
 asmlinkage void ret_from_fork(void);
+asmlinkage void ret_from_kernel_thread(void);
 
 #include <asm/pgalloc.h>
 
@@ -172,32 +173,13 @@ asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
  * set up the kernel stack and exception frames for a new process
  */
 int copy_thread(unsigned long clone_flags,
-               unsigned long usp, unsigned long topstk,
+               unsigned long usp, unsigned long arg,
                struct task_struct *p, struct pt_regs *regs)
 {
-       struct pt_regs *childregs0, *childregs, *regs0;
+       struct pt_regs *childregs;
 
-       regs0 = __kernel_frame0_ptr;
-       childregs0 = (struct pt_regs *)
+       childregs = (struct pt_regs *)
                (task_stack_page(p) + THREAD_SIZE - FRV_FRAME0_SIZE);
-       childregs = childregs0;
-
-       /* set up the userspace frame (the only place that the USP is stored) */
-       *childregs0 = *regs0;
-
-       childregs0->gr8         = 0;
-       childregs0->sp          = usp;
-       childregs0->next_frame  = NULL;
-
-       /* set up the return kernel frame if called from kernel_thread() */
-       if (regs != regs0) {
-               childregs--;
-               *childregs = *regs;
-               childregs->sp = (unsigned long) childregs0;
-               childregs->next_frame = childregs0;
-               childregs->gr15 = (unsigned long) task_thread_info(p);
-               childregs->gr29 = (unsigned long) p;
-       }
 
        p->set_child_tid = p->clear_child_tid = NULL;
 
@@ -206,8 +188,25 @@ int copy_thread(unsigned long clone_flags,
        p->thread.sp     = (unsigned long) childregs;
        p->thread.fp     = 0;
        p->thread.lr     = 0;
-       p->thread.pc     = (unsigned long) ret_from_fork;
-       p->thread.frame0 = childregs0;
+       p->thread.frame0 = childregs;
+
+       if (unlikely(!regs)) {
+               memset(childregs, 0, sizeof(struct pt_regs));
+               childregs->gr9 = usp; /* function */
+               childregs->gr8 = arg;
+               chilregs->psr = PSR_S;
+               p->thread.pc = (unsigned long) ret_from_kernel_thread;
+               save_user_regs(p->thread.user);
+               return 0;
+       }
+
+       /* set up the userspace frame (the only place that the USP is stored) */
+       *childregs = *regs;
+
+       childregs->sp           = usp;
+       childregs->next_frame   = NULL;
+
+       p->thread.pc = (unsigned long) ret_from_fork;
 
        /* the new TLS pointer is passed in as arg #5 to sys_clone() */
        if (clone_flags & CLONE_SETTLS)
@@ -218,25 +217,6 @@ int copy_thread(unsigned long clone_flags,
        return 0;
 } /* end copy_thread() */
 
-/*
- * sys_execve() executes a new program.
- */
-asmlinkage int sys_execve(const char __user *name,
-                         const char __user *const __user *argv,
-                         const char __user *const __user *envp)
-{
-       int error;
-       char * filename;
-
-       filename = getname(name);
-       error = PTR_ERR(filename);
-       if (IS_ERR(filename))
-               return error;
-       error = do_execve(filename, argv, envp, __frame);
-       putname(filename);
-       return error;
-}
-
 unsigned long get_wchan(struct task_struct *p)
 {
        struct pt_regs *regs0;
index 864c2f0d497bfa62800e4168cac94215bff4d128..535810a3217a25bf64e3f5d53059f8a5ff1a7ea4 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/ptrace.h>
 #include <linux/unistd.h>
 #include <linux/personality.h>
-#include <linux/freezer.h>
 #include <linux/tracehook.h>
 #include <asm/ucontext.h>
 #include <asm/uaccess.h>
@@ -298,10 +297,6 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
        __frame->lr   = (unsigned long) &frame->retcode;
        __frame->gr8  = sig;
 
-       /* the tracer may want to single-step inside the handler */
-       if (test_thread_flag(TIF_SINGLESTEP))
-               ptrace_notify(SIGTRAP);
-
 #if DEBUG_SIG
        printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
               sig, current->comm, current->pid, frame, __frame->pc,
@@ -400,10 +395,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        __frame->gr8 = sig;
        __frame->gr9 = (unsigned long) &frame->info;
 
-       /* the tracer may want to single-step inside the handler */
-       if (test_thread_flag(TIF_SINGLESTEP))
-               ptrace_notify(SIGTRAP);
-
 #if DEBUG_SIG
        printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
               sig, current->comm, current->pid, frame, __frame->pc,
index 871382d239fef60105b37f50424afe24ed6773e3..883a0be9f69f7921b993698a576b176460bec0cd 100644 (file)
@@ -1,3 +1,4 @@
 include include/asm-generic/Kbuild.asm
 
 generic-y      += module.h
+generic-y += exec.h
diff --git a/arch/h8300/include/asm/exec.h b/arch/h8300/include/asm/exec.h
deleted file mode 100644 (file)
index c01c45c..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _H8300_EXEC_H
-#define _H8300_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* _H8300_EXEC_H */
index 9c126e0c09aa0717f4c976586440ad18d01a7232..ec2f7777c65a6c631f68fbc87733992c7b421b6e 100644 (file)
@@ -85,8 +85,6 @@ static inline struct thread_info *current_thread_info(void)
 #define TIF_SYSCALL_TRACE      0       /* syscall trace active */
 #define TIF_SIGPENDING         1       /* signal pending */
 #define TIF_NEED_RESCHED       2       /* rescheduling necessary */
-#define TIF_POLLING_NRFLAG     3       /* true if poll_idle() is polling
-                                          TIF_NEED_RESCHED */
 #define TIF_MEMDIE             4       /* is terminating due to OOM killer */
 #define TIF_RESTORE_SIGMASK    5       /* restore signal mask in do_signal() */
 #define TIF_NOTIFY_RESUME      6       /* callback before returning to user */
@@ -95,11 +93,10 @@ static inline struct thread_info *current_thread_info(void)
 #define _TIF_SYSCALL_TRACE     (1<<TIF_SYSCALL_TRACE)
 #define _TIF_SIGPENDING                (1<<TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED      (1<<TIF_NEED_RESCHED)
-#define _TIF_POLLING_NRFLAG    (1<<TIF_POLLING_NRFLAG)
-#define _TIF_RESTORE_SIGMASK   (1<<TIF_RESTORE_SIGMASK)
 #define _TIF_NOTIFY_RESUME     (1 << TIF_NOTIFY_RESUME)
 
-#define _TIF_WORK_MASK         0x0000FFFE      /* work to do on interrupt/exception return */
+#define _TIF_WORK_MASK         (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \
+                                _TIF_NOTIFY_RESUME)
 
 #endif /* __KERNEL__ */
 
index 5adaadaf92183c42703b9995e32e622dc926d958..0e81b96c642f9cb4736070e9fdcbd453da0f0564 100644 (file)
@@ -38,7 +38,6 @@
 #include <linux/personality.h>
 #include <linux/tty.h>
 #include <linux/binfmts.h>
-#include <linux/freezer.h>
 #include <linux/tracehook.h>
 
 #include <asm/setup.h>
index 4f936a7ee8470b9ada6c1fe9096f77f97506a540..e4a0aad69cbbb0164bbe3cbbb007aade36c31df7 100644 (file)
@@ -120,10 +120,8 @@ register struct thread_info *__current_thread_info asm(QUOTED_THREADINFO_REG);
 #define TIF_SIGPENDING          2       /* signal pending */
 #define TIF_NEED_RESCHED        3       /* rescheduling necessary */
 #define TIF_SINGLESTEP          4       /* restore ss @ return to usr mode */
-#define TIF_IRET                5       /* return with iret */
 #define TIF_RESTORE_SIGMASK     6       /* restore sig mask in do_signal() */
 /* true if poll_idle() is polling TIF_NEED_RESCHED */
-#define TIF_POLLING_NRFLAG      16
 #define TIF_MEMDIE              17      /* OOM killer killed process */
 
 #define _TIF_SYSCALL_TRACE      (1 << TIF_SYSCALL_TRACE)
@@ -131,9 +129,6 @@ register struct thread_info *__current_thread_info asm(QUOTED_THREADINFO_REG);
 #define _TIF_SIGPENDING         (1 << TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED       (1 << TIF_NEED_RESCHED)
 #define _TIF_SINGLESTEP         (1 << TIF_SINGLESTEP)
-#define _TIF_IRET               (1 << TIF_IRET)
-#define _TIF_RESTORE_SIGMASK    (1 << TIF_RESTORE_SIGMASK)
-#define _TIF_POLLING_NRFLAG     (1 << TIF_POLLING_NRFLAG)
 
 /* work to do on interrupt/exception return - All but TIF_SYSCALL_TRACE */
 #define _TIF_WORK_MASK          (0x0000FFFF & ~_TIF_SYSCALL_TRACE)
index 304b0808d07213f0853ee256d781a114f561a947..1ea16bec7b91385ca9bb9de3563d44e0958546af 100644 (file)
@@ -20,7 +20,6 @@
 
 #include <linux/linkage.h>
 #include <linux/syscalls.h>
-#include <linux/freezer.h>
 #include <linux/tracehook.h>
 #include <asm/registers.h>
 #include <asm/thread_info.h>
index 620dd18197a0597144ffece20adc98f655d521dd..553cd60ee659d8bcc13fff4dbde40cd646a2c86c 100644 (file)
@@ -87,4 +87,3 @@ int kernel_execve(const char *filename,
 
        return retval;
 }
-EXPORT_SYMBOL(kernel_execve);
index d4eb9383f5f657718fba1b5467baa4c35257eb14..98efd48d7da4dfbeefa23a55022d893165d483c2 100644 (file)
@@ -13,3 +13,4 @@ header-y += ptrace_offsets.h
 header-y += rse.h
 header-y += ucontext.h
 header-y += ustack.h
+generic-y += exec.h
diff --git a/arch/ia64/include/asm/exec.h b/arch/ia64/include/asm/exec.h
deleted file mode 100644 (file)
index b262424..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * Process execution defines.
- *
- * Copyright (C) 1998-2003 Hewlett-Packard Co
- *     David Mosberger-Tang <davidm@hpl.hp.com>
- * Copyright (C) 1999 Asit Mallick <asit.k.mallick@intel.com>
- * Copyright (C) 1999 Don Dugger <don.dugger@intel.com>
- */
-#ifndef _ASM_IA64_EXEC_H
-#define _ASM_IA64_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* _ASM_IA64_EXEC_H */
index f7ee85378311a0f2d241a458640f697b4940a2a1..ff2ae41365840a616b4a7b6211aed1b2678c6e0a 100644 (file)
@@ -106,7 +106,6 @@ struct thread_info {
 #define TIF_SYSCALL_AUDIT      3       /* syscall auditing active */
 #define TIF_SINGLESTEP         4       /* restore singlestep on return to user mode */
 #define TIF_NOTIFY_RESUME      6       /* resumption notification requested */
-#define TIF_POLLING_NRFLAG     16      /* true if poll_idle() is polling TIF_NEED_RESCHED */
 #define TIF_MEMDIE             17      /* is terminating due to OOM killer */
 #define TIF_MCA_INIT           18      /* this task is processing MCA or INIT */
 #define TIF_DB_DISABLED                19      /* debug trap disabled for fsyscall */
@@ -119,7 +118,6 @@ struct thread_info {
 #define _TIF_NOTIFY_RESUME     (1 << TIF_NOTIFY_RESUME)
 #define _TIF_SIGPENDING                (1 << TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED      (1 << TIF_NEED_RESCHED)
-#define _TIF_POLLING_NRFLAG    (1 << TIF_POLLING_NRFLAG)
 #define _TIF_MCA_INIT          (1 << TIF_MCA_INIT)
 #define _TIF_DB_DISABLED       (1 << TIF_DB_DISABLED)
 #define _TIF_RESTORE_RSE       (1 << TIF_RESTORE_RSE)
index 37dd79511cbeb548c67b4f255ff0b1fcb2c69196..680b73786be85077fe2a2424e3ecfd00ebe6ea43 100644 (file)
@@ -437,14 +437,6 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall)
        long restart = in_syscall;
        long errno = scr->pt.r8;
 
-       /*
-        * In the ia64_leave_kernel code path, we want the common case to go fast, which
-        * is why we may in certain cases get here from kernel mode. Just return without
-        * doing anything if so.
-        */
-       if (!user_mode(&scr->pt))
-               return;
-
        /*
         * This only loops in the rare cases of handle_signal() failing, in which case we
         * need to push through a forced SIGSEGV.
index 871382d239fef60105b37f50424afe24ed6773e3..883a0be9f69f7921b993698a576b176460bec0cd 100644 (file)
@@ -1,3 +1,4 @@
 include include/asm-generic/Kbuild.asm
 
 generic-y      += module.h
+generic-y += exec.h
diff --git a/arch/m32r/include/asm/exec.h b/arch/m32r/include/asm/exec.h
deleted file mode 100644 (file)
index c805dbd..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2001  Hiroyuki Kondo, Hirokazu Takata, and Hitoshi Yamamoto
- * Copyright (C) 2004, 2006  Hirokazu Takata <takata at linux-m32r.org>
- */
-#ifndef _ASM_M32R_EXEC_H
-#define _ASM_M32R_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* _ASM_M32R_EXEC_H */
index c083f6073ef4f3d1720f466fb08f62a64bbe0881..c074f4c2e858e6cc76b16476a9fc24aea2566793 100644 (file)
@@ -119,25 +119,20 @@ static inline unsigned int get_thread_fault_code(void)
 #define TIF_SIGPENDING         1       /* signal pending */
 #define TIF_NEED_RESCHED       2       /* rescheduling necessary */
 #define TIF_SINGLESTEP         3       /* restore singlestep on return to user mode */
-#define TIF_IRET               4       /* return with iret */
 #define TIF_NOTIFY_RESUME      5       /* callback before returning to user */
 #define TIF_RESTORE_SIGMASK    8       /* restore signal mask in do_signal() */
 #define TIF_USEDFPU            16      /* FPU was used by this task this quantum (SMP) */
-#define TIF_POLLING_NRFLAG     17      /* true if poll_idle() is polling TIF_NEED_RESCHED */
 #define TIF_MEMDIE             18      /* is terminating due to OOM killer */
 
 #define _TIF_SYSCALL_TRACE     (1<<TIF_SYSCALL_TRACE)
 #define _TIF_SIGPENDING                (1<<TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED      (1<<TIF_NEED_RESCHED)
 #define _TIF_SINGLESTEP                (1<<TIF_SINGLESTEP)
-#define _TIF_IRET              (1<<TIF_IRET)
 #define _TIF_NOTIFY_RESUME     (1<<TIF_NOTIFY_RESUME)
-#define _TIF_RESTORE_SIGMASK   (1<<TIF_RESTORE_SIGMASK)
 #define _TIF_USEDFPU           (1<<TIF_USEDFPU)
-#define _TIF_POLLING_NRFLAG    (1<<TIF_POLLING_NRFLAG)
 
-#define _TIF_WORK_MASK         0x0000FFFE      /* work to do on interrupt/exception return */
-#define _TIF_ALLWORK_MASK      0x0000FFFF      /* work to do on any return to u-space */
+#define _TIF_WORK_MASK         (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_NOTIFY_RESUME)
+#define _TIF_ALLWORK_MASK      (_TIF_WORK_MASK | _TIF_SYSCALL_TRACE)
 
 /*
  * Thread-synchronous status.
index d0f60b97bbc5d82b1855e73145ce0b809124200f..6e3c26a1607cdb6b505e4b25cab682a08ed04605 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/unistd.h>
 #include <linux/stddef.h>
 #include <linux/personality.h>
-#include <linux/freezer.h>
 #include <linux/tracehook.h>
 #include <asm/cacheflush.h>
 #include <asm/ucontext.h>
@@ -366,6 +365,4 @@ void do_notify_resume(struct pt_regs *regs, __u32 thread_info_flags)
                clear_thread_flag(TIF_NOTIFY_RESUME);
                tracehook_notify_resume(regs);
        }
-
-       clear_thread_flag(TIF_IRET);
 }
index 0df07cee3faf5e1c0585f879a8e61e8d69a1d81b..b4126a7dfddcd9c44da41b1c48e136cf26917066 100644 (file)
@@ -16,6 +16,7 @@ config M68K
        select HAVE_MOD_ARCH_SPECIFIC
        select MODULES_USE_ELF_REL
        select MODULES_USE_ELF_RELA
+       select GENERIC_KERNEL_THREAD
 
 config RWSEM_GENERIC_SPINLOCK
        bool
index a74e5d95c384941583d99096bae1175634c9b4cb..a9d1bf1400f8496a5fa0cb5446b969cb103ba823 100644 (file)
@@ -6,6 +6,7 @@ generic-y += cputime.h
 generic-y += device.h
 generic-y += emergency-restart.h
 generic-y += errno.h
+generic-y += exec.h
 generic-y += futex.h
 generic-y += ioctl.h
 generic-y += ipcbuf.h
diff --git a/arch/m68k/include/asm/exec.h b/arch/m68k/include/asm/exec.h
deleted file mode 100644 (file)
index 0499adf..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _M68K_EXEC_H
-#define _M68K_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* _M68K_EXEC_H */
index f17c42aff7ffb9aa592aebf2e118d99309d8e699..ae700f49e51da86b8b86b8ce9ee41b0a1908d6b1 100644 (file)
@@ -100,6 +100,16 @@ struct thread_struct {
        .fs     = __KERNEL_DS,                                          \
 }
 
+/*
+ * ColdFire stack format sbould be 0x4 for an aligned usp (will always be
+ * true on thread creation). We need to set this explicitly.
+ */
+#ifdef CONFIG_COLDFIRE
+#define setframeformat(_regs)  do { (_regs)->format = 0x4; } while(0)
+#else
+#define setframeformat(_regs)  do { } while (0)
+#endif
+
 #ifdef CONFIG_MMU
 /*
  * Do necessary setup to start up a newly executed thread.
@@ -109,6 +119,7 @@ static inline void start_thread(struct pt_regs * regs, unsigned long pc,
 {
        regs->pc = pc;
        regs->sr &= ~0x2000;
+       setframeformat(regs);
        wrusp(usp);
 }
 
@@ -116,21 +127,11 @@ extern int handle_kernel_fault(struct pt_regs *regs);
 
 #else
 
-/*
- * Coldfire stacks need to be re-aligned on trap exit, conventional
- * 68k can handle this case cleanly.
- */
-#ifdef CONFIG_COLDFIRE
-#define reformat(_regs)                do { (_regs)->format = 0x4; } while(0)
-#else
-#define reformat(_regs)                do { } while (0)
-#endif
-
 #define start_thread(_regs, _pc, _usp)                  \
 do {                                                    \
        (_regs)->pc = (_pc);                            \
        ((struct switch_stack *)(_regs))[-1].a6 = 0;    \
-       reformat(_regs);                                \
+       setframeformat(_regs);                          \
        if (current->mm)                                \
                (_regs)->d5 = current->mm->start_data;  \
        (_regs)->sr &= ~0x2000;                         \
@@ -153,8 +154,6 @@ static inline void release_thread(struct task_struct *dead_task)
 {
 }
 
-extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-
 /*
  * Free current thread data structures etc..
  */
index 65322b17b6cfb96664763a74796871d1c321413b..5e08b597f012192e8a5f8cd4cc4d0a20690b485d 100644 (file)
@@ -85,6 +85,8 @@ struct switch_stack {
 #define user_mode(regs) (!((regs)->sr & PS_S))
 #define instruction_pointer(regs) ((regs)->pc)
 #define profile_pc(regs) instruction_pointer(regs)
+#define current_pt_regs() \
+       (struct pt_regs *)((char *)current_thread_info() + THREAD_SIZE) - 1
 
 #define arch_has_single_step() (1)
 
index 045cfd6a9e31b72edd428160deedd47b6078a51a..c702ad71679195f501f540b7ed5b32108f920813 100644 (file)
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGACTION
 #define __ARCH_WANT_SYS_RT_SIGSUSPEND
+#define __ARCH_WANT_SYS_EXECVE
+#define __ARCH_WANT_KERNEL_EXECVE
 
 /*
  * "Conditional" syscalls
index 165ee9f9d5c9db716290009980fc6d1e865bf446..946cb0187751caf241a0f2f4e1b5b9ebe3c535a0 100644 (file)
@@ -111,6 +111,22 @@ ENTRY(ret_from_fork)
        addql   #4,%sp
        jra     ret_from_exception
 
+ENTRY(ret_from_kernel_thread)
+       | a3 contains the kernel thread payload, d7 - its argument
+       movel   %d1,%sp@-
+       jsr     schedule_tail
+       GET_CURRENT(%d0)
+       movel   %d7,(%sp)
+       jsr     %a3@
+       addql   #4,%sp
+       movel   %d0,(%sp)
+       jra     sys_exit
+
+ENTRY(ret_from_kernel_execve)
+       movel   4(%sp), %sp
+       GET_CURRENT(%d0)
+       jra     ret_from_exception
+
 #if defined(CONFIG_COLDFIRE) || !defined(CONFIG_MMU)
 
 #ifdef TRAP_DBG_INTERRUPT
index ac2892e49c7c9107734044925caad596e56988bc..c51bb172e14d774a4dcbea235fc22618de198aba 100644 (file)
@@ -35,6 +35,7 @@
 
 
 asmlinkage void ret_from_fork(void);
+asmlinkage void ret_from_kernel_thread(void);
 
 
 /*
@@ -123,51 +124,6 @@ void show_regs(struct pt_regs * regs)
                printk("USP: %08lx\n", rdusp());
 }
 
-/*
- * Create a kernel thread
- */
-int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
-{
-       int pid;
-       mm_segment_t fs;
-
-       fs = get_fs();
-       set_fs (KERNEL_DS);
-
-       {
-       register long retval __asm__ ("d0");
-       register long clone_arg __asm__ ("d1") = flags | CLONE_VM | CLONE_UNTRACED;
-
-       retval = __NR_clone;
-       __asm__ __volatile__
-         ("clrl %%d2\n\t"
-          "trap #0\n\t"                /* Linux/m68k system call */
-          "tstl %0\n\t"                /* child or parent */
-          "jne 1f\n\t"                 /* parent - jump */
-#ifdef CONFIG_MMU
-          "lea %%sp@(%c7),%6\n\t"      /* reload current */
-          "movel %6@,%6\n\t"
-#endif
-          "movel %3,%%sp@-\n\t"        /* push argument */
-          "jsr %4@\n\t"                /* call fn */
-          "movel %0,%%d1\n\t"          /* pass exit value */
-          "movel %2,%%d0\n\t"          /* exit */
-          "trap #0\n"
-          "1:"
-          : "+d" (retval)
-          : "i" (__NR_clone), "i" (__NR_exit),
-            "r" (arg), "a" (fn), "d" (clone_arg), "r" (current),
-            "i" (-THREAD_SIZE)
-          : "d2");
-
-       pid = retval;
-       }
-
-       set_fs (fs);
-       return pid;
-}
-EXPORT_SYMBOL(kernel_thread);
-
 void flush_thread(void)
 {
        current->thread.fs = __USER_DS;
@@ -219,30 +175,18 @@ asmlinkage int m68k_clone(struct pt_regs *regs)
 }
 
 int copy_thread(unsigned long clone_flags, unsigned long usp,
-                unsigned long unused,
+                unsigned long arg,
                 struct task_struct * p, struct pt_regs * regs)
 {
        struct pt_regs * childregs;
-       struct switch_stack * childstack, *stack;
-       unsigned long *retp;
+       struct switch_stack *childstack;
 
        childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE) - 1;
-
-       *childregs = *regs;
-       childregs->d0 = 0;
-
-       retp = ((unsigned long *) regs);
-       stack = ((struct switch_stack *) retp) - 1;
-
        childstack = ((struct switch_stack *) childregs) - 1;
-       *childstack = *stack;
-       childstack->retpc = (unsigned long)ret_from_fork;
 
        p->thread.usp = usp;
        p->thread.ksp = (unsigned long)childstack;
-
-       if (clone_flags & CLONE_SETTLS)
-               task_thread_info(p)->tp_value = regs->d5;
+       p->thread.esp0 = (unsigned long)childregs;
 
        /*
         * Must save the current SFC/DFC value, NOT the value when
@@ -250,6 +194,26 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
         */
        p->thread.fs = get_fs().seg;
 
+       if (unlikely(!regs)) {
+               /* kernel thread */
+               memset(childstack, 0,
+                       sizeof(struct switch_stack) + sizeof(struct pt_regs));
+               childregs->sr = PS_S;
+               childstack->a3 = usp; /* function */
+               childstack->d7 = arg;
+               childstack->retpc = (unsigned long)ret_from_kernel_thread;
+               p->thread.usp = 0;
+               return 0;
+       }
+       *childregs = *regs;
+       childregs->d0 = 0;
+
+       *childstack = ((struct switch_stack *) regs)[-1];
+       childstack->retpc = (unsigned long)ret_from_fork;
+
+       if (clone_flags & CLONE_SETTLS)
+               task_thread_info(p)->tp_value = regs->d5;
+
 #ifdef CONFIG_FPU
        if (!FPU_IS_EMU) {
                /* Copy the current fpu state */
@@ -337,26 +301,6 @@ int dump_fpu (struct pt_regs *regs, struct user_m68kfp_struct *fpu)
 EXPORT_SYMBOL(dump_fpu);
 #endif /* CONFIG_FPU */
 
-/*
- * sys_execve() executes a new program.
- */
-asmlinkage int sys_execve(const char __user *name,
-                         const char __user *const __user *argv,
-                         const char __user *const __user *envp)
-{
-       int error;
-       char * filename;
-       struct pt_regs *regs = (struct pt_regs *) &name;
-
-       filename = getname(name);
-       error = PTR_ERR(filename);
-       if (IS_ERR(filename))
-               return error;
-       error = do_execve(filename, argv, envp, regs);
-       putname(filename);
-       return error;
-}
-
 unsigned long get_wchan(struct task_struct *p)
 {
        unsigned long fp, pc;
index 9a5932ec368946bf808c5faf527cbf39731b5540..3a480b3df0d6cfee0fa7a6e2da99f710d776d587 100644 (file)
@@ -549,23 +549,6 @@ asmlinkage int sys_getpagesize(void)
        return PAGE_SIZE;
 }
 
-/*
- * Do a system call from kernel instead of calling sys_execve so we
- * end up with proper pt_regs.
- */
-int kernel_execve(const char *filename,
-                 const char *const argv[],
-                 const char *const envp[])
-{
-       register long __res asm ("%d0") = __NR_execve;
-       register long __a asm ("%d1") = (long)(filename);
-       register long __b asm ("%d2") = (long)(argv);
-       register long __c asm ("%d3") = (long)(envp);
-       asm volatile ("trap  #0" : "+d" (__res)
-                       : "d" (__a), "d" (__b), "d" (__c));
-       return __res;
-}
-
 asmlinkage unsigned long sys_get_thread_area(void)
 {
        return current_thread_info()->tp_value;
index db5294c30cafef1d2cbb8f83b787edb36f812613..5a0e72bf998d90516f3acbd5a3275093b4dd0dd7 100644 (file)
@@ -1,3 +1,4 @@
 include include/asm-generic/Kbuild.asm
 
 header-y  += elf.h
+generic-y += exec.h
diff --git a/arch/microblaze/include/asm/exec.h b/arch/microblaze/include/asm/exec.h
deleted file mode 100644 (file)
index e750de1..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * Copyright (C) 2006 Atmark Techno, Inc.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
-#ifndef _ASM_MICROBLAZE_EXEC_H
-#define _ASM_MICROBLAZE_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* _ASM_MICROBLAZE_EXEC_H */
index 6c610234ffab96c8d849dfc8dac498bfaf1c9919..008f30433d22f606f6b6d15f2d644fa5d88c1dd2 100644 (file)
@@ -121,7 +121,6 @@ static inline struct thread_info *current_thread_info(void)
 #define TIF_NEED_RESCHED       3 /* rescheduling necessary */
 /* restore singlestep on return to user mode */
 #define TIF_SINGLESTEP         4
-#define TIF_IRET               5 /* return with iret */
 #define TIF_MEMDIE             6       /* is terminating due to OOM killer */
 #define TIF_SYSCALL_AUDIT      9       /* syscall auditing active */
 #define TIF_SECCOMP            10      /* secure computing */
@@ -134,7 +133,6 @@ static inline struct thread_info *current_thread_info(void)
 #define _TIF_SIGPENDING                (1 << TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED      (1 << TIF_NEED_RESCHED)
 #define _TIF_SINGLESTEP                (1 << TIF_SINGLESTEP)
-#define _TIF_IRET              (1 << TIF_IRET)
 #define _TIF_POLLING_NRFLAG    (1 << TIF_POLLING_NRFLAG)
 #define _TIF_SYSCALL_AUDIT     (1 << TIF_SYSCALL_AUDIT)
 #define _TIF_SECCOMP           (1 << TIF_SECCOMP)
@@ -184,6 +182,7 @@ static inline bool test_and_clear_restore_sigmask(void)
        ti->status &= ~TS_RESTORE_SIGMASK;
        return true;
 }
+#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
 #endif
 
 #endif /* __KERNEL__ */
index 76b9722557db77e99a3500154a34b8ed6556d958..0d27fdbb30fdde8ed6ff5407c72561173d718f22 100644 (file)
@@ -254,10 +254,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 
        set_fs(USER_DS);
 
-       /* the tracer may want to single-step inside the handler */
-       if (test_thread_flag(TIF_SINGLESTEP))
-               ptrace_notify(SIGTRAP);
-
 #ifdef DEBUG_SIG
        printk(KERN_INFO "SIG deliver (%s:%d): sp=%p pc=%08lx\n",
                current->comm, current->pid, frame, regs->pc);
@@ -323,7 +319,8 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
        if (ret)
                return;
 
-       signal_delivered(sig, info, ka, regs, 0);
+       signal_delivered(sig, info, ka, regs,
+                       test_thread_flag(TIF_SINGLESTEP));
 }
 
 /*
index 946e010f20182b11622aa0b9bbc2d53927eab36e..8debe9e917549097d09f5083489714605066a1cc 100644 (file)
@@ -103,7 +103,6 @@ register struct thread_info *__current_thread_info __asm__("$28");
 #define TIF_NOTIFY_RESUME      5       /* callback before returning to user */
 #define TIF_RESTORE_SIGMASK    9       /* restore signal mask in do_signal() */
 #define TIF_USEDFPU            16      /* FPU was used by this task this quantum (SMP) */
-#define TIF_POLLING_NRFLAG     17      /* true if poll_idle() is polling TIF_NEED_RESCHED */
 #define TIF_MEMDIE             18      /* is terminating due to OOM killer */
 #define TIF_FIXADE             20      /* Fix address errors in software */
 #define TIF_LOGADE             21      /* Log address errors to syslog */
@@ -125,9 +124,7 @@ register struct thread_info *__current_thread_info __asm__("$28");
 #define _TIF_SYSCALL_AUDIT     (1<<TIF_SYSCALL_AUDIT)
 #define _TIF_SECCOMP           (1<<TIF_SECCOMP)
 #define _TIF_NOTIFY_RESUME     (1<<TIF_NOTIFY_RESUME)
-#define _TIF_RESTORE_SIGMASK   (1<<TIF_RESTORE_SIGMASK)
 #define _TIF_USEDFPU           (1<<TIF_USEDFPU)
-#define _TIF_POLLING_NRFLAG    (1<<TIF_POLLING_NRFLAG)
 #define _TIF_FIXADE            (1<<TIF_FIXADE)
 #define _TIF_LOGADE            (1<<TIF_LOGADE)
 #define _TIF_32BIT_REGS                (1<<TIF_32BIT_REGS)
index aa03f2e13385fe5083a50b17ae6f8c02e3ccb269..549b9e50182eb26ab8d10a9eae0e9f38e63e852f 100644 (file)
@@ -9,6 +9,7 @@ config MN10300
        select HAVE_NMI_WATCHDOG if MN10300_WD_TIMER
        select GENERIC_CLOCKEVENTS
        select MODULES_USE_ELF_RELA
+       select GENERIC_KERNEL_THREAD
 
 config AM33_2
        def_bool n
index c68e1680da0173d5754d1a1df4944120a5239e58..708340339b057e16c4accba616fd5d37ffa53838 100644 (file)
@@ -1 +1,3 @@
 include include/asm-generic/Kbuild.asm
+
+generic-y += exec.h
diff --git a/arch/mn10300/include/asm/exec.h b/arch/mn10300/include/asm/exec.h
deleted file mode 100644 (file)
index c74e367..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-/* MN10300 process execution definitions
- *
- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
-#ifndef _ASM_EXEC_H
-#define _ASM_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* _ASM_EXEC_H */
index 2ee58e3eb6b355b75166bf57334c01498a66b8fd..1c3eb4fda9588a57e555bf8ead8757f8952eb7a8 100644 (file)
@@ -61,7 +61,7 @@
 ###############################################################################
 .macro RESTORE_ALL
        # peel back the stack to the calling frame
-       # - this permits execve() to discard extra frames due to kernel syscalls
+       # - we need that when returning from interrupts to kernel mode
        GET_THREAD_INFO a0
        mov     (TI_frame,a0),fp
        mov     fp,sp
index 247928c9f549ec239e1e5556a1c7157674833bba..8b80b19d0c8a4fbfe7406f12141ae6d12040fd35 100644 (file)
@@ -119,31 +119,19 @@ struct thread_struct {
 
 /*
  * do necessary setup to start up a newly executed thread
- * - need to discard the frame stacked by the kernel thread invoking the execve
- *   syscall (see RESTORE_ALL macro)
  */
 static inline void start_thread(struct pt_regs *regs,
                                unsigned long new_pc, unsigned long new_sp)
 {
-       struct thread_info *ti = current_thread_info();
-       struct pt_regs *frame0;
-
-       frame0 = thread_info_to_uregs(ti);
-       frame0->epsw = EPSW_nSL | EPSW_IE | EPSW_IM;
-       frame0->pc = new_pc;
-       frame0->sp = new_sp;
-       ti->frame = frame0;
+       regs->epsw = EPSW_nSL | EPSW_IE | EPSW_IM;
+       regs->pc = new_pc;
+       regs->sp = new_sp;
 }
 
 
 /* Free all resources held by a thread. */
 extern void release_thread(struct task_struct *);
 
-/*
- * create a kernel thread without removing it from tasklists
- */
-extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
-
 /*
  * Return saved PC of a blocked thread.
  */
index 44251b974f1d96d4931e4704d9433163eb070962..08ac856c053e67f915958fdbe5f20d67c48970ae 100644 (file)
@@ -86,6 +86,7 @@ struct pt_regs {
 #define user_mode(regs)                        (((regs)->epsw & EPSW_nSL) == EPSW_nSL)
 #define instruction_pointer(regs)      ((regs)->pc)
 #define user_stack_pointer(regs)       ((regs)->sp)
+#define current_pt_regs()              current_frame()
 
 #define arch_has_single_step() (1)
 
index ac519bbd42ffe32693a02d3f88ac5dbd21d426ff..f90062b0622df11c2f049830f185adefa4a60b22 100644 (file)
@@ -160,12 +160,13 @@ void arch_release_thread_info(struct thread_info *ti);
 #define _TIF_SIGPENDING                +(1 << TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED      +(1 << TIF_NEED_RESCHED)
 #define _TIF_SINGLESTEP                +(1 << TIF_SINGLESTEP)
-#define _TIF_RESTORE_SIGMASK   +(1 << TIF_RESTORE_SIGMASK)
 #define _TIF_POLLING_NRFLAG    +(1 << TIF_POLLING_NRFLAG)
 
 #define _TIF_WORK_MASK         0x0000FFFE      /* work to do on interrupt/exception return */
 #define _TIF_ALLWORK_MASK      0x0000FFFF      /* work to do on any return to u-space */
 
+#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
+
 #endif /* __KERNEL__ */
 
 #endif /* _ASM_THREAD_INFO_H */
index 866eb14749d7701cb4dafce5566d8aa00df18fe6..044c770adbb65bc11fe2332d645d7b1c06a29640 100644 (file)
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGACTION
 #define __ARCH_WANT_SYS_RT_SIGSUSPEND
+#define __ARCH_WANT_SYS_EXECVE
+#define __ARCH_WANT_KERNEL_EXECVE
 
 /*
  * "Conditional" syscalls
index d06749173d639dd66f4ce32358ff199b88b5ae09..561029f7fa4489259297225313ffa7b6d028817a 100644 (file)
@@ -7,8 +7,8 @@ fpu-obj-y := fpu-nofpu.o fpu-nofpu-low.o
 fpu-obj-$(CONFIG_FPU) := fpu.o fpu-low.o
 
 obj-y   := process.o signal.o entry.o traps.o irq.o \
-          ptrace.o setup.o time.o sys_mn10300.o io.o kthread.o \
-          switch_to.o mn10300_ksyms.o kernel_execve.o $(fpu-obj-y) \
+          ptrace.o setup.o time.o sys_mn10300.o io.o \
+          switch_to.o mn10300_ksyms.o $(fpu-obj-y) \
           csrc-mn10300.o cevt-mn10300.o
 
 obj-$(CONFIG_SMP) += smp.o smp-low.o
index 8e11f9f48999e172437a925bb9713a2c9c1236c2..0c631d34c8d7f1f73807b4f46c8114ea430a3154 100644 (file)
@@ -55,6 +55,20 @@ ENTRY(ret_from_fork)
        mov     d0,(REG_D0,fp)
        jmp     syscall_exit
 
+ENTRY(ret_from_kernel_thread)
+       call    schedule_tail[],0
+       mov     (REG_D0,fp),d0
+       mov     (REG_A0,fp),a0
+       calls   (a0)
+       jmp     sys_exit
+
+ENTRY(ret_from_kernel_execve)
+       add     -12,d0  /* pt_regs -> frame */
+       mov     d0,sp
+       GET_THREAD_INFO a2
+       clr     d0
+       jmp     syscall_exit
+
 ###############################################################################
 #
 # system call handler
@@ -94,6 +108,10 @@ restore_all:
 ###############################################################################
        ALIGN
 syscall_exit_work:
+       mov     (REG_EPSW,fp),d0
+       and     EPSW_nSL,d0
+       beq     resume_kernel           # returning to supervisor mode
+
        btst    _TIF_SYSCALL_TRACE,d2
        beq     work_pending
        LOCAL_IRQ_ENABLE                # could let syscall_trace_exit() call
index 2df440105a80f78e111f4f863261cbb7abab10ae..561785581f6c21382e9e17b5e1566a5c4ed1c20e 100644 (file)
 struct clocksource;
 struct clock_event_device;
 
-/*
- * kthread.S
- */
-extern int kernel_thread_helper(int);
-
 /*
  * entry.S
  */
 extern void ret_from_fork(struct task_struct *) __attribute__((noreturn));
+extern void ret_from_kernel_thread(struct task_struct *) __attribute__((noreturn));
 
 /*
  * smp-low.S
diff --git a/arch/mn10300/kernel/kernel_execve.S b/arch/mn10300/kernel/kernel_execve.S
deleted file mode 100644 (file)
index 86039f1..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/* MN10300 In-kernel program execution
- *
- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
-#include <linux/linkage.h>
-#include <asm/unistd.h>
-
-###############################################################################
-#
-# Do a system call from kernel instead of calling sys_execve so we end up with
-# proper pt_regs.
-#
-# int kernel_execve(const char *filename, char *const argv[],
-#                  char *const envp[])
-#
-# On entry: D0/D1/8(SP): arguments to function
-# On return: D0: syscall return.
-#
-###############################################################################
-       .globl          kernel_execve
-       .type           kernel_execve,@function
-kernel_execve:
-       mov             a3,a1
-       mov             d0,a0
-       mov             (12,sp),a3
-       mov             +__NR_execve,d0
-       syscall         0
-       mov             a1,a3
-       rets
-
-       .size           kernel_execve,.-kernel_execve
diff --git a/arch/mn10300/kernel/kthread.S b/arch/mn10300/kernel/kthread.S
deleted file mode 100644 (file)
index b5ae467..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/* MN10300 Kernel thread trampoline function
- *
- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
- * Written by Mark Salter (msalter@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
-       .text
-
-###############################################################################
-#
-# kernel_thread_helper - trampoline for kernel_thread()
-#
-# On entry:
-#   A2 = address of function to call
-#   D2 = function argument
-#
-###############################################################################
-       .globl  kernel_thread_helper
-       .type   kernel_thread_helper,@function
-kernel_thread_helper:
-       mov     do_exit,d1
-       mov     d1,(sp)
-       mov     d1,mdr
-       mov     d2,d0
-       jmp     (a2)
-
-       .size   kernel_thread_helper,.-kernel_thread_helper
index e9cceba193b6510f50acd8419a4a2498f82ff64f..d0c671b6d9ffc18f687b5d45b99697f891686583 100644 (file)
@@ -164,27 +164,6 @@ void show_regs(struct pt_regs *regs)
 {
 }
 
-/*
- * create a kernel thread
- */
-int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
-{
-       struct pt_regs regs;
-
-       memset(&regs, 0, sizeof(regs));
-
-       regs.a2 = (unsigned long) fn;
-       regs.d2 = (unsigned long) arg;
-       regs.pc = (unsigned long) kernel_thread_helper;
-       local_save_flags(regs.epsw);
-       regs.epsw |= EPSW_IE | EPSW_IM_7;
-
-       /* Ok, create the new process.. */
-       return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0,
-                      NULL, NULL);
-}
-EXPORT_SYMBOL(kernel_thread);
-
 /*
  * free current thread data structures etc..
  */
@@ -230,50 +209,42 @@ int copy_thread(unsigned long clone_flags,
                struct task_struct *p, struct pt_regs *kregs)
 {
        struct thread_info *ti = task_thread_info(p);
-       struct pt_regs *c_uregs, *c_kregs, *uregs;
+       struct pt_regs *c_regs;
        unsigned long c_ksp;
 
-       uregs = current->thread.uregs;
-
        c_ksp = (unsigned long) task_stack_page(p) + THREAD_SIZE;
 
        /* allocate the userspace exception frame and set it up */
        c_ksp -= sizeof(struct pt_regs);
-       c_uregs = (struct pt_regs *) c_ksp;
+       c_regs = (struct pt_regs *) c_ksp;
+       c_ksp -= 12; /* allocate function call ABI slack */
 
-       p->thread.uregs = c_uregs;
-       *c_uregs = *uregs;
-       c_uregs->sp = c_usp;
-       c_uregs->epsw &= ~EPSW_FE; /* my FPU */
+       /* set up things up so the scheduler can start the new task */
+       p->thread.uregs = c_regs;
+       ti->frame       = c_regs;
+       p->thread.a3    = (unsigned long) c_regs;
+       p->thread.sp    = c_ksp;
+       p->thread.wchan = p->thread.pc;
+       p->thread.usp   = c_usp;
 
-       c_ksp -= 12; /* allocate function call ABI slack */
+       if (unlikely(!kregs)) {
+               memset(c_regs, 0, sizeof(struct pt_regs));
+               c_regs->a0 = c_usp; /* function */
+               c_regs->d0 = ustk_size; /* argument */
+               local_save_flags(c_regs->epsw);
+               c_regs->epsw |= EPSW_IE | EPSW_IM_7;
+               p->thread.pc    = (unsigned long) ret_from_kernel_thread;
+               return 0;
+       }
+       *c_regs = *kregs;
+       c_regs->sp = c_usp;
+       c_regs->epsw &= ~EPSW_FE; /* my FPU */
 
        /* the new TLS pointer is passed in as arg #5 to sys_clone() */
        if (clone_flags & CLONE_SETTLS)
-               c_uregs->e2 = current_frame()->d3;
-
-       /* set up the return kernel frame if called from kernel_thread() */
-       c_kregs = c_uregs;
-       if (kregs != uregs) {
-               c_ksp -= sizeof(struct pt_regs);
-               c_kregs = (struct pt_regs *) c_ksp;
-               *c_kregs = *kregs;
-               c_kregs->sp = c_usp;
-               c_kregs->next = c_uregs;
-#ifdef CONFIG_MN10300_CURRENT_IN_E2
-               c_kregs->e2 = (unsigned long) p; /* current */
-#endif
-
-               c_ksp -= 12; /* allocate function call ABI slack */
-       }
+               c_regs->e2 = current_frame()->d3;
 
-       /* set up things up so the scheduler can start the new task */
-       ti->frame       = c_kregs;
-       p->thread.a3    = (unsigned long) c_kregs;
-       p->thread.sp    = c_ksp;
        p->thread.pc    = (unsigned long) ret_from_fork;
-       p->thread.wchan = (unsigned long) ret_from_fork;
-       p->thread.usp   = c_usp;
 
        return 0;
 }
@@ -302,22 +273,6 @@ asmlinkage long sys_vfork(void)
                       current_frame(), 0, NULL, NULL);
 }
 
-asmlinkage long sys_execve(const char __user *name,
-                          const char __user *const __user *argv,
-                          const char __user *const __user *envp)
-{
-       char *filename;
-       int error;
-
-       filename = getname(name);
-       error = PTR_ERR(filename);
-       if (IS_ERR(filename))
-               return error;
-       error = do_execve(filename, argv, envp, current_frame());
-       putname(filename);
-       return error;
-}
-
 unsigned long get_wchan(struct task_struct *p)
 {
        return p->thread.wchan;
index 4d584ae29ae1c1c2c53746ee3a6d1d9b78e7042a..f570b3085ef90004d2150eca7f86107ea232cf1e 100644 (file)
@@ -317,10 +317,6 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
        regs->d0 = sig;
        regs->d1 = (unsigned long) &frame->sc;
 
-       /* the tracer may want to single-step inside the handler */
-       if (test_thread_flag(TIF_SINGLESTEP))
-               ptrace_notify(SIGTRAP);
-
 #if DEBUG_SIG
        printk(KERN_DEBUG "SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
               sig, current->comm, current->pid, frame, regs->pc,
@@ -398,10 +394,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        regs->d0 = sig;
        regs->d1 = (long) &frame->info;
 
-       /* the tracer may want to single-step inside the handler */
-       if (test_thread_flag(TIF_SINGLESTEP))
-               ptrace_notify(SIGTRAP);
-
 #if DEBUG_SIG
        printk(KERN_DEBUG "SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
               sig, current->comm, current->pid, frame, regs->pc,
@@ -475,11 +467,6 @@ static void do_signal(struct pt_regs *regs)
        siginfo_t info;
        int signr;
 
-       /* we want the common case to go fast, which is why we may in certain
-        * cases get here from kernel mode */
-       if (!user_mode(regs))
-               return;
-
        signr = get_signal_to_deliver(&info, &ka, regs, NULL);
        if (signr > 0) {
                if (handle_signal(signr, &info, &ka, regs) == 0) {
index 07a8bc080ef2e25508cbded379a2e94b9531adad..07f3212422adf916f2dfa590f492eb7a4dc517ad 100644 (file)
@@ -121,7 +121,6 @@ register struct thread_info *current_thread_info_reg asm("r10");
 #define _TIF_SIGPENDING                (1<<TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED      (1<<TIF_NEED_RESCHED)
 #define _TIF_SINGLESTEP                (1<<TIF_SINGLESTEP)
-#define _TIF_RESTORE_SIGMASK     (1<<TIF_RESTORE_SIGMASK)
 #define _TIF_POLLING_NRFLAG    (1<<TIF_POLLING_NRFLAG)
 
 
@@ -129,6 +128,8 @@ register struct thread_info *current_thread_info_reg asm("r10");
 /* For OpenRISC, this is anything in the LSW other than syscall trace */
 #define _TIF_WORK_MASK (0xff & ~(_TIF_SYSCALL_TRACE|_TIF_SINGLESTEP))
 
+#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
+
 #endif /* __KERNEL__ */
 
 #endif /* _ASM_THREAD_INFO_H */
index 38a1c1b8d4e8e11093b3a35db9d95ca98749ed1a..011468857e9801fe850164655bddf840d3e4f2ea 100644 (file)
@@ -71,7 +71,7 @@ ENTRY(hpux_gateway_page)
        STREG   %r26, TASK_PT_GR26(%r1)         /* 1st argument */
        STREG   %r27, TASK_PT_GR27(%r1)         /* user dp */
        STREG   %r28, TASK_PT_GR28(%r1)         /* return value 0 */
-       STREG   %r28, TASK_PT_ORIG_R28(%r1)     /* return value 0 (saved for signals) */
+       STREG   %r0, TASK_PT_ORIG_R28(%r1)     /* don't prohibit restarts */
        STREG   %r29, TASK_PT_GR29(%r1)         /* 8th argument */
        STREG   %r31, TASK_PT_GR31(%r1)         /* preserve syscall return ptr */
        
index 4383707d9801eb7bfe2b1bb34be6bbea447be139..818d6516567864cb0a4f52361ee863774e01dece 100644 (file)
@@ -2,3 +2,4 @@ include include/asm-generic/Kbuild.asm
 
 header-y += pdc.h
 generic-y += word-at-a-time.h
+generic-y += exec.h
diff --git a/arch/parisc/include/asm/exec.h b/arch/parisc/include/asm/exec.h
deleted file mode 100644 (file)
index 6bb5af7..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __PARISC_EXEC_H
-#define __PARISC_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* __PARISC_EXEC_H */
index 22b4726dee494403c80bdf2f88c583ba32043b94..d1fb79a36f3d32f1632772d6fb366b8416c96a17 100644 (file)
@@ -68,13 +68,16 @@ struct thread_info {
 #define _TIF_NEED_RESCHED      (1 << TIF_NEED_RESCHED)
 #define _TIF_POLLING_NRFLAG    (1 << TIF_POLLING_NRFLAG)
 #define _TIF_32BIT             (1 << TIF_32BIT)
-#define _TIF_RESTORE_SIGMASK   (1 << TIF_RESTORE_SIGMASK)
 #define _TIF_NOTIFY_RESUME     (1 << TIF_NOTIFY_RESUME)
 #define _TIF_SINGLESTEP                (1 << TIF_SINGLESTEP)
 #define _TIF_BLOCKSTEP         (1 << TIF_BLOCKSTEP)
 
 #define _TIF_USER_WORK_MASK     (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | \
                                  _TIF_NEED_RESCHED)
+#define _TIF_SYSCALL_TRACE_MASK (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP |        \
+                                _TIF_BLOCKSTEP)
+
+#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
 
 #endif /* __KERNEL__ */
 
index 594459bde14ed3c927b7dddce88e1d9cf9863e74..53799695599872565f1ad8c387cbf0e1b91ceb3d 100644 (file)
@@ -113,6 +113,8 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
                (usp - sigframe_size);
        DBG(2,"sys_rt_sigreturn: frame is %p\n", frame);
 
+       regs->orig_r28 = 1; /* no restarts for sigreturn */
+
 #ifdef CONFIG_64BIT
        compat_frame = (struct compat_rt_sigframe __user *)frame;
        
@@ -437,7 +439,7 @@ give_sigsegv:
  * OK, we're invoking a handler.
  */    
 
-static long
+static void
 handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
                struct pt_regs *regs, int in_syscall)
 {
@@ -447,7 +449,7 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
        
        /* Set up the stack frame */
        if (!setup_rt_frame(sig, ka, info, oldset, regs, in_syscall))
-               return 0;
+               return;
 
        signal_delivered(sig, info, ka, regs, 
                test_thread_flag(TIF_SINGLESTEP) ||
@@ -455,13 +457,14 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
 
        DBG(1,KERN_DEBUG "do_signal: Exit (success), regs->gr[28] = %ld\n",
                regs->gr[28]);
-
-       return 1;
 }
 
 static inline void
 syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
 {
+       if (regs->orig_r28)
+               return;
+       regs->orig_r28 = 1; /* no more restarts */
        /* Check the return code */
        switch (regs->gr[28]) {
        case -ERESTART_RESTARTBLOCK:
@@ -482,8 +485,6 @@ syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
                 * we have to do is fiddle the return pointer.
                 */
                regs->gr[31] -= 8; /* delayed branching */
-               /* Preserve original r28. */
-               regs->gr[28] = regs->orig_r28;
                break;
        }
 }
@@ -491,6 +492,9 @@ syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
 static inline void
 insert_restart_trampoline(struct pt_regs *regs)
 {
+       if (regs->orig_r28)
+               return;
+       regs->orig_r28 = 1; /* no more restarts */
        switch(regs->gr[28]) {
        case -ERESTART_RESTARTBLOCK: {
                /* Restart the system call - no handlers present */
@@ -525,9 +529,6 @@ insert_restart_trampoline(struct pt_regs *regs)
                flush_user_icache_range(regs->gr[30], regs->gr[30] + 4);
 
                regs->gr[31] = regs->gr[30] + 8;
-               /* Preserve original r28. */
-               regs->gr[28] = regs->orig_r28;
-
                return;
        }
        case -ERESTARTNOHAND:
@@ -539,9 +540,6 @@ insert_restart_trampoline(struct pt_regs *regs)
                 * slot of the branch external instruction.
                 */
                regs->gr[31] -= 8;
-               /* Preserve original r28. */
-               regs->gr[28] = regs->orig_r28;
-
                return;
        }
        default:
@@ -570,30 +568,17 @@ do_signal(struct pt_regs *regs, long in_syscall)
        DBG(1,"\ndo_signal: regs=0x%p, sr7 %#lx, in_syscall=%d\n",
               regs, regs->sr[7], in_syscall);
 
-       /* Everyone else checks to see if they are in kernel mode at
-          this point and exits if that's the case.  I'm not sure why
-          we would be called in that case, but for some reason we
-          are. */
-
-       /* May need to force signal if handle_signal failed to deliver */
-       while (1) {
-               signr = get_signal_to_deliver(&info, &ka, regs, NULL);
-               DBG(3,"do_signal: signr = %d, regs->gr[28] = %ld\n", signr, regs->gr[28]); 
+       signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+       DBG(3,"do_signal: signr = %d, regs->gr[28] = %ld\n", signr, regs->gr[28]); 
        
-               if (signr <= 0)
-                 break;
-               
+       if (signr > 0) {
                /* Restart a system call if necessary. */
                if (in_syscall)
                        syscall_restart(regs, &ka);
 
-               /* Whee!  Actually deliver the signal.  If the
-                  delivery failed, we need to continue to iterate in
-                  this loop so we can deliver the SIGSEGV... */
-               if (handle_signal(signr, &info, &ka, regs, in_syscall))
-                       return;
+               handle_signal(signr, &info, &ka, regs, in_syscall);
+               return;
        }
-       /* end of while(1) looping forever if we can't force a signal */
 
        /* Did we come from a system call? */
        if (in_syscall)
index 82a52b2fb13f296ef65726afc51b38f12e420047..86742df0b1941b4599c4cf0be76e9be48445bfef 100644 (file)
@@ -156,7 +156,7 @@ linux_gateway_entry:
        STREG   %r26, TASK_PT_GR26(%r1)         /* 1st argument */
        STREG   %r27, TASK_PT_GR27(%r1)         /* user dp */
        STREG   %r28, TASK_PT_GR28(%r1)         /* return value 0 */
-       STREG   %r28, TASK_PT_ORIG_R28(%r1)     /* return value 0 (saved for signals) */
+       STREG   %r0, TASK_PT_ORIG_R28(%r1)      /* don't prohibit restarts */
        STREG   %r29, TASK_PT_GR29(%r1)         /* return value 1 */
        STREG   %r31, TASK_PT_GR31(%r1)         /* preserve syscall return ptr */
        
@@ -180,9 +180,10 @@ linux_gateway_entry:
 
        /* Are we being ptraced? */
        mfctl   %cr30, %r1
-       LDREG   TI_TASK(%r1),%r1
-       ldw     TASK_PTRACE(%r1), %r1
-       bb,<,n  %r1,31,.Ltracesys
+       LDREG   TI_FLAGS(%r1),%r1
+       ldi     _TIF_SYSCALL_TRACE_MASK, %r19
+       and,COND(=) %r1, %r19, %r0
+       b,n     .Ltracesys
        
        /* Note!  We cannot use the syscall table that is mapped
        nearby since the gateway page is mapped execute-only. */
index 8d8a7c6a7066c7a160e5f172617063c687afe050..088fc76ce9f014c82ab7af20a518b771f57d61e6 100644 (file)
@@ -141,6 +141,7 @@ config PPC
        select GENERIC_STRNLEN_USER
        select HAVE_MOD_ARCH_SPECIFIC
        select MODULES_USE_ELF_RELA
+       select GENERIC_KERNEL_THREAD
 
 config EARLY_PRINTK
        bool
index 9dc5cd1fde1a9107614709d1082270361ac71882..8734b3855272b3583aa9ba7c723f5e6df01772b1 100644 (file)
@@ -74,9 +74,6 @@ struct task_struct;
 void start_thread(struct pt_regs *regs, unsigned long fdptr, unsigned long sp);
 void release_thread(struct task_struct *);
 
-/* Create a new kernel thread. */
-extern long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
-
 /* Lazy FPU handling on uni-processor */
 extern struct task_struct *last_task_used_math;
 extern struct task_struct *last_task_used_altivec;
index 9c21ed42aba6c593207d4b24b1b1523916c07716..f76b88c367d1615e994de316423b832121acdf63 100644 (file)
@@ -125,6 +125,8 @@ extern unsigned long ptrace_get_reg(struct task_struct *task, int regno);
 extern int ptrace_put_reg(struct task_struct *task, int regno,
                          unsigned long data);
 
+#define current_pt_regs() \
+       ((struct pt_regs *)((unsigned long)current_thread_info() + THREAD_SIZE) - 1)
 /*
  * We use the least-significant bit of the trap field to indicate
  * whether we have saved the full set of registers, or only a
index 4084e567d28ef0d41b4bc2834270bd80c7e1eaa4..329db4ec12ca855f2180a8edfe5f535a201d0015 100644 (file)
@@ -17,9 +17,6 @@ asmlinkage unsigned long sys_mmap(unsigned long addr, size_t len,
 asmlinkage unsigned long sys_mmap2(unsigned long addr, size_t len,
                unsigned long prot, unsigned long flags,
                unsigned long fd, unsigned long pgoff);
-asmlinkage int sys_execve(unsigned long a0, unsigned long a1,
-               unsigned long a2, unsigned long a3, unsigned long a4,
-               unsigned long a5, struct pt_regs *regs);
 asmlinkage int sys_clone(unsigned long clone_flags, unsigned long usp,
                int __user *parent_tidp, void __user *child_threadptr,
                int __user *child_tidp, int p6, struct pt_regs *regs);
index 8ceea14d6fe44a20d0d807e28a4ca63477f18863..406b7b9a13412f3736c369f500a5022e4955a928 100644 (file)
@@ -182,6 +182,8 @@ static inline bool test_thread_local_flags(unsigned int flags)
 #define is_32bit_task()        (1)
 #endif
 
+#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
+
 #endif /* !__ASSEMBLY__ */
 
 #endif /* __KERNEL__ */
index c683fa350add7f5f34547ff88f58233f1724c338..2533752af30f75dc63e333e48e7939e40ee85cb0 100644 (file)
 #define __ARCH_WANT_SYS_NEWFSTATAT
 #define __ARCH_WANT_COMPAT_SYS_SENDFILE
 #endif
+#define __ARCH_WANT_SYS_EXECVE
+#define __ARCH_WANT_KERNEL_EXECVE
 
 /*
  * "Conditional" syscalls
index af37528da49fff06ef7b47fb2e9add01dd6b1caa..9499385676e784362c20eade975ae396aaff144d 100644 (file)
@@ -435,6 +435,22 @@ ret_from_fork:
        li      r3,0
        b       ret_from_syscall
 
+       .globl  ret_from_kernel_thread
+ret_from_kernel_thread:
+       REST_NVGPRS(r1)
+       bl      schedule_tail
+       mtlr    r14
+       mr      r3,r15
+       PPC440EP_ERR42
+       blrl
+       li      r3,0
+       b       do_exit         # no return
+
+       .globl  __ret_from_kernel_execve
+__ret_from_kernel_execve:
+       addi    r1,r3,-STACK_FRAME_OVERHEAD
+       b       ret_from_syscall
+
 /* Traced system call support */
 syscall_dotrace:
        SAVE_NVGPRS(r1)
index 0e931aaffca20ad2213c1fb0dd2923e409cf75c9..56e0ff0878b5534c76b8c93818f7536498ce52df 100644 (file)
@@ -370,6 +370,22 @@ _GLOBAL(ret_from_fork)
        li      r3,0
        b       syscall_exit
 
+_GLOBAL(ret_from_kernel_thread)
+       bl      .schedule_tail
+       REST_NVGPRS(r1)
+       REST_GPR(2,r1)
+       mtlr    r14
+       mr      r3,r15
+       blrl
+       li      r3,0
+       b       .do_exit        # no return
+
+_GLOBAL(__ret_from_kernel_execve)
+       addi    r1,r3,-STACK_FRAME_OVERHEAD
+       li      r10,1
+       std     r10,SOFTE(r1)
+       b       syscall_exit
+
        .section        ".toc","aw"
 DSCR_DEFAULT:
        .tc dscr_default[TC],dscr_default
index ba16874fe294c003b6d28a65f25da53f8d23097a..7ce26d45777ef1d5497ab778eff937b11204aef3 100644 (file)
@@ -54,13 +54,6 @@ _GLOBAL(add_reloc_offset)
        .align  3
 2:     PPC_LONG 1b
 
-_GLOBAL(kernel_execve)
-       li      r0,__NR_execve
-       sc
-       bnslr
-       neg     r3,r3
-       blr
-
 _GLOBAL(setjmp)
        mflr    r0
        PPC_STL r0,0(r3)
index 407e293aad2fcad29c97be4d88961af12827f357..19e096bd0e73d8b9a530159a4b9b440efc25403f 100644 (file)
@@ -663,39 +663,6 @@ _GLOBAL(abs)
        sub     r3,r3,r4
        blr
 
-/*
- * Create a kernel thread
- *   kernel_thread(fn, arg, flags)
- */
-_GLOBAL(kernel_thread)
-       stwu    r1,-16(r1)
-       stw     r30,8(r1)
-       stw     r31,12(r1)
-       mr      r30,r3          /* function */
-       mr      r31,r4          /* argument */
-       ori     r3,r5,CLONE_VM  /* flags */
-       oris    r3,r3,CLONE_UNTRACED>>16
-       li      r4,0            /* new sp (unused) */
-       li      r0,__NR_clone
-       sc
-       bns+    1f              /* did system call indicate error? */
-       neg     r3,r3           /* if so, make return code negative */
-1:     cmpwi   0,r3,0          /* parent or child? */
-       bne     2f              /* return if parent */
-       li      r0,0            /* make top-level stack frame */
-       stwu    r0,-16(r1)
-       mtlr    r30             /* fn addr in lr */
-       mr      r3,r31          /* load arg and call fn */
-       PPC440EP_ERR42
-       blrl
-       li      r0,__NR_exit    /* exit if function returns */
-       li      r3,0
-       sc
-2:     lwz     r30,8(r1)
-       lwz     r31,12(r1)
-       addi    r1,r1,16
-       blr
-
 #ifdef CONFIG_SMP
 _GLOBAL(start_secondary_resume)
        /* Reset stack */
index 565b78625a32a149ce4959fb9610a46a82a5e04a..5cfa8008693b83aaae96dd4f5d91a7e8190d234b 100644 (file)
@@ -406,40 +406,6 @@ _GLOBAL(scom970_write)
 #endif /* CONFIG_CPU_FREQ_PMAC64 || CONFIG_CPU_FREQ_MAPLE */
 
 
-/*
- * Create a kernel thread
- *   kernel_thread(fn, arg, flags)
- */
-_GLOBAL(kernel_thread)
-       std     r29,-24(r1)
-       std     r30,-16(r1)
-       stdu    r1,-STACK_FRAME_OVERHEAD(r1)
-       mr      r29,r3
-       mr      r30,r4
-       ori     r3,r5,CLONE_VM  /* flags */
-       oris    r3,r3,(CLONE_UNTRACED>>16)
-       li      r4,0            /* new sp (unused) */
-       li      r0,__NR_clone
-       sc
-       bns+    1f              /* did system call indicate error? */
-       neg     r3,r3           /* if so, make return code negative */
-1:     cmpdi   0,r3,0          /* parent or child? */
-       bne     2f              /* return if parent */
-       li      r0,0
-       stdu    r0,-STACK_FRAME_OVERHEAD(r1)
-       ld      r2,8(r29)
-       ld      r29,0(r29)
-       mtlr    r29              /* fn addr in lr */
-       mr      r3,r30          /* load arg and call fn */
-       blrl
-       li      r0,__NR_exit    /* exit after child exits */
-        li     r3,0
-       sc
-2:     addi    r1,r1,STACK_FRAME_OVERHEAD
-       ld      r29,-24(r1)
-       ld      r30,-16(r1)
-       blr
-
 /*
  * disable_kernel_fp()
  * Disable the FPU.
index e597dde124e8736d09caf15a8f1012c443b820cc..78b8766fd79e4605f96a103c6562ff62caa37c5e 100644 (file)
@@ -95,7 +95,6 @@ EXPORT_SYMBOL(pci_dram_offset);
 #endif /* CONFIG_PCI */
 
 EXPORT_SYMBOL(start_thread);
-EXPORT_SYMBOL(kernel_thread);
 
 EXPORT_SYMBOL(giveup_fpu);
 #ifdef CONFIG_ALTIVEC
index d5ad666efd8b9a5fde3b93541fb774ae8459881f..ba48233500f6d47d7f2a554f5023f23060b5cff2 100644 (file)
@@ -733,30 +733,39 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
 extern unsigned long dscr_default; /* defined in arch/powerpc/kernel/sysfs.c */
 
 int copy_thread(unsigned long clone_flags, unsigned long usp,
-               unsigned long unused, struct task_struct *p,
+               unsigned long arg, struct task_struct *p,
                struct pt_regs *regs)
 {
        struct pt_regs *childregs, *kregs;
        extern void ret_from_fork(void);
+       extern void ret_from_kernel_thread(void);
+       void (*f)(void);
        unsigned long sp = (unsigned long)task_stack_page(p) + THREAD_SIZE;
 
-       CHECK_FULL_REGS(regs);
        /* Copy registers */
        sp -= sizeof(struct pt_regs);
        childregs = (struct pt_regs *) sp;
-       *childregs = *regs;
-       if ((childregs->msr & MSR_PR) == 0) {
+       if (!regs) {
                /* for kernel thread, set `current' and stackptr in new task */
+               memset(childregs, 0, sizeof(struct pt_regs));
                childregs->gpr[1] = sp + sizeof(struct pt_regs);
-#ifdef CONFIG_PPC32
-               childregs->gpr[2] = (unsigned long) p;
-#else
+#ifdef CONFIG_PPC64
+               childregs->gpr[14] = *(unsigned long *)usp;
+               childregs->gpr[2] = ((unsigned long *)usp)[1],
                clear_tsk_thread_flag(p, TIF_32BIT);
+#else
+               childregs->gpr[14] = usp;       /* function */
+               childregs->gpr[2] = (unsigned long) p;
 #endif
+               childregs->gpr[15] = arg;
                p->thread.regs = NULL;  /* no user register state */
+               f = ret_from_kernel_thread;
        } else {
+               CHECK_FULL_REGS(regs);
+               *childregs = *regs;
                childregs->gpr[1] = usp;
                p->thread.regs = childregs;
+               childregs->gpr[3] = 0;  /* Result from fork() */
                if (clone_flags & CLONE_SETTLS) {
 #ifdef CONFIG_PPC64
                        if (!is_32bit_task())
@@ -765,8 +774,9 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
 #endif
                                childregs->gpr[2] = childregs->gpr[6];
                }
+
+               f = ret_from_fork;
        }
-       childregs->gpr[3] = 0;  /* Result from fork() */
        sp -= STACK_FRAME_OVERHEAD;
 
        /*
@@ -805,19 +815,17 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
                p->thread.dscr = current->thread.dscr;
        }
 #endif
-
        /*
         * The PPC64 ABI makes use of a TOC to contain function 
         * pointers.  The function (ret_from_except) is actually a pointer
         * to the TOC entry.  The first entry is a pointer to the actual
         * function.
-        */
+        */
 #ifdef CONFIG_PPC64
-       kregs->nip = *((unsigned long *)ret_from_fork);
+       kregs->nip = *((unsigned long *)f);
 #else
-       kregs->nip = (unsigned long)ret_from_fork;
+       kregs->nip = (unsigned long)f;
 #endif
-
        return 0;
 }
 
@@ -1055,26 +1063,13 @@ int sys_vfork(unsigned long p1, unsigned long p2, unsigned long p3,
                        regs, 0, NULL, NULL);
 }
 
-int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
-              unsigned long a3, unsigned long a4, unsigned long a5,
-              struct pt_regs *regs)
+void __ret_from_kernel_execve(struct pt_regs *normal)
+__noreturn;
+
+void ret_from_kernel_execve(struct pt_regs *normal)
 {
-       int error;
-       char *filename;
-
-       filename = getname((const char __user *) a0);
-       error = PTR_ERR(filename);
-       if (IS_ERR(filename))
-               goto out;
-       flush_fp_to_thread(current);
-       flush_altivec_to_thread(current);
-       flush_spe_to_thread(current);
-       error = do_execve(filename,
-                         (const char __user *const __user *) a1,
-                         (const char __user *const __user *) a2, regs);
-       putname(filename);
-out:
-       return error;
+       set_thread_flag(TIF_RESTOREALL);
+       __ret_from_kernel_execve(normal);
 }
 
 static inline int valid_irq_stack(unsigned long sp, struct task_struct *p,
index 8b4c049aee20e8604fa83a9a017366213d0ab6d9..804e323c139d000fbc280742d9b1a6729271110e 100644 (file)
@@ -35,7 +35,6 @@
 #include <linux/stddef.h>
 #include <linux/tty.h>
 #include <linux/binfmts.h>
-#include <linux/freezer.h>
 #endif
 
 #include <asm/uaccess.h>
index abd1112da54f40b1b24a08a6a0732373ad95ef0e..9c2ed90ece8f4cdb93b75456f70376b944d52703 100644 (file)
@@ -156,28 +156,6 @@ asmlinkage long compat_sys_sendfile64_wrapper(u32 out_fd, u32 in_fd,
                            (off_t __user *)offset, count);
 }
 
-long compat_sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
-                 unsigned long a3, unsigned long a4, unsigned long a5,
-                 struct pt_regs *regs)
-{
-       int error;
-       char * filename;
-       
-       filename = getname((char __user *) a0);
-       error = PTR_ERR(filename);
-       if (IS_ERR(filename))
-               goto out;
-       flush_fp_to_thread(current);
-       flush_altivec_to_thread(current);
-
-       error = compat_do_execve(filename, compat_ptr(a1), compat_ptr(a2), regs);
-
-       putname(filename);
-
-out:
-       return error;
-}
-
 /* Note: it is necessary to treat option as an unsigned int, 
  * with the corresponding cast to a signed int to insure that the 
  * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
index de7ce84eae560b455cae1ce1764bdff1db838b2c..35eaaaa62d3f62320f893cba8340cbb57f01a330 100644 (file)
@@ -134,6 +134,7 @@ config S390
        select HAVE_ARCH_SECCOMP_FILTER
        select HAVE_MOD_ARCH_SPECIFIC
        select MODULES_USE_ELF_RELA
+       select GENERIC_KERNEL_THREAD
 
 config SCHED_OMIT_FRAME_POINTER
        def_bool y
index 56831dfa9198c6e2192605fd5ee9d68c538d8b17..94e749c90230d9f824949429d505625f90f7b4e7 100644 (file)
@@ -35,6 +35,7 @@ static inline void get_cpu_id(struct cpuid *ptr)
 extern void s390_adjust_jiffies(void);
 extern const struct seq_operations cpuinfo_op;
 extern int sysctl_ieee_emulation_warnings;
+extern void execve_tail(void);
 
 /*
  * User space process size: 2GB for 31 bit, 4TB or 8PT for 64 bit.
@@ -126,6 +127,7 @@ struct stack_frame {
        regs->psw.mask  = psw_user_bits | PSW_MASK_EA | PSW_MASK_BA;    \
        regs->psw.addr  = new_psw | PSW_ADDR_AMODE;                     \
        regs->gprs[15]  = new_stackp;                                   \
+       execve_tail();                                                  \
 } while (0)
 
 #define start_thread31(regs, new_psw, new_stackp) do {                 \
@@ -135,6 +137,7 @@ struct stack_frame {
        __tlb_flush_mm(current->mm);                                    \
        crst_table_downgrade(current->mm, 1UL << 31);                   \
        update_mm(current->mm, current);                                \
+       execve_tail();                                                  \
 } while (0)
 
 /* Forward declaration, a strange C thing */
@@ -150,7 +153,6 @@ static inline void show_cacheinfo(struct seq_file *m) { }
 
 /* Free all resources held by a thread. */
 extern void release_thread(struct task_struct *);
-extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
 
 /*
  * Return saved PC of a blocked thread.
index bb08e2afc5de6c570787ce518d7aeda778a28b92..9e2cfe0349c3c5f50177a870ba6061ec7bd85dd0 100644 (file)
@@ -91,8 +91,6 @@ static inline struct thread_info *current_thread_info(void)
 #define TIF_SYSCALL_AUDIT      9       /* syscall auditing active */
 #define TIF_SECCOMP            10      /* secure computing */
 #define TIF_SYSCALL_TRACEPOINT 11      /* syscall tracepoint instrumentation */
-#define TIF_POLLING_NRFLAG     16      /* true if poll_idle() is polling
-                                          TIF_NEED_RESCHED */
 #define TIF_31BIT              17      /* 32bit process */
 #define TIF_MEMDIE             18      /* is terminating due to OOM killer */
 #define TIF_RESTORE_SIGMASK    19      /* restore signal mask in do_signal() */
@@ -100,7 +98,6 @@ static inline struct thread_info *current_thread_info(void)
 
 #define _TIF_SYSCALL           (1<<TIF_SYSCALL)
 #define _TIF_NOTIFY_RESUME     (1<<TIF_NOTIFY_RESUME)
-#define _TIF_RESTORE_SIGMASK   (1<<TIF_RESTORE_SIGMASK)
 #define _TIF_SIGPENDING                (1<<TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED      (1<<TIF_NEED_RESCHED)
 #define _TIF_PER_TRAP          (1<<TIF_PER_TRAP)
@@ -109,7 +106,6 @@ static inline struct thread_info *current_thread_info(void)
 #define _TIF_SYSCALL_AUDIT     (1<<TIF_SYSCALL_AUDIT)
 #define _TIF_SECCOMP           (1<<TIF_SECCOMP)
 #define _TIF_SYSCALL_TRACEPOINT        (1<<TIF_SYSCALL_TRACEPOINT)
-#define _TIF_POLLING_NRFLAG    (1<<TIF_POLLING_NRFLAG)
 #define _TIF_31BIT             (1<<TIF_31BIT)
 #define _TIF_SINGLE_STEP       (1<<TIF_SINGLE_STEP)
 
index 4e64b5cd1558762016ef166b1a73022f9ccfc084..8192e292753ac7c45713a41886e29c98bf98db08 100644 (file)
 #   define __ARCH_WANT_COMPAT_SYS_TIME
 #   define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
 # endif
+#define __ARCH_WANT_SYS_EXECVE
+#define __ARCH_WANT_KERNEL_EXECVE
 
 /*
  * "Conditional" syscalls
index 189963c90c6eb09deb498947f057ae6ad3450f12..65cca95843e112d170c40535a95030a087614adb 100644 (file)
@@ -432,32 +432,6 @@ sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t __user *uinfo)
        return ret;
 }
 
-/*
- * sys32_execve() executes a new program after the asm stub has set
- * things up for us.  This should basically do what I want it to.
- */
-asmlinkage long sys32_execve(const char __user *name, compat_uptr_t __user *argv,
-                            compat_uptr_t __user *envp)
-{
-       struct pt_regs *regs = task_pt_regs(current);
-       char *filename;
-       long rc;
-
-       filename = getname(name);
-       rc = PTR_ERR(filename);
-       if (IS_ERR(filename))
-               return rc;
-       rc = compat_do_execve(filename, argv, envp, regs);
-       if (rc)
-               goto out;
-       current->thread.fp_regs.fpc=0;
-       asm volatile("sfpc %0,0" : : "d" (0));
-       rc = regs->gprs[2];
-out:
-       putname(filename);
-       return rc;
-}
-
 asmlinkage long sys32_pread64(unsigned int fd, char __user *ubuf,
                                size_t count, u32 poshi, u32 poslo)
 {
index 9635d759c2b9fbb107e39f326ff7b638bc353c36..5daff1d34b8e502919c62a2ad4a38a25fc216894 100644 (file)
@@ -193,8 +193,6 @@ long sys32_rt_sigprocmask(int how, compat_sigset_t __user *set,
                          compat_sigset_t __user *oset, size_t sigsetsize);
 long sys32_rt_sigpending(compat_sigset_t __user *set, size_t sigsetsize);
 long sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t __user *uinfo);
-long sys32_execve(const char __user *name, compat_uptr_t __user *argv,
-                 compat_uptr_t __user *envp);
 long sys32_init_module(void __user *umod, unsigned long len,
                       const char __user *uargs);
 long sys32_delete_module(const char __user *name_user, unsigned int flags);
index 3afba804fe97e9e9eb19ee9f2040cf3466f23361..ad79b846535c4d9345e884341f40481e9d38c492 100644 (file)
@@ -1576,7 +1576,7 @@ ENTRY(sys32_execve_wrapper)
        llgtr   %r2,%r2                 # char *
        llgtr   %r3,%r3                 # compat_uptr_t *
        llgtr   %r4,%r4                 # compat_uptr_t *
-       jg      sys32_execve            # branch to system call
+       jg      compat_sys_execve       # branch to system call
 
 ENTRY(sys_fanotify_init_wrapper)
        llgfr   %r2,%r2                 # unsigned int
index 870bad6d56fc4fb7a5a9e308446148a7efec6633..ef46f66bc0d6bdf0caa0dc4ecaae4225f3d3b1ef 100644 (file)
@@ -331,45 +331,38 @@ ENTRY(ret_from_fork)
        l       %r12,__LC_THREAD_INFO
        l       %r13,__LC_SVC_NEW_PSW+4
        tm      __PT_PSW+1(%r11),0x01   # forking a kernel thread ?
-       jo      0f
-       st      %r15,__PT_R15(%r11)     # store stack pointer for new kthread
-0:     l       %r1,BASED(.Lschedule_tail)
+       je      1f
+       l       %r1,BASED(.Lschedule_tail)
        basr    %r14,%r1                # call schedule_tail
        TRACE_IRQS_ON
        ssm     __LC_SVC_NEW_PSW        # reenable interrupts
        j       sysc_tracenogo
 
+1:     # it's a kernel thread
+       st      %r15,__PT_R15(%r11)     # store stack pointer for new kthread
+       l       %r1,BASED(.Lschedule_tail)
+       basr    %r14,%r1                # call schedule_tail
+       TRACE_IRQS_ON
+       ssm     __LC_SVC_NEW_PSW        # reenable interrupts
+       lm      %r9,%r11,__PT_R9(%r11)  # load gprs
+ENTRY(kernel_thread_starter)
+       la      %r2,0(%r10)
+       basr    %r14,%r9
+       la      %r2,0
+       br      %r11                    # do_exit
+
 #
 # kernel_execve function needs to deal with pt_regs that is not
 # at the usual place
 #
-ENTRY(kernel_execve)
-       stm     %r12,%r15,48(%r15)
-       lr      %r14,%r15
-       l       %r13,__LC_SVC_NEW_PSW+4
-       ahi     %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
-       st      %r14,__SF_BACKCHAIN(%r15)
-       la      %r12,STACK_FRAME_OVERHEAD(%r15)
-       xc      0(__PT_SIZE,%r12),0(%r12)
-       l       %r1,BASED(.Ldo_execve)
-       lr      %r5,%r12
-       basr    %r14,%r1                # call do_execve
-       ltr     %r2,%r2
-       je      0f
-       ahi     %r15,(STACK_FRAME_OVERHEAD + __PT_SIZE)
-       lm      %r12,%r15,48(%r15)
-       br      %r14
-       # execve succeeded.
-0:     ssm     __LC_PGM_NEW_PSW        # disable I/O and ext. interrupts
-       l       %r15,__LC_KERNEL_STACK  # load ksp
-       ahi     %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
-       la      %r11,STACK_FRAME_OVERHEAD(%r15)
-       mvc     0(__PT_SIZE,%r11),0(%r12)       # copy pt_regs
-       l       %r12,__LC_THREAD_INFO
+ENTRY(ret_from_kernel_execve)
+       ssm     __LC_PGM_NEW_PSW        # disable I/O and ext. interrupts
+       lr      %r15,%r2
+       lr      %r11,%r2
+       ahi     %r15,-STACK_FRAME_OVERHEAD
        xc      __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
+       l       %r12,__LC_THREAD_INFO
        ssm     __LC_SVC_NEW_PSW        # reenable interrupts
-       l       %r1,BASED(.Lexecve_tail)
-       basr    %r14,%r1                # call execve_tail
        j       sysc_return
 
 /*
@@ -931,8 +924,6 @@ cleanup_idle_wait:
 .Ldo_signal:           .long   do_signal
 .Ldo_notify_resume:    .long   do_notify_resume
 .Ldo_per_trap:         .long   do_per_trap
-.Ldo_execve:           .long   do_execve
-.Lexecve_tail:         .long   execve_tail
 .Ljump_table:          .long   pgm_check_table
 .Lschedule:            .long   schedule
 #ifdef CONFIG_PREEMPT
index a5f4dc42a5db18843e54972cfdfb28216a30daa2..d0d3f69a73463744edc3d3ec53fdd37dddd0adca 100644 (file)
@@ -58,9 +58,6 @@ long sys_fork(void);
 long sys_clone(unsigned long newsp, unsigned long clone_flags,
               int __user *parent_tidptr, int __user *child_tidptr);
 long sys_vfork(void);
-void execve_tail(void);
-long sys_execve(const char __user *name, const char __user *const __user *argv,
-               const char __user *const __user *envp);
 long sys_sigsuspend(int history0, int history1, old_sigset_t mask);
 long sys_sigaction(int sig, const struct old_sigaction __user *act,
                   struct old_sigaction __user *oact);
index 7549985402f726515e49694708957e710c50e17e..f9761f806c9e52cee8b4d3270055198cab63845c 100644 (file)
@@ -353,41 +353,31 @@ ENTRY(ret_from_fork)
        la      %r11,STACK_FRAME_OVERHEAD(%r15)
        lg      %r12,__LC_THREAD_INFO
        tm      __PT_PSW+1(%r11),0x01   # forking a kernel thread ?
-       jo      0f
-       stg     %r15,__PT_R15(%r11)     # store stack pointer for new kthread
-0:     brasl   %r14,schedule_tail
+       je      1f
+       brasl   %r14,schedule_tail
        TRACE_IRQS_ON
        ssm     __LC_SVC_NEW_PSW        # reenable interrupts
        j       sysc_tracenogo
-
-#
-# kernel_execve function needs to deal with pt_regs that is not
-# at the usual place
-#
-ENTRY(kernel_execve)
-       stmg    %r12,%r15,96(%r15)
-       lgr     %r14,%r15
-       aghi    %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
-       stg     %r14,__SF_BACKCHAIN(%r15)
-       la      %r12,STACK_FRAME_OVERHEAD(%r15)
-       xc      0(__PT_SIZE,%r12),0(%r12)
-       lgr     %r5,%r12
-       brasl   %r14,do_execve
-       ltgfr   %r2,%r2
-       je      0f
-       aghi    %r15,(STACK_FRAME_OVERHEAD + __PT_SIZE)
-       lmg     %r12,%r15,96(%r15)
-       br      %r14
-       # execve succeeded.
-0:     ssm     __LC_PGM_NEW_PSW        # disable I/O and ext. interrupts
-       lg      %r15,__LC_KERNEL_STACK  # load ksp
-       aghi    %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
-       la      %r11,STACK_FRAME_OVERHEAD(%r15)
-       mvc     0(__PT_SIZE,%r11),0(%r12)       # copy pt_regs
-       lg      %r12,__LC_THREAD_INFO
+1:     # it's a kernel thread
+       stg     %r15,__PT_R15(%r11)     # store stack pointer for new kthread
+       brasl   %r14,schedule_tail
+       TRACE_IRQS_ON
+       ssm     __LC_SVC_NEW_PSW        # reenable interrupts
+       lmg     %r9,%r11,__PT_R9(%r11)  # load gprs
+ENTRY(kernel_thread_starter)
+       la      %r2,0(%r10)
+       basr    %r14,%r9
+       la      %r2,0
+       br      %r11                    # do_exit
+
+ENTRY(ret_from_kernel_execve)
+       ssm     __LC_PGM_NEW_PSW        # disable I/O and ext. interrupts
+       lgr     %r15,%r2
+       lgr     %r11,%r2
+       aghi    %r15,-STACK_FRAME_OVERHEAD
        xc      __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
+       lg      %r12,__LC_THREAD_INFO
        ssm     __LC_SVC_NEW_PSW        # reenable interrupts
-       brasl   %r14,execve_tail
        j       sysc_return
 
 /*
index 5024be27df444b3dedc669f823734404fcb0fe4c..cd31ad457a9bdb7890a0ff7eae840a63f5f0f48f 100644 (file)
@@ -100,35 +100,6 @@ void cpu_idle(void)
 
 extern void __kprobes kernel_thread_starter(void);
 
-asm(
-       ".section .kprobes.text, \"ax\"\n"
-       ".global kernel_thread_starter\n"
-       "kernel_thread_starter:\n"
-       "    la    2,0(10)\n"
-       "    basr  14,9\n"
-       "    la    2,0\n"
-       "    br    11\n"
-       ".previous\n");
-
-int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
-{
-       struct pt_regs regs;
-
-       memset(&regs, 0, sizeof(regs));
-       regs.psw.mask = psw_kernel_bits |
-               PSW_MASK_DAT | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK;
-       regs.psw.addr = (unsigned long) kernel_thread_starter | PSW_ADDR_AMODE;
-       regs.gprs[9] = (unsigned long) fn;
-       regs.gprs[10] = (unsigned long) arg;
-       regs.gprs[11] = (unsigned long) do_exit;
-       regs.orig_gpr2 = -1;
-
-       /* Ok, create the new process.. */
-       return do_fork(flags | CLONE_VM | CLONE_UNTRACED,
-                      0, &regs, 0, NULL, NULL);
-}
-EXPORT_SYMBOL(kernel_thread);
-
 /*
  * Free current thread data structures etc..
  */
@@ -146,7 +117,7 @@ void release_thread(struct task_struct *dead_task)
 }
 
 int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
-               unsigned long unused,
+               unsigned long arg,
                struct task_struct *p, struct pt_regs *regs)
 {
        struct thread_info *ti;
@@ -158,20 +129,44 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
 
        frame = container_of(task_pt_regs(p), struct fake_frame, childregs);
        p->thread.ksp = (unsigned long) frame;
-       /* Store access registers to kernel stack of new process. */
-       frame->childregs = *regs;
-       frame->childregs.gprs[2] = 0;   /* child returns 0 on fork. */
-       frame->childregs.gprs[15] = new_stackp;
-       frame->sf.back_chain = 0;
+       /* Save access registers to new thread structure. */
+       save_access_regs(&p->thread.acrs[0]);
+       /* start new process with ar4 pointing to the correct address space */
+       p->thread.mm_segment = get_fs();
+       /* Don't copy debug registers */
+       memset(&p->thread.per_user, 0, sizeof(p->thread.per_user));
+       memset(&p->thread.per_event, 0, sizeof(p->thread.per_event));
+       clear_tsk_thread_flag(p, TIF_SINGLE_STEP);
+       clear_tsk_thread_flag(p, TIF_PER_TRAP);
+       /* Initialize per thread user and system timer values */
+       ti = task_thread_info(p);
+       ti->user_timer = 0;
+       ti->system_timer = 0;
 
+       frame->sf.back_chain = 0;
        /* new return point is ret_from_fork */
        frame->sf.gprs[8] = (unsigned long) ret_from_fork;
-
        /* fake return stack for resume(), don't go back to schedule */
        frame->sf.gprs[9] = (unsigned long) frame;
 
-       /* Save access registers to new thread structure. */
-       save_access_regs(&p->thread.acrs[0]);
+       /* Store access registers to kernel stack of new process. */
+       if (unlikely(!regs)) {
+               /* kernel thread */
+               memset(&frame->childregs, 0, sizeof(struct pt_regs));
+               frame->childregs.psw.mask = psw_kernel_bits | PSW_MASK_DAT |
+                               PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK;
+               frame->childregs.psw.addr = PSW_ADDR_AMODE |
+                               (unsigned long) kernel_thread_starter;
+               frame->childregs.gprs[9] = new_stackp; /* function */
+               frame->childregs.gprs[10] = arg;
+               frame->childregs.gprs[11] = (unsigned long) do_exit;
+               frame->childregs.orig_gpr2 = -1;
+
+               return 0;
+       }
+       frame->childregs = *regs;
+       frame->childregs.gprs[2] = 0;   /* child returns 0 on fork. */
+       frame->childregs.gprs[15] = new_stackp;
 
        /* Don't copy runtime instrumentation info */
        p->thread.ri_cb = NULL;
@@ -202,17 +197,6 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
                }
        }
 #endif /* CONFIG_64BIT */
-       /* start new process with ar4 pointing to the correct address space */
-       p->thread.mm_segment = get_fs();
-       /* Don't copy debug registers */
-       memset(&p->thread.per_user, 0, sizeof(p->thread.per_user));
-       memset(&p->thread.per_event, 0, sizeof(p->thread.per_event));
-       clear_tsk_thread_flag(p, TIF_SINGLE_STEP);
-       clear_tsk_thread_flag(p, TIF_PER_TRAP);
-       /* Initialize per thread user and system timer values */
-       ti = task_thread_info(p);
-       ti->user_timer = 0;
-       ti->system_timer = 0;
        return 0;
 }
 
@@ -257,31 +241,6 @@ asmlinkage void execve_tail(void)
                asm volatile("sfpc %0,%0" : : "d" (0));
 }
 
-/*
- * sys_execve() executes a new program.
- */
-SYSCALL_DEFINE3(execve, const char __user *, name,
-               const char __user *const __user *, argv,
-               const char __user *const __user *, envp)
-{
-       struct pt_regs *regs = task_pt_regs(current);
-       char *filename;
-       long rc;
-
-       filename = getname(name);
-       rc = PTR_ERR(filename);
-       if (IS_ERR(filename))
-               return rc;
-       rc = do_execve(filename, argv, envp, regs);
-       if (rc)
-               goto out;
-       execve_tail();
-       rc = regs->gprs[2];
-out:
-       putname(filename);
-       return rc;
-}
-
 /*
  * fill in the FPU structure for a core dump.
  */
index a18006e97f1c31ccbb2b23f1c5e270a28a33d8cb..1425cc034872e5993320e6722f4965bdb34f1189 100644 (file)
@@ -86,16 +86,12 @@ register struct thread_info *__current_thread_info __asm__("r28");
 #define TIF_NEED_RESCHED       2       /* rescheduling necessary */
 #define TIF_NOTIFY_RESUME      5       /* callback before returning to user */
 #define TIF_RESTORE_SIGMASK    9       /* restore signal mask in do_signal() */
-#define TIF_POLLING_NRFLAG     17      /* true if poll_idle() is polling
-                                                TIF_NEED_RESCHED */
 #define TIF_MEMDIE             18      /* is terminating due to OOM killer */
 
 #define _TIF_SYSCALL_TRACE     (1<<TIF_SYSCALL_TRACE)
 #define _TIF_SIGPENDING                (1<<TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED      (1<<TIF_NEED_RESCHED)
 #define _TIF_NOTIFY_RESUME     (1<<TIF_NOTIFY_RESUME)
-#define _TIF_RESTORE_SIGMASK   (1<<TIF_RESTORE_SIGMASK)
-#define _TIF_POLLING_NRFLAG    (1<<TIF_POLLING_NRFLAG)
 
 #define _TIF_WORK_MASK         (0x0000ffff)
 
index e382c52ca0d90b455d9bee68f7587f4278d36bc8..c268bbf8b41047b2717a5a41a7ed86178a7df24e 100644 (file)
@@ -174,6 +174,7 @@ score_rt_sigreturn(struct pt_regs *regs)
        /* It is more difficult to avoid calling this function than to
           call it and ignore errors.  */
        do_sigaltstack((stack_t __user *)&st, NULL, regs->regs[0]);
+       regs->is_syscall = 0;
 
        __asm__ __volatile__(
                "mv\tr0, %0\n\t"
index 7b673ddcd5551cc887cbd393c331056c6c1cc20b..86eadceff097481b4ba5ce3494d60134f50e02ae 100644 (file)
@@ -7,6 +7,7 @@ generic-y += delay.h
 generic-y += div64.h
 generic-y += emergency-restart.h
 generic-y += errno.h
+generic-y += exec.h
 generic-y += fcntl.h
 generic-y += ioctl.h
 generic-y += ipcbuf.h
diff --git a/arch/sh/include/asm/exec.h b/arch/sh/include/asm/exec.h
deleted file mode 100644 (file)
index 69486a9..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * Copyright (C) 1999, 2000  Niibe Yutaka  &  Kaz Kojima
- * Copyright (C) 2002 Paul Mundt
- */
-#ifndef __ASM_SH_EXEC_H
-#define __ASM_SH_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* __ASM_SH_EXEC_H */
index bc13b57cdc834210b95aaa70ea603298ed55f468..7d5ac4e4848518118ad07fce5eb34a763bd6d405 100644 (file)
@@ -206,6 +206,9 @@ static inline bool test_and_clear_restore_sigmask(void)
        ti->status &= ~TS_RESTORE_SIGMASK;
        return true;
 }
+
+#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
+
 #endif /* !__ASSEMBLY__ */
 
 #endif /* __KERNEL__ */
index d6b7b6154f8764576abac916033326ba1c1e6bd2..2f1f65356c0c39005a605c77f285e614019d387b 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/elf.h>
 #include <linux/personality.h>
 #include <linux/binfmts.h>
-#include <linux/freezer.h>
 #include <linux/io.h>
 #include <linux/tracehook.h>
 #include <asm/ucontext.h>
index 6b5b3dfe886b2d3c15a4b08a4d4f21ab74e90da0..23853814bd174284a3a75c62b88154ac8fb890d3 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/errno.h>
 #include <linux/wait.h>
 #include <linux/personality.h>
-#include <linux/freezer.h>
 #include <linux/ptrace.h>
 #include <linux/unistd.h>
 #include <linux/stddef.h>
index fbe1cb578fcd0fcdceeaa637724fdf13bbb12958..c5833f42783ef95fa2bbe01603c270d2eb6f202f 100644 (file)
@@ -18,6 +18,7 @@ header-y += utrap.h
 header-y += watchdog.h
 
 generic-y += div64.h
+generic-y += exec.h
 generic-y += local64.h
 generic-y += irq_regs.h
 generic-y += local.h
diff --git a/arch/sparc/include/asm/exec.h b/arch/sparc/include/asm/exec.h
deleted file mode 100644 (file)
index 2e08588..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __SPARC_EXEC_H
-#define __SPARC_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* __SPARC_EXEC_H */
index e6cd224506a9355168ebea0c5ed0be8c3b625120..25849ae3e900305e86a138fabebb6b2484a1a07f 100644 (file)
@@ -126,13 +126,14 @@ register struct thread_info *current_thread_info_reg asm("g6");
 #define _TIF_NOTIFY_RESUME     (1<<TIF_NOTIFY_RESUME)
 #define _TIF_SIGPENDING                (1<<TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED      (1<<TIF_NEED_RESCHED)
-#define _TIF_RESTORE_SIGMASK   (1<<TIF_RESTORE_SIGMASK)
 #define _TIF_USEDFPU           (1<<TIF_USEDFPU)
 #define _TIF_POLLING_NRFLAG    (1<<TIF_POLLING_NRFLAG)
 
 #define _TIF_DO_NOTIFY_RESUME_MASK     (_TIF_NOTIFY_RESUME | \
                                         _TIF_SIGPENDING)
 
+#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
+
 #endif /* __KERNEL__ */
 
 #endif /* _ASM_THREAD_INFO_H */
index cfa8c38fb9c8511d51cfbe17e3d8792584d8b241..4e227663108181b45700b0cb879d5043ee1da64b 100644 (file)
@@ -256,6 +256,9 @@ static inline bool test_and_clear_restore_sigmask(void)
        ti->status &= ~TS_RESTORE_SIGMASK;
        return true;
 }
+
+#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
+
 #endif /* !__ASSEMBLY__ */
 
 #endif /* __KERNEL__ */
index 5bd71994452d588d4790585f76a9cd5dfd35e185..5a5e6796a312c89a6a480b05bc7e6b280c1da3b2 100644 (file)
@@ -12,6 +12,7 @@ generic-y += cputime.h
 generic-y += div64.h
 generic-y += emergency-restart.h
 generic-y += errno.h
+generic-y += exec.h
 generic-y += fb.h
 generic-y += fcntl.h
 generic-y += ioctl.h
diff --git a/arch/tile/include/asm/exec.h b/arch/tile/include/asm/exec.h
deleted file mode 100644 (file)
index a714e19..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright 2010 Tilera Corporation. All Rights Reserved.
- *
- *   This program is free software; you can redistribute it and/or
- *   modify it under the terms of the GNU General Public License
- *   as published by the Free Software Foundation, version 2.
- *
- *   This program is distributed in the hope that it will be useful, but
- *   WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- *   NON INFRINGEMENT.  See the GNU General Public License for
- *   more details.
- */
-
-#ifndef _ASM_TILE_EXEC_H
-#define _ASM_TILE_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* _ASM_TILE_EXEC_H */
index 474571b8408584d37743678ce02b2ca77c3c9938..3690f0199f09af6629f2ed3dd1c18b7805da1725 100644 (file)
@@ -411,15 +411,6 @@ int compat_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        regs->regs[1] = ptr_to_compat_reg(&frame->info);
        regs->regs[2] = ptr_to_compat_reg(&frame->uc);
        regs->flags |= PT_FLAGS_CALLER_SAVES;
-
-       /*
-        * Notify any tracer that was single-stepping it.
-        * The tracer may want to single-step inside the
-        * handler too.
-        */
-       if (test_thread_flag(TIF_SINGLESTEP))
-               ptrace_notify(SIGTRAP);
-
        return 0;
 
 give_sigsegv:
index e29b0553211d611af9802dfe190f9d0d9d868f69..67efb656d10451946baa827066811948dc45b2d6 100644 (file)
@@ -219,15 +219,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        regs->regs[1] = (unsigned long) &frame->info;
        regs->regs[2] = (unsigned long) &frame->uc;
        regs->flags |= PT_FLAGS_CALLER_SAVES;
-
-       /*
-        * Notify any tracer that was single-stepping it.
-        * The tracer may want to single-step inside the
-        * handler too.
-        */
-       if (test_thread_flag(TIF_SINGLESTEP))
-               ptrace_notify(SIGTRAP);
-
        return 0;
 
 give_sigsegv:
@@ -278,7 +269,8 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
                ret = setup_rt_frame(sig, ka, info, oldset, regs);
        if (ret)
                return;
-       signal_delivered(sig, info, ka, regs, 0);
+       signal_delivered(sig, info, ka, regs,
+                       test_thread_flag(TIF_SINGLESTEP));
 }
 
 /*
index 33a6a2423bd25638a2b93f20fdc77bcf6e0f1737..5d9ab0c4f4887594989273a5bd8fac1a5eb35140 100644 (file)
@@ -63,8 +63,6 @@ static inline void release_thread(struct task_struct *task)
 {
 }
 
-extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-
 extern unsigned long thread_saved_pc(struct task_struct *t);
 
 static inline void mm_copy_segments(struct mm_struct *from_mm,
index c04e5ab68f56a3f14d3831c501c3af66b0d2610b..2c8eeb2df8b43a6c21b4b10da99fe1042276229f 100644 (file)
@@ -65,8 +65,6 @@ static inline struct thread_info *current_thread_info(void)
 #define TIF_SYSCALL_TRACE      0       /* syscall trace active */
 #define TIF_SIGPENDING         1       /* signal pending */
 #define TIF_NEED_RESCHED       2       /* rescheduling necessary */
-#define TIF_POLLING_NRFLAG      3       /* true if poll_idle() is polling
-                                        * TIF_NEED_RESCHED */
 #define TIF_RESTART_BLOCK      4
 #define TIF_MEMDIE             5       /* is terminating due to OOM killer */
 #define TIF_SYSCALL_AUDIT      6
@@ -76,7 +74,6 @@ static inline struct thread_info *current_thread_info(void)
 #define _TIF_SYSCALL_TRACE     (1 << TIF_SYSCALL_TRACE)
 #define _TIF_SIGPENDING                (1 << TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED      (1 << TIF_NEED_RESCHED)
-#define _TIF_POLLING_NRFLAG     (1 << TIF_POLLING_NRFLAG)
 #define _TIF_MEMDIE            (1 << TIF_MEMDIE)
 #define _TIF_SYSCALL_AUDIT     (1 << TIF_SYSCALL_AUDIT)
 
index 8c82786da823df2cdf53ad9361b9b950d85018c7..e427301f55d6b789639d3948b48b9c50447f248b 100644 (file)
@@ -16,7 +16,6 @@
 #include "mem_user.h"
 #include "skas.h"
 #include "os.h"
-#include "internal.h"
 
 void flush_thread(void)
 {
@@ -49,27 +48,7 @@ void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp)
 }
 EXPORT_SYMBOL(start_thread);
 
-long um_execve(const char *file, const char __user *const __user *argv, const char __user *const __user *env)
+void __noreturn ret_from_kernel_execve(struct pt_regs *unused)
 {
-       long err;
-
-       err = do_execve(file, argv, env, &current->thread.regs);
-       if (!err)
-               UML_LONGJMP(current->thread.exec_buf, 1);
-       return err;
-}
-
-long sys_execve(const char __user *file, const char __user *const __user *argv,
-               const char __user *const __user *env)
-{
-       long error;
-       char *filename;
-
-       filename = getname(file);
-       error = PTR_ERR(filename);
-       if (IS_ERR(filename)) goto out;
-       error = do_execve(filename, argv, env, &current->thread.regs);
-       putname(filename);
- out:
-       return error;
+       UML_LONGJMP(current->thread.exec_buf, 1);
 }
diff --git a/arch/um/kernel/internal.h b/arch/um/kernel/internal.h
deleted file mode 100644 (file)
index 5bf97db..0000000
+++ /dev/null
@@ -1 +0,0 @@
-extern long um_execve(const char *file, const char __user *const __user *argv, const char __user *const __user *env);
index c5f5afa5074571c2b5872bc157c9f199a80c9f5b..a1b50add48a299feb1b3c88b8a2d1c73ce477c85 100644 (file)
@@ -69,18 +69,6 @@ unsigned long alloc_stack(int order, int atomic)
        return page;
 }
 
-int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
-{
-       int pid;
-
-       current->thread.request.u.thread.proc = fn;
-       current->thread.request.u.thread.arg = arg;
-       pid = do_fork(CLONE_VM | CLONE_UNTRACED | flags, 0,
-                     &current->thread.regs, 0, NULL, NULL);
-       return pid;
-}
-EXPORT_SYMBOL(kernel_thread);
-
 static inline void set_current(struct task_struct *task)
 {
        cpu_tasks[task_thread_info(task)->cpu] = ((struct cpu_task)
@@ -177,7 +165,7 @@ void fork_handler(void)
 }
 
 int copy_thread(unsigned long clone_flags, unsigned long sp,
-               unsigned long stack_top, struct task_struct * p,
+               unsigned long arg, struct task_struct * p,
                struct pt_regs *regs)
 {
        void (*handler)(void);
@@ -198,7 +186,8 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
                arch_copy_thread(&current->thread.arch, &p->thread.arch);
        } else {
                get_safe_registers(p->thread.regs.regs.gp, p->thread.regs.regs.fp);
-               p->thread.request.u.thread = current->thread.request.u.thread;
+               p->thread.request.u.thread.proc = (int (*)(void *))sp;
+               p->thread.request.u.thread.arg = (void *)arg;
                handler = new_thread_handler;
        }
 
index a4c6d8eee74c702999cc26955e250f40db30f553..a5639c4727729562f74728e5c93d5d3517bbfb1d 100644 (file)
@@ -13,7 +13,6 @@
 #include "asm/mman.h"
 #include "asm/uaccess.h"
 #include "asm/unistd.h"
-#include "internal.h"
 
 long sys_fork(void)
 {
@@ -50,19 +49,3 @@ long old_mmap(unsigned long addr, unsigned long len,
  out:
        return err;
 }
-
-int kernel_execve(const char *filename,
-                 const char *const argv[],
-                 const char *const envp[])
-{
-       mm_segment_t fs;
-       int ret;
-
-       fs = get_fs();
-       set_fs(KERNEL_DS);
-       ret = um_execve(filename, (const char __user *const __user *)argv,
-                       (const char __user *const __user *) envp);
-       set_fs(fs);
-
-       return ret;
-}
index 34b789b711151edf6d86e02c8122bd2f40d0896a..90a01c83a036e7298e332f90b8a0380fa6af0086 100644 (file)
@@ -10,6 +10,7 @@ generic-y += device.h
 generic-y += div64.h
 generic-y += emergency-restart.h
 generic-y += errno.h
+generic-y += exec.h
 generic-y += fb.h
 generic-y += fcntl.h
 generic-y += ftrace.h
diff --git a/arch/unicore32/include/asm/exec.h b/arch/unicore32/include/asm/exec.h
deleted file mode 100644 (file)
index 06d1f0f..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Process execution bits for PKUnity SoC and UniCore ISA
- *
- * Copyright (C) 2001-2012 GUAN Xue-tao
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#ifndef __UNICORE_EXEC_H__
-#define __UNICORE_EXEC_H__
-
-#define arch_align_stack(x)            (x)
-
-#endif /* __UNICORE_EXEC_H__ */
index 89f7557583b82d9bfe86d6bd967251c99e66de0b..818b4a1edb5b1bd26e3d8eb7baffe212df50a6f0 100644 (file)
@@ -141,12 +141,12 @@ static inline struct thread_info *current_thread_info(void)
 #define _TIF_NEED_RESCHED      (1 << TIF_NEED_RESCHED)
 #define _TIF_NOTIFY_RESUME     (1 << TIF_NOTIFY_RESUME)
 #define _TIF_SYSCALL_TRACE     (1 << TIF_SYSCALL_TRACE)
-#define _TIF_RESTORE_SIGMASK   (1 << TIF_RESTORE_SIGMASK)
 
 /*
  * Change these and you break ASM code in entry-common.S
  */
-#define _TIF_WORK_MASK         0x000000ff
+#define _TIF_WORK_MASK \
+       (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_NOTIFY_RESUME)
 
 #endif /* __KERNEL__ */
 #endif /* __UNICORE_THREAD_INFO_H__ */
index 00a259f9819e147dc77e22802594bc48a2d042f7..dcb87ab19ddd8b5912dfa2d765c4158fa1bbad73 100644 (file)
@@ -544,8 +544,6 @@ fast_work_pending:
 work_pending:
        cand.a  r1, #_TIF_NEED_RESCHED
        bne     work_resched
-       cand.a  r1, #_TIF_SIGPENDING|_TIF_NOTIFY_RESUME
-       beq     no_work_pending
        mov     r0, sp                          @ 'regs'
        mov     r2, why                         @ 'syscall'
        cand.a  r1, #_TIF_SIGPENDING            @ delivering a signal?
index 8adedb37720a0e997dea9ea88abff76113904830..b8b2ffd774d637bdf55a35bc2a5116d8872904c8 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/errno.h>
 #include <linux/signal.h>
 #include <linux/personality.h>
-#include <linux/freezer.h>
 #include <linux/uaccess.h>
 #include <linux/tracehook.h>
 #include <linux/elf.h>
index 3afe60a39ac992178554f6e3bbd23900918cffd9..5fd9af773e15f2752002555b1af787c6a610d334 100644 (file)
@@ -104,7 +104,6 @@ int kernel_execve(const char *filename,
  out:
        return ret;
 }
-EXPORT_SYMBOL(kernel_execve);
 
 /* Note: used by the compat code even in 64-bit Linux. */
 SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
index 3ba3813932ba125ff8e793feff41428fbb92f088..8fc92d61a78677d1c55241721bf1706e845076b6 100644 (file)
@@ -106,6 +106,7 @@ config X86
        select MODULES_USE_ELF_RELA if X86_64
        select HAVE_RCU_USER_QS if X86_64
        select HAVE_IRQ_TIME_ACCOUNTING
+       select GENERIC_KERNEL_THREAD
 
 config INSTRUCTION_DECODER
        def_bool y
index 9c289504e680303a2bdfed3308eb40eb35135176..076745fc8045a8c35d1df646ede41d3c191c52e6 100644 (file)
@@ -465,7 +465,7 @@ GLOBAL(\label)
        PTREGSCALL stub32_rt_sigreturn, sys32_rt_sigreturn, %rdi
        PTREGSCALL stub32_sigreturn, sys32_sigreturn, %rdi
        PTREGSCALL stub32_sigaltstack, sys32_sigaltstack, %rdx
-       PTREGSCALL stub32_execve, sys32_execve, %rcx
+       PTREGSCALL stub32_execve, compat_sys_execve, %rcx
        PTREGSCALL stub32_fork, sys_fork, %rdi
        PTREGSCALL stub32_clone, sys32_clone, %rdx
        PTREGSCALL stub32_vfork, sys_vfork, %rdi
index c5b938d92eab3c3eb07294fdc425b8e756f776b6..86d68d1c8806b27fdf5506d0807d6fe874b48438 100644 (file)
@@ -385,21 +385,6 @@ asmlinkage long sys32_sendfile(int out_fd, int in_fd,
        return ret;
 }
 
-asmlinkage long sys32_execve(const char __user *name, compat_uptr_t __user *argv,
-                            compat_uptr_t __user *envp, struct pt_regs *regs)
-{
-       long error;
-       char *filename;
-
-       filename = getname(name);
-       error = PTR_ERR(filename);
-       if (IS_ERR(filename))
-               return error;
-       error = compat_do_execve(filename, argv, envp, regs);
-       putname(filename);
-       return error;
-}
-
 asmlinkage long sys32_clone(unsigned int clone_flags, unsigned int newsp,
                            struct pt_regs *regs)
 {
index b98c0d958ebbdf830536ad42e3d166c198c1d29e..ad1fc85116743d677ff5b050e7226c2988a5e559 100644 (file)
@@ -588,11 +588,6 @@ typedef struct {
 } mm_segment_t;
 
 
-/*
- * create a kernel thread without removing it from tasklists
- */
-extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
-
 /* Free all resources held by a thread. */
 extern void release_thread(struct task_struct *);
 
index 4ca1c611b55202cfa6df55c37032cce27eca86b8..a9a8cf3da49d72ae78eb3e98af8ad3e0523ce6e3 100644 (file)
@@ -54,8 +54,6 @@ asmlinkage long sys32_pwrite(unsigned int, const char __user *, u32, u32, u32);
 asmlinkage long sys32_personality(unsigned long);
 asmlinkage long sys32_sendfile(int, int, compat_off_t __user *, s32);
 
-asmlinkage long sys32_execve(const char __user *, compat_uptr_t __user *,
-                            compat_uptr_t __user *, struct pt_regs *);
 asmlinkage long sys32_clone(unsigned int, unsigned int, struct pt_regs *);
 
 long sys32_lseek(unsigned int, int, unsigned int);
index f1d8b441fc775b4920b7397d6a151d2eed314a09..2be0b880417e62b3b827fd5b68f18521a4625777 100644 (file)
@@ -25,7 +25,7 @@ int sys_fork(struct pt_regs *);
 int sys_vfork(struct pt_regs *);
 long sys_execve(const char __user *,
                const char __user *const __user *,
-               const char __user *const __user *, struct pt_regs *);
+               const char __user *const __user *);
 long sys_clone(unsigned long, unsigned long, void __user *,
               void __user *, struct pt_regs *);
 
index c535d847e3b5f75dff0d8d2dd7988935fc35b63f..2d946e63ee82bceca34043aff29958b5e0e34127 100644 (file)
@@ -79,7 +79,6 @@ struct thread_info {
 #define TIF_SIGPENDING         2       /* signal pending */
 #define TIF_NEED_RESCHED       3       /* rescheduling necessary */
 #define TIF_SINGLESTEP         4       /* reenable singlestep on user return*/
-#define TIF_IRET               5       /* force IRET */
 #define TIF_SYSCALL_EMU                6       /* syscall emulation active */
 #define TIF_SYSCALL_AUDIT      7       /* syscall auditing active */
 #define TIF_SECCOMP            8       /* secure computing */
@@ -105,7 +104,6 @@ struct thread_info {
 #define _TIF_SIGPENDING                (1 << TIF_SIGPENDING)
 #define _TIF_SINGLESTEP                (1 << TIF_SINGLESTEP)
 #define _TIF_NEED_RESCHED      (1 << TIF_NEED_RESCHED)
-#define _TIF_IRET              (1 << TIF_IRET)
 #define _TIF_SYSCALL_EMU       (1 << TIF_SYSCALL_EMU)
 #define _TIF_SYSCALL_AUDIT     (1 << TIF_SYSCALL_AUDIT)
 #define _TIF_SECCOMP           (1 << TIF_SECCOMP)
index 0d9776e9e2dc3f2a539015a5f2930e00d2727a99..55d155560fdf80a0834e19fec15dd73306905aa0 100644 (file)
@@ -50,6 +50,8 @@
 # define __ARCH_WANT_SYS_TIME
 # define __ARCH_WANT_SYS_UTIME
 # define __ARCH_WANT_SYS_WAITPID
+# define __ARCH_WANT_SYS_EXECVE
+# define __ARCH_WANT_KERNEL_EXECVE
 
 /*
  * "Conditional" syscalls
index a48ea05157d3bbcb8cb56c4a2f92bb45cad446e8..91ce48f05f9f6d623beaa84029be5ff1cdf1cfc8 100644 (file)
@@ -23,7 +23,7 @@ obj-y                 += time.o ioport.o ldt.o dumpstack.o nmi.o
 obj-y                  += setup.o x86_init.o i8259.o irqinit.o jump_label.o
 obj-$(CONFIG_IRQ_WORK)  += irq_work.o
 obj-y                  += probe_roms.o
-obj-$(CONFIG_X86_32)   += sys_i386_32.o i386_ksyms_32.o
+obj-$(CONFIG_X86_32)   += i386_ksyms_32.o
 obj-$(CONFIG_X86_64)   += sys_x86_64.o x8664_ksyms_64.o
 obj-y                  += syscall_$(BITS).o
 obj-$(CONFIG_X86_64)   += vsyscall_64.o
index 68de2dc962ec0dc52a8721578aa0ca9aff40ba39..28610822fb3cc4be10a04c098ee91b6a8b8ab78f 100644 (file)
@@ -69,4 +69,7 @@ void common(void) {
        OFFSET(BP_kernel_alignment, boot_params, hdr.kernel_alignment);
        OFFSET(BP_pref_address, boot_params, hdr.pref_address);
        OFFSET(BP_code32_start, boot_params, hdr.code32_start);
+
+       BLANK();
+       DEFINE(PTREGS_SIZE, sizeof(struct pt_regs));
 }
index 0750e3ba87c09447c7443112b0a1e5678538de91..2c6340796fe99b7374b545649e89cbc96996bd44 100644 (file)
@@ -299,6 +299,13 @@ ENTRY(ret_from_fork)
        CFI_ENDPROC
 END(ret_from_fork)
 
+ENTRY(ret_from_kernel_execve)
+       movl %eax, %esp
+       movl $0,PT_EAX(%esp)
+       GET_THREAD_INFO(%ebp)
+       jmp syscall_exit
+END(ret_from_kernel_execve)
+
 /*
  * Interrupt exit functions should be protected against kprobes
  */
@@ -323,8 +330,7 @@ ret_from_intr:
        andl $(X86_EFLAGS_VM | SEGMENT_RPL_MASK), %eax
 #else
        /*
-        * We can be coming here from a syscall done in the kernel space,
-        * e.g. a failed kernel_execve().
+        * We can be coming here from child spawned by kernel_thread().
         */
        movl PT_CS(%esp), %eax
        andl $SEGMENT_RPL_MASK, %eax
@@ -616,6 +622,10 @@ work_notifysig:                            # deal with pending signals and
        movl %esp, %eax
        jne work_notifysig_v86          # returning to kernel-space or
                                        # vm86-space
+1:
+#else
+       movl %esp, %eax
+#endif
        TRACE_IRQS_ON
        ENABLE_INTERRUPTS(CLBR_NONE)
        movb PT_CS(%esp), %bl
@@ -626,24 +636,15 @@ work_notifysig:                           # deal with pending signals and
        call do_notify_resume
        jmp resume_userspace
 
+#ifdef CONFIG_VM86
        ALIGN
 work_notifysig_v86:
        pushl_cfi %ecx                  # save ti_flags for do_notify_resume
        call save_v86_state             # %eax contains pt_regs pointer
        popl_cfi %ecx
        movl %eax, %esp
-#else
-       movl %esp, %eax
+       jmp 1b
 #endif
-       TRACE_IRQS_ON
-       ENABLE_INTERRUPTS(CLBR_NONE)
-       movb PT_CS(%esp), %bl
-       andb $SEGMENT_RPL_MASK, %bl
-       cmpb $USER_RPL, %bl
-       jb resume_kernel
-       xorl %edx, %edx
-       call do_notify_resume
-       jmp resume_userspace
 END(work_pending)
 
        # perform syscall exit tracing
@@ -732,7 +733,6 @@ ENDPROC(ptregs_##name)
 PTREGSCALL1(iopl)
 PTREGSCALL0(fork)
 PTREGSCALL0(vfork)
-PTREGSCALL3(execve)
 PTREGSCALL2(sigaltstack)
 PTREGSCALL0(sigreturn)
 PTREGSCALL0(rt_sigreturn)
@@ -1015,15 +1015,20 @@ END(spurious_interrupt_bug)
  */
        .popsection
 
-ENTRY(kernel_thread_helper)
-       pushl $0                # fake return address for unwinder
+ENTRY(ret_from_kernel_thread)
        CFI_STARTPROC
-       movl %edi,%eax
-       call *%esi
+       pushl_cfi %eax
+       call schedule_tail
+       GET_THREAD_INFO(%ebp)
+       popl_cfi %eax
+       pushl_cfi $0x0202               # Reset kernel eflags
+       popfl_cfi
+       movl PT_EBP(%esp),%eax
+       call *PT_EBX(%esp)
        call do_exit
        ud2                     # padding for call trace
        CFI_ENDPROC
-ENDPROC(kernel_thread_helper)
+ENDPROC(ret_from_kernel_thread)
 
 #ifdef CONFIG_XEN
 /* Xen doesn't set %esp to be precisely what the normal sysenter
index 44531acd9a81e83f932a34a409c028b24cdb9bce..cdc790c78f328ed0d9525c270ed9e4013db28bdb 100644 (file)
@@ -554,7 +554,7 @@ ENTRY(ret_from_fork)
        RESTORE_REST
 
        testl $3, CS-ARGOFFSET(%rsp)            # from kernel_thread?
-       jz   retint_restore_args
+       jz   1f
 
        testl $_TIF_IA32, TI_flags(%rcx)        # 32-bit compat task needs IRET
        jnz  int_ret_from_sys_call
@@ -562,6 +562,16 @@ ENTRY(ret_from_fork)
        RESTORE_TOP_OF_STACK %rdi, -ARGOFFSET
        jmp ret_from_sys_call                   # go to the SYSRET fastpath
 
+1:
+       subq $REST_SKIP, %rsp   # move the stack pointer back
+       CFI_ADJUST_CFA_OFFSET   REST_SKIP
+       movq %rbp, %rdi
+       call *%rbx
+       # exit
+       mov %eax, %edi
+       call do_exit
+       ud2                     # padding for call trace
+
        CFI_ENDPROC
 END(ret_from_fork)
 
@@ -862,7 +872,6 @@ ENTRY(stub_execve)
        PARTIAL_FRAME 0
        SAVE_REST
        FIXUP_TOP_OF_STACK %r11
-       movq %rsp, %rcx
        call sys_execve
        RESTORE_TOP_OF_STACK %r11
        movq %rax,RAX(%rsp)
@@ -912,8 +921,7 @@ ENTRY(stub_x32_execve)
        PARTIAL_FRAME 0
        SAVE_REST
        FIXUP_TOP_OF_STACK %r11
-       movq %rsp, %rcx
-       call sys32_execve
+       call compat_sys_execve
        RESTORE_TOP_OF_STACK %r11
        movq %rax,RAX(%rsp)
        RESTORE_REST
@@ -1318,51 +1326,19 @@ bad_gs:
        jmp  2b
        .previous
 
-ENTRY(kernel_thread_helper)
-       pushq $0                # fake return address
-       CFI_STARTPROC
-       /*
-        * Here we are in the child and the registers are set as they were
-        * at kernel_thread() invocation in the parent.
-        */
-       call *%rsi
-       # exit
-       mov %eax, %edi
-       call do_exit
-       ud2                     # padding for call trace
-       CFI_ENDPROC
-END(kernel_thread_helper)
-
-/*
- * execve(). This function needs to use IRET, not SYSRET, to set up all state properly.
- *
- * C extern interface:
- *      extern long execve(const char *name, char **argv, char **envp)
- *
- * asm input arguments:
- *     rdi: name, rsi: argv, rdx: envp
- *
- * We want to fallback into:
- *     extern long sys_execve(const char *name, char **argv,char **envp, struct pt_regs *regs)
- *
- * do_sys_execve asm fallback arguments:
- *     rdi: name, rsi: argv, rdx: envp, rcx: fake frame on the stack
- */
-ENTRY(kernel_execve)
-       CFI_STARTPROC
-       FAKE_STACK_FRAME $0
-       SAVE_ALL
-       movq %rsp,%rcx
-       call sys_execve
-       movq %rax, RAX(%rsp)
-       RESTORE_REST
-       testq %rax,%rax
-       je int_ret_from_sys_call
-       RESTORE_ARGS
-       UNFAKE_STACK_FRAME
-       ret
-       CFI_ENDPROC
-END(kernel_execve)
+ENTRY(ret_from_kernel_execve)
+       movq %rdi, %rsp
+       movl $0, RAX(%rsp)
+       // RESTORE_REST
+       movq 0*8(%rsp), %r15
+       movq 1*8(%rsp), %r14
+       movq 2*8(%rsp), %r13
+       movq 3*8(%rsp), %r12
+       movq 4*8(%rsp), %rbp
+       movq 5*8(%rsp), %rbx
+       addq $(6*8), %rsp
+       jmp int_ret_from_sys_call
+END(ret_from_kernel_execve)
 
 /* Call softirq on interrupt stack. Interrupts are off. */
 ENTRY(call_softirq)
index dc3567e083f9f5ec3a9d524756d191b5125490cc..b644e1c765dc211dbb07b6ee7570081e5cd0e6c6 100644 (file)
@@ -292,71 +292,6 @@ sys_clone(unsigned long clone_flags, unsigned long newsp,
        return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid);
 }
 
-/*
- * This gets run with %si containing the
- * function to call, and %di containing
- * the "args".
- */
-extern void kernel_thread_helper(void);
-
-/*
- * Create a kernel thread
- */
-int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
-{
-       struct pt_regs regs;
-
-       memset(&regs, 0, sizeof(regs));
-
-       regs.si = (unsigned long) fn;
-       regs.di = (unsigned long) arg;
-
-#ifdef CONFIG_X86_32
-       regs.ds = __USER_DS;
-       regs.es = __USER_DS;
-       regs.fs = __KERNEL_PERCPU;
-       regs.gs = __KERNEL_STACK_CANARY;
-#else
-       regs.ss = __KERNEL_DS;
-#endif
-
-       regs.orig_ax = -1;
-       regs.ip = (unsigned long) kernel_thread_helper;
-       regs.cs = __KERNEL_CS | get_kernel_rpl();
-       regs.flags = X86_EFLAGS_IF | X86_EFLAGS_BIT1;
-
-       /* Ok, create the new process.. */
-       return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
-}
-EXPORT_SYMBOL(kernel_thread);
-
-/*
- * sys_execve() executes a new program.
- */
-long sys_execve(const char __user *name,
-               const char __user *const __user *argv,
-               const char __user *const __user *envp, struct pt_regs *regs)
-{
-       long error;
-       char *filename;
-
-       filename = getname(name);
-       error = PTR_ERR(filename);
-       if (IS_ERR(filename))
-               return error;
-       error = do_execve(filename, argv, envp, regs);
-
-#ifdef CONFIG_X86_32
-       if (error == 0) {
-               /* Make sure we don't return using sysenter.. */
-                set_thread_flag(TIF_IRET);
-        }
-#endif
-
-       putname(filename);
-       return error;
-}
-
 /*
  * Idle related variables and functions
  */
index b9ff83c7135bad337d4e5d7e7554be6e833204a0..44e0bff38e724de5b9e02e5bd9581133999ad40e 100644 (file)
@@ -57,6 +57,7 @@
 #include <asm/switch_to.h>
 
 asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
+asmlinkage void ret_from_kernel_thread(void) __asm__("ret_from_kernel_thread");
 
 /*
  * Return saved PC of a blocked thread.
@@ -127,23 +128,39 @@ void release_thread(struct task_struct *dead_task)
 }
 
 int copy_thread(unsigned long clone_flags, unsigned long sp,
-       unsigned long unused,
+       unsigned long arg,
        struct task_struct *p, struct pt_regs *regs)
 {
-       struct pt_regs *childregs;
+       struct pt_regs *childregs = task_pt_regs(p);
        struct task_struct *tsk;
        int err;
 
-       childregs = task_pt_regs(p);
+       p->thread.sp = (unsigned long) childregs;
+       p->thread.sp0 = (unsigned long) (childregs+1);
+
+       if (unlikely(!regs)) {
+               /* kernel thread */
+               memset(childregs, 0, sizeof(struct pt_regs));
+               p->thread.ip = (unsigned long) ret_from_kernel_thread;
+               task_user_gs(p) = __KERNEL_STACK_CANARY;
+               childregs->ds = __USER_DS;
+               childregs->es = __USER_DS;
+               childregs->fs = __KERNEL_PERCPU;
+               childregs->bx = sp;     /* function */
+               childregs->bp = arg;
+               childregs->orig_ax = -1;
+               childregs->cs = __KERNEL_CS | get_kernel_rpl();
+               childregs->flags = X86_EFLAGS_IF | X86_EFLAGS_BIT1;
+               p->fpu_counter = 0;
+               p->thread.io_bitmap_ptr = NULL;
+               memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps));
+               return 0;
+       }
        *childregs = *regs;
        childregs->ax = 0;
        childregs->sp = sp;
 
-       p->thread.sp = (unsigned long) childregs;
-       p->thread.sp0 = (unsigned long) (childregs+1);
-
        p->thread.ip = (unsigned long) ret_from_fork;
-
        task_user_gs(p) = get_user_gs(regs);
 
        p->fpu_counter = 0;
@@ -190,6 +207,12 @@ start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp)
        regs->cs                = __USER_CS;
        regs->ip                = new_ip;
        regs->sp                = new_sp;
+       regs->flags             = X86_EFLAGS_IF;
+       /*
+        * force it to the iret return path by making it look as if there was
+        * some work pending.
+        */
+       set_thread_flag(TIF_NOTIFY_RESUME);
 }
 EXPORT_SYMBOL_GPL(start_thread);
 
index 8a6d20ce19784ee96362cbaaa29c696497122a6a..16c6365e2b867c883805061f533349751f9bfbf0 100644 (file)
@@ -146,29 +146,18 @@ static inline u32 read_32bit_tls(struct task_struct *t, int tls)
 }
 
 int copy_thread(unsigned long clone_flags, unsigned long sp,
-               unsigned long unused,
+               unsigned long arg,
        struct task_struct *p, struct pt_regs *regs)
 {
        int err;
        struct pt_regs *childregs;
        struct task_struct *me = current;
 
-       childregs = ((struct pt_regs *)
-                       (THREAD_SIZE + task_stack_page(p))) - 1;
-       *childregs = *regs;
-
-       childregs->ax = 0;
-       if (user_mode(regs))
-               childregs->sp = sp;
-       else
-               childregs->sp = (unsigned long)childregs;
-
+       p->thread.sp0 = (unsigned long)task_stack_page(p) + THREAD_SIZE;
+       childregs = task_pt_regs(p);
        p->thread.sp = (unsigned long) childregs;
-       p->thread.sp0 = (unsigned long) (childregs+1);
        p->thread.usersp = me->thread.usersp;
-
        set_tsk_thread_flag(p, TIF_FORK);
-
        p->fpu_counter = 0;
        p->thread.io_bitmap_ptr = NULL;
 
@@ -178,6 +167,24 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
        p->thread.fs = p->thread.fsindex ? 0 : me->thread.fs;
        savesegment(es, p->thread.es);
        savesegment(ds, p->thread.ds);
+       memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps));
+
+       if (unlikely(!regs)) {
+               /* kernel thread */
+               memset(childregs, 0, sizeof(struct pt_regs));
+               childregs->sp = (unsigned long)childregs;
+               childregs->ss = __KERNEL_DS;
+               childregs->bx = sp; /* function */
+               childregs->bp = arg;
+               childregs->orig_ax = -1;
+               childregs->cs = __KERNEL_CS | get_kernel_rpl();
+               childregs->flags = X86_EFLAGS_IF | X86_EFLAGS_BIT1;
+               return 0;
+       }
+       *childregs = *regs;
+
+       childregs->ax = 0;
+       childregs->sp = sp;
 
        err = -ENOMEM;
        memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps));
index b33144c8b3098a10d956882f31e6ca1933770ce7..29ad351804e9324d3aaf59c07c86d274958516b3 100644 (file)
@@ -840,10 +840,6 @@ do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags)
        if (thread_info_flags & _TIF_USER_RETURN_NOTIFY)
                fire_user_return_notifiers();
 
-#ifdef CONFIG_X86_32
-       clear_thread_flag(TIF_IRET);
-#endif /* CONFIG_X86_32 */
-
        rcu_user_enter();
 }
 
diff --git a/arch/x86/kernel/sys_i386_32.c b/arch/x86/kernel/sys_i386_32.c
deleted file mode 100644 (file)
index 0b0cb5f..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * This file contains various random system calls that
- * have a non-standard calling sequence on the Linux/i386
- * platform.
- */
-
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/fs.h>
-#include <linux/smp.h>
-#include <linux/sem.h>
-#include <linux/msg.h>
-#include <linux/shm.h>
-#include <linux/stat.h>
-#include <linux/syscalls.h>
-#include <linux/mman.h>
-#include <linux/file.h>
-#include <linux/utsname.h>
-#include <linux/ipc.h>
-
-#include <linux/uaccess.h>
-#include <linux/unistd.h>
-
-#include <asm/syscalls.h>
-
-/*
- * Do a system call from kernel instead of calling sys_execve so we
- * end up with proper pt_regs.
- */
-int kernel_execve(const char *filename,
-                 const char *const argv[],
-                 const char *const envp[])
-{
-       long __res;
-       asm volatile ("int $0x80"
-       : "=a" (__res)
-       : "0" (__NR_execve), "b" (filename), "c" (argv), "d" (envp) : "memory");
-       return __res;
-}
index 54abcc0baf23f0f4181106a7b2a83312c01ed03f..5c9687b1bde6706293e199331e7c866f1b752095 100644 (file)
@@ -561,9 +561,9 @@ int handle_vm86_trap(struct kernel_vm86_regs *regs, long error_code, int trapno)
                if ((trapno == 3) || (trapno == 1)) {
                        KVM86->regs32->ax = VM86_TRAP + (trapno << 8);
                        /* setting this flag forces the code in entry_32.S to
-                          call save_v86_state() and change the stack pointer
-                          to KVM86->regs32 */
-                       set_thread_flag(TIF_IRET);
+                          the path where we call save_v86_state() and change
+                          the stack pointer to KVM86->regs32 */
+                       set_thread_flag(TIF_NOTIFY_RESUME);
                        return 0;
                }
                do_int(regs, trapno, (unsigned char __user *) (regs->pt.ss << 4), SP(regs));
index 7a35a6e71d44332d351cdeb9ec28e96c6467c7b6..a47103fbc6925ac7c717ef1ed2d1f9eccaa35fa4 100644 (file)
@@ -17,7 +17,7 @@
 8      i386    creat                   sys_creat
 9      i386    link                    sys_link
 10     i386    unlink                  sys_unlink
-11     i386    execve                  ptregs_execve                   stub32_execve
+11     i386    execve                  sys_execve                      stub32_execve
 12     i386    chdir                   sys_chdir
 13     i386    time                    sys_time                        compat_sys_time
 14     i386    mknod                   sys_mknod
index 35f462a6512b2977717a210211f02e09aa0baa4b..dfe41302079607a3b4215f9f9528cd53a68cda5e 100644 (file)
@@ -13,6 +13,7 @@ endmenu
 config UML_X86
        def_bool y
        select GENERIC_FIND_FIRST_BIT
+       select GENERIC_KERNEL_THREAD
 
 config 64BIT
        bool "64-bit kernel" if SUBARCH = "x86"
index b5408cecac6cd68f5f649b0a45749c1fdab40d77..232e60504b3a8c6c62db26a29b35b07c295d6ac9 100644 (file)
@@ -25,7 +25,6 @@
 #define old_mmap sys_old_mmap
 
 #define ptregs_fork sys_fork
-#define ptregs_execve sys_execve
 #define ptregs_iopl sys_iopl
 #define ptregs_vm86old sys_vm86old
 #define ptregs_clone i386_clone
index c68e1680da0173d5754d1a1df4944120a5239e58..708340339b057e16c4accba616fd5d37ffa53838 100644 (file)
@@ -1 +1,3 @@
 include include/asm-generic/Kbuild.asm
+
+generic-y += exec.h
diff --git a/arch/xtensa/include/asm/exec.h b/arch/xtensa/include/asm/exec.h
deleted file mode 100644 (file)
index af949e2..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2001 - 2005 Tensilica Inc.
- */
-
-#ifndef _XTENSA_EXEC_H
-#define _XTENSA_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* _XTENSA_EXEC_H */
index 81abfd5d01acfdb7c01f4c5e6c1ba4bc3f731e06..9481004ac119e04ef8f6a80921561de071b445a1 100644 (file)
@@ -128,19 +128,14 @@ static inline struct thread_info *current_thread_info(void)
 #define TIF_SIGPENDING         1       /* signal pending */
 #define TIF_NEED_RESCHED       2       /* rescheduling necessary */
 #define TIF_SINGLESTEP         3       /* restore singlestep on return to user mode */
-#define TIF_IRET               4       /* return with iret */
 #define TIF_MEMDIE             5       /* is terminating due to OOM killer */
 #define TIF_RESTORE_SIGMASK    6       /* restore signal mask in do_signal() */
 #define TIF_NOTIFY_RESUME      7       /* callback before returning to user */
-#define TIF_POLLING_NRFLAG     16      /* true if poll_idle() is polling TIF_NEED_RESCHED */
 
 #define _TIF_SYSCALL_TRACE     (1<<TIF_SYSCALL_TRACE)
 #define _TIF_SIGPENDING                (1<<TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED      (1<<TIF_NEED_RESCHED)
 #define _TIF_SINGLESTEP                (1<<TIF_SINGLESTEP)
-#define _TIF_IRET              (1<<TIF_IRET)
-#define _TIF_POLLING_NRFLAG    (1<<TIF_POLLING_NRFLAG)
-#define _TIF_RESTORE_SIGMASK   (1<<TIF_RESTORE_SIGMASK)
 
 #define _TIF_WORK_MASK         0x0000FFFE      /* work to do on interrupt/exception return */
 #define _TIF_ALLWORK_MASK      0x0000FFFF      /* work to do on any return to u-space */
index efe4e854b3cdd06808eec1bcd3fe8fa70b07ed96..63c566f627bc9ca13ac0df36a9752698ca9a62c0 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/errno.h>
 #include <linux/ptrace.h>
 #include <linux/personality.h>
-#include <linux/freezer.h>
 #include <linux/tracehook.h>
 
 #include <asm/ucontext.h>
@@ -527,9 +526,6 @@ static void do_signal(struct pt_regs *regs)
 
 void do_notify_resume(struct pt_regs *regs)
 {
-       if (!user_mode(regs))
-               return;
-
        if (test_thread_flag(TIF_SIGPENDING))
                do_signal(regs);
 
index 0225fddf49b7d9e25ae2a8361b631ba30c34a496..1229fe94992f9496fb5bffacfe157e0b290e0454 100644 (file)
@@ -35,7 +35,6 @@
 #include <asm/uaccess.h>
 #include <asm/param.h>
 #include <asm/page.h>
-#include <asm/exec.h>
 
 static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs);
 static int load_elf_library(struct file *);
index 3d77cf81ba3c82c8dbe7d80531e34bea4355250c..c298f2efc1bfcad428fbc0cd39b55831215276c6 100644 (file)
@@ -39,7 +39,6 @@
 #include <asm/uaccess.h>
 #include <asm/param.h>
 #include <asm/pgalloc.h>
-#include <asm/exec.h>
 
 typedef char *elf_caddr_t;
 
index 48fb26ef8a1b3daebb49a74c9ae09ba83c7f7a14..605706b2630dc2af56aa13c429b77d5b09b9e565 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -59,7 +59,6 @@
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
 #include <asm/tlb.h>
-#include <asm/exec.h>
 
 #include <trace/events/task.h>
 #include "internal.h"
@@ -391,7 +390,7 @@ struct user_arg_ptr {
        union {
                const char __user *const __user *native;
 #ifdef CONFIG_COMPAT
-               compat_uptr_t __user *compat;
+               const compat_uptr_t __user *compat;
 #endif
        } ptr;
 };
@@ -1561,9 +1560,9 @@ int do_execve(const char *filename,
 }
 
 #ifdef CONFIG_COMPAT
-int compat_do_execve(char *filename,
-       compat_uptr_t __user *__argv,
-       compat_uptr_t __user *__envp,
+int compat_do_execve(const char *filename,
+       const compat_uptr_t __user *__argv,
+       const compat_uptr_t __user *__envp,
        struct pt_regs *regs)
 {
        struct user_arg_ptr argv = {
@@ -1645,3 +1644,55 @@ int get_dumpable(struct mm_struct *mm)
 {
        return __get_dumpable(mm->flags);
 }
+
+#ifdef __ARCH_WANT_SYS_EXECVE
+SYSCALL_DEFINE3(execve,
+               const char __user *, filename,
+               const char __user *const __user *, argv,
+               const char __user *const __user *, envp)
+{
+       const char *path = getname(filename);
+       int error = PTR_ERR(path);
+       if (!IS_ERR(path)) {
+               error = do_execve(path, argv, envp, current_pt_regs());
+               putname(path);
+       }
+       return error;
+}
+#ifdef CONFIG_COMPAT
+asmlinkage long compat_sys_execve(const char __user * filename,
+       const compat_uptr_t __user * argv,
+       const compat_uptr_t __user * envp)
+{
+       const char *path = getname(filename);
+       int error = PTR_ERR(path);
+       if (!IS_ERR(path)) {
+               error = compat_do_execve(path, argv, envp, current_pt_regs());
+               putname(path);
+       }
+       return error;
+}
+#endif
+#endif
+
+#ifdef __ARCH_WANT_KERNEL_EXECVE
+int kernel_execve(const char *filename,
+                 const char *const argv[],
+                 const char *const envp[])
+{
+       struct pt_regs *p = current_pt_regs();
+       int ret;
+
+       ret = do_execve(filename,
+                       (const char __user *const __user *)argv,
+                       (const char __user *const __user *)envp, p);
+       if (ret < 0)
+               return ret;
+
+       /*
+        * We were successful.  We won't be returning to our caller, but
+        * instead to user space by manipulating the kernel stack.
+        */
+       ret_from_kernel_execve(p);
+}
+#endif
index 366422bc1633cecda39235276569f283faf0bf46..f9c9d08f4f7c7bfe1712b8f04f993eb776244dc8 100644 (file)
@@ -19,6 +19,8 @@ struct pt_regs;
 
 #ifdef __KERNEL__
 #include <linux/sched.h>
+#include <linux/unistd.h>
+#include <asm/exec.h>
 
 #define CORENAME_MAX_SIZE 128
 
@@ -136,5 +138,9 @@ extern void do_coredump(long signr, int exit_code, struct pt_regs *regs);
 extern void set_binfmt(struct linux_binfmt *new);
 extern void free_bprm(struct linux_binprm *);
 
+#ifdef __ARCH_WANT_KERNEL_EXECVE
+extern void ret_from_kernel_execve(struct pt_regs *normal) __noreturn;
+#endif
+
 #endif /* __KERNEL__ */
 #endif /* _LINUX_BINFMTS_H */
index fd4e29956d1c1d8069a085553bf1474e7b99ff7f..b0d180554fa2ff56f2ffadee708fdff3abf6cc77 100644 (file)
@@ -289,8 +289,12 @@ asmlinkage ssize_t compat_sys_pwritev(unsigned long fd,
                const struct compat_iovec __user *vec,
                unsigned long vlen, u32 pos_low, u32 pos_high);
 
-int compat_do_execve(char *filename, compat_uptr_t __user *argv,
-                    compat_uptr_t __user *envp, struct pt_regs *regs);
+int compat_do_execve(const char *filename, const compat_uptr_t __user *argv,
+                    const compat_uptr_t __user *envp, struct pt_regs *regs);
+#ifdef __ARCH_WANT_SYS_EXECVE
+asmlinkage long compat_sys_execve(const char __user *filename, const compat_uptr_t __user *argv,
+                    const compat_uptr_t __user *envp);
+#endif
 
 asmlinkage long compat_sys_select(int n, compat_ulong_t __user *inp,
                compat_ulong_t __user *outp, compat_ulong_t __user *exp,
index 3db698aee34cd9437f8f42823f17825796597f09..1d24ffad59c53c27a66bf7b4cced639f0a5f000a 100644 (file)
@@ -401,6 +401,10 @@ static inline void user_single_step_siginfo(struct task_struct *tsk,
 #define arch_ptrace_stop(code, info)           do { } while (0)
 #endif
 
+#ifndef current_pt_regs
+#define current_pt_regs() task_pt_regs(current)
+#endif
+
 extern int task_current_syscall(struct task_struct *target, long *callno,
                                unsigned long args[6], unsigned int maxargs,
                                unsigned long *sp, unsigned long *pc);
index b2be93bd65f6863ba128cbe8db57b5357babd28f..ea695ade763a1f30e8ef80aaf9d59661d86ccf4d 100644 (file)
@@ -2353,6 +2353,9 @@ extern int do_execve(const char *,
                     const char __user * const __user *, struct pt_regs *);
 extern long do_fork(unsigned long, unsigned long, struct pt_regs *, unsigned long, int __user *, int __user *);
 struct task_struct *fork_idle(int);
+#ifdef CONFIG_GENERIC_KERNEL_THREAD
+extern pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
+#endif
 
 extern void set_task_comm(struct task_struct *tsk, char *from);
 extern char *get_task_comm(char *to, struct task_struct *tsk);
index a2b1efc2092809904024e33e8bf0405d0d73de12..79d27b0ef4281ccf43432f20ecdad77423c3853b 100644 (file)
@@ -1602,7 +1602,7 @@ long do_fork(unsigned long clone_flags,
         * requested, no event is reported; otherwise, report if the event
         * for the type of forking is enabled.
         */
-       if (likely(user_mode(regs)) && !(clone_flags & CLONE_UNTRACED)) {
+       if (!(clone_flags & CLONE_UNTRACED) && likely(user_mode(regs))) {
                if (clone_flags & CLONE_VFORK)
                        trace = PTRACE_EVENT_VFORK;
                else if ((clone_flags & CSIGNAL) != SIGCHLD)
@@ -1652,6 +1652,17 @@ long do_fork(unsigned long clone_flags,
        return nr;
 }
 
+#ifdef CONFIG_GENERIC_KERNEL_THREAD
+/*
+ * Create a kernel thread.
+ */
+pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
+{
+       return do_fork(flags|CLONE_VM|CLONE_UNTRACED, (unsigned long)fn, NULL,
+               (unsigned long)arg, NULL, NULL);
+}
+#endif
+
 #ifndef ARCH_MIN_MMSTRUCT_ALIGN
 #define ARCH_MIN_MMSTRUCT_ALIGN 0
 #endif
index 878e33f47a0634a1feedd96985fa5d4928deb351..b43635d54d030b6b7f79469491bd706ed71423f4 100644 (file)
@@ -505,7 +505,7 @@ static inline void init_hrtick(void)
 #ifdef CONFIG_SMP
 
 #ifndef tsk_is_polling
-#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
+#define tsk_is_polling(t) 0
 #endif
 
 void resched_task(struct task_struct *p)