Merge commit '6ba1bc826d160fe4f32bcb188687dcca4bdfaf3d' into arch-arm64
Al Viro [Sat, 17 Nov 2012 01:53:36 +0000 (20:53 -0500)]
Backmerge from mainline commit that introduced a trivial conflict in
arch/arm64/kernel/process.c - a bunch of functions removed next to the
place where kernel_thread() used to be.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

arch/arm64/Kconfig
arch/arm64/include/asm/processor.h
arch/arm64/include/asm/syscalls.h
arch/arm64/include/asm/unistd.h
arch/arm64/include/asm/unistd32.h
arch/arm64/kernel/entry.S
arch/arm64/kernel/process.c
arch/arm64/kernel/sys.c
arch/arm64/kernel/sys32.S
arch/arm64/kernel/sys_compat.c

index ef54a59..138fc9c 100644 (file)
@@ -6,6 +6,8 @@ config ARM64
        select GENERIC_IOMAP
        select GENERIC_IRQ_PROBE
        select GENERIC_IRQ_SHOW
+       select GENERIC_KERNEL_EXECVE
+       select GENERIC_KERNEL_THREAD
        select GENERIC_SMP_IDLE_THREAD
        select GENERIC_TIME_VSYSCALL
        select HARDIRQS_SW_RESEND
index 5d81004..42471d0 100644 (file)
@@ -126,11 +126,6 @@ unsigned long get_wchan(struct task_struct *p);
 extern struct task_struct *cpu_switch_to(struct task_struct *prev,
                                         struct task_struct *next);
 
-/*
- * 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 09ff335..a1b00cd 100644 (file)
 /*
  * System call wrappers implemented in kernel/entry.S.
  */
-asmlinkage long sys_execve_wrapper(const char __user *filename,
-                                  const char __user *const __user *argv,
-                                  const char __user *const __user *envp);
-asmlinkage long sys_clone_wrapper(unsigned long clone_flags,
-                                 unsigned long newsp,
-                                 void __user *parent_tid,
-                                 unsigned long tls_val,
-                                 void __user *child_tid);
 asmlinkage long sys_rt_sigreturn_wrapper(void);
 asmlinkage long sys_sigaltstack_wrapper(const stack_t __user *uss,
                                        stack_t __user *uoss);
 
+/*
+ * AArch64 sys_clone implementation has a different prototype than the generic
+ * one (additional TLS value argument).
+ */
+#define sys_clone      sys_clone
+
 #include <asm-generic/syscalls.h>
 
 #endif /* __ASM_SYSCALLS_H */
index 63f853f..b40dc6b 100644 (file)
@@ -26,4 +26,5 @@
 #define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
 #define __ARCH_WANT_COMPAT_SYS_SENDFILE
 #endif
+#define __ARCH_WANT_SYS_EXECVE
 #include <uapi/asm/unistd.h>
index 6d909fa..d9850cf 100644 (file)
@@ -23,7 +23,7 @@
 
 __SYSCALL(0,   sys_restart_syscall)
 __SYSCALL(1,   sys_exit)
-__SYSCALL(2,   compat_sys_fork_wrapper)
+__SYSCALL(2,   compat_sys_fork)
 __SYSCALL(3,   sys_read)
 __SYSCALL(4,   sys_write)
 __SYSCALL(5,   compat_sys_open)
@@ -32,7 +32,7 @@ __SYSCALL(7,   sys_ni_syscall)                        /* 7 was sys_waitpid */
 __SYSCALL(8,   sys_creat)
 __SYSCALL(9,   sys_link)
 __SYSCALL(10,  sys_unlink)
-__SYSCALL(11,  compat_sys_execve_wrapper)
+__SYSCALL(11,  compat_sys_execve)
 __SYSCALL(12,  sys_chdir)
 __SYSCALL(13,  sys_ni_syscall)                 /* 13 was sys_time */
 __SYSCALL(14,  sys_mknod)
@@ -141,7 +141,7 @@ __SYSCALL(116, compat_sys_sysinfo)
 __SYSCALL(117, sys_ni_syscall)                 /* 117 was sys_ipc */
 __SYSCALL(118, sys_fsync)
 __SYSCALL(119, compat_sys_sigreturn_wrapper)
-__SYSCALL(120, compat_sys_clone_wrapper)
+__SYSCALL(120, sys_clone)
 __SYSCALL(121, sys_setdomainname)
 __SYSCALL(122, sys_newuname)
 __SYSCALL(123, sys_ni_syscall)                 /* 123 was sys_modify_ldt */
@@ -211,7 +211,7 @@ __SYSCALL(186, compat_sys_sigaltstack_wrapper)
 __SYSCALL(187, compat_sys_sendfile)
 __SYSCALL(188, sys_ni_syscall)                 /* 188 reserved */
 __SYSCALL(189, sys_ni_syscall)                 /* 189 reserved */
-__SYSCALL(190, compat_sys_vfork_wrapper)
+__SYSCALL(190, compat_sys_vfork)
 __SYSCALL(191, compat_sys_getrlimit)           /* SuS compliant getrlimit */
 __SYSCALL(192, sys_mmap_pgoff)
 __SYSCALL(193, compat_sys_truncate64_wrapper)
index a6f3f7d..cbfa4d2 100644 (file)
@@ -594,7 +594,7 @@ work_resched:
 /*
  * "slow" syscall return path.
  */
-ENTRY(ret_to_user)
+ret_to_user:
        disable_irq                             // disable interrupts
        ldr     x1, [tsk, #TI_FLAGS]
        and     x2, x1, #_TIF_WORK_MASK
@@ -611,7 +611,10 @@ ENDPROC(ret_to_user)
  */
 ENTRY(ret_from_fork)
        bl      schedule_tail
-       get_thread_info tsk
+       cbz     x19, 1f                         // not a kernel thread
+       mov     x0, x20
+       blr     x19
+1:     get_thread_info tsk
        b       ret_to_user
 ENDPROC(ret_from_fork)
 
@@ -673,16 +676,6 @@ __sys_trace_return:
 /*
  * Special system call wrappers.
  */
-ENTRY(sys_execve_wrapper)
-       mov     x3, sp
-       b       sys_execve
-ENDPROC(sys_execve_wrapper)
-
-ENTRY(sys_clone_wrapper)
-       mov     x5, sp
-       b       sys_clone
-ENDPROC(sys_clone_wrapper)
-
 ENTRY(sys_rt_sigreturn_wrapper)
        mov     x0, sp
        b       sys_rt_sigreturn
index e04cebd..8a5f334 100644 (file)
@@ -240,27 +240,41 @@ int copy_thread(unsigned long clone_flags, unsigned long stack_start,
        struct pt_regs *childregs = task_pt_regs(p);
        unsigned long tls = p->thread.tp_value;
 
-       *childregs = *regs;
-       childregs->regs[0] = 0;
+       memset(&p->thread.cpu_context, 0, sizeof(struct cpu_context));
 
-       if (is_compat_thread(task_thread_info(p)))
-               childregs->compat_sp = stack_start;
-       else {
+       if (likely(regs)) {
+               *childregs = *regs;
+               childregs->regs[0] = 0;
+               if (is_compat_thread(task_thread_info(p))) {
+                       if (stack_start)
+                               childregs->compat_sp = stack_start;
+               } else {
+                       /*
+                        * Read the current TLS pointer from tpidr_el0 as it may be
+                        * out-of-sync with the saved value.
+                        */
+                       asm("mrs %0, tpidr_el0" : "=r" (tls));
+                       if (stack_start) {
+                               /* 16-byte aligned stack mandatory on AArch64 */
+                               if (stack_start & 15)
+                                       return -EINVAL;
+                               childregs->sp = stack_start;
+                       }
+               }
                /*
-                * Read the current TLS pointer from tpidr_el0 as it may be
-                * out-of-sync with the saved value.
+                * If a TLS pointer was passed to clone (4th argument), use it
+                * for the new thread.
                 */
-               asm("mrs %0, tpidr_el0" : "=r" (tls));
-               childregs->sp = stack_start;
+               if (clone_flags & CLONE_SETTLS)
+                       tls = regs->regs[3];
+       } else {
+               memset(childregs, 0, sizeof(struct pt_regs));
+               childregs->pstate = PSR_MODE_EL1h;
+               p->thread.cpu_context.x19 = stack_start;
+               p->thread.cpu_context.x20 = stk_sz;
        }
-
-       memset(&p->thread.cpu_context, 0, sizeof(struct cpu_context));
-       p->thread.cpu_context.sp = (unsigned long)childregs;
        p->thread.cpu_context.pc = (unsigned long)ret_from_fork;
-
-       /* If a TLS pointer was passed to clone, use that for the new thread. */
-       if (clone_flags & CLONE_SETTLS)
-               tls = regs->regs[3];
+       p->thread.cpu_context.sp = (unsigned long)childregs;
        p->thread.tp_value = tls;
 
        ptrace_hw_copy_thread(p);
@@ -309,43 +323,6 @@ struct task_struct *__switch_to(struct task_struct *prev,
        return last;
 }
 
-/*
- * Shuffle the argument into the correct register before calling the
- * thread function.  x1 is the thread argument, x2 is the pointer to
- * the thread function, and x3 points to the exit function.
- */
-extern void kernel_thread_helper(void);
-asm(   ".section .text\n"
-"      .align\n"
-"      .type   kernel_thread_helper, #function\n"
-"kernel_thread_helper:\n"
-"      mov     x0, x1\n"
-"      mov     x30, x3\n"
-"      br      x2\n"
-"      .size   kernel_thread_helper, . - kernel_thread_helper\n"
-"      .previous");
-
-#define kernel_thread_exit     do_exit
-
-/*
- * 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.regs[1] = (unsigned long)arg;
-       regs.regs[2] = (unsigned long)fn;
-       regs.regs[3] = (unsigned long)kernel_thread_exit;
-       regs.pc = (unsigned long)kernel_thread_helper;
-       regs.pstate = PSR_MODE_EL1h;
-
-       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 b120df3..4364df8 100644 (file)
  */
 asmlinkage long sys_clone(unsigned long clone_flags, unsigned long newsp,
                          int __user *parent_tidptr, unsigned long tls_val,
-                         int __user *child_tidptr, struct pt_regs *regs)
+                         int __user *child_tidptr)
 {
-       if (!newsp)
-               newsp = regs->sp;
-       /* 16-byte aligned stack mandatory on AArch64 */
-       if (newsp & 15)
-               return -EINVAL;
-       return do_fork(clone_flags, newsp, regs, 0, parent_tidptr, child_tidptr);
-}
-
-/*
- * sys_execve() executes a new program.
- */
-asmlinkage long sys_execve(const char __user *filenamei,
-                          const char __user *const __user *argv,
-                          const char __user *const __user *envp,
-                          struct pt_regs *regs)
-{
-       long error;
-       struct filename *filename;
-
-       filename = getname(filenamei);
-       error = PTR_ERR(filename);
-       if (IS_ERR(filename))
-               goto out;
-       error = do_execve(filename->name, 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.regs[0] = ret;
-
-       /*
-        * We were successful.  We won't be returning to our caller, but
-        * instead to user space by manipulating the kernel stack.
-        */
-       asm(    "add    x0, %0, %1\n\t"
-               "mov    x1, %2\n\t"
-               "mov    x2, %3\n\t"
-               "bl     memmove\n\t"    /* copy regs to top of stack */
-               "mov    x27, #0\n\t"    /* not a syscall */
-               "mov    x28, %0\n\t"    /* thread structure */
-               "mov    sp, x0\n\t"     /* reposition stack pointer */
-               "b      ret_to_user"
-               :
-               : "r" (current_thread_info()),
-                 "Ir" (THREAD_START_SP - sizeof(regs)),
-                 "r" (&regs),
-                 "Ir" (sizeof(regs))
-               : "x0", "x1", "x2", "x27", "x28", "x30", "memory");
-
- out:
-       return ret;
+       return do_fork(clone_flags, newsp, current_pt_regs(), 0,
+                       parent_tidptr, child_tidptr);
 }
-EXPORT_SYMBOL(kernel_execve);
 
 asmlinkage long sys_mmap(unsigned long addr, unsigned long len,
                         unsigned long prot, unsigned long flags,
@@ -118,8 +50,6 @@ asmlinkage long sys_mmap(unsigned long addr, unsigned long len,
 /*
  * Wrappers to pass the pt_regs argument.
  */
-#define sys_execve             sys_execve_wrapper
-#define sys_clone              sys_clone_wrapper
 #define sys_rt_sigreturn       sys_rt_sigreturn_wrapper
 #define sys_sigaltstack                sys_sigaltstack_wrapper
 
index 54c4aec..7ef59e9 100644 (file)
 /*
  * System call wrappers for the AArch32 compatibility layer.
  */
-compat_sys_fork_wrapper:
-       mov     x0, sp
-       b       compat_sys_fork
-ENDPROC(compat_sys_fork_wrapper)
-
-compat_sys_vfork_wrapper:
-       mov     x0, sp
-       b       compat_sys_vfork
-ENDPROC(compat_sys_vfork_wrapper)
-
-compat_sys_execve_wrapper:
-       mov     x3, sp
-       b       compat_sys_execve
-ENDPROC(compat_sys_execve_wrapper)
-
-compat_sys_clone_wrapper:
-       mov     x5, sp
-       b       compat_sys_clone
-ENDPROC(compat_sys_clone_wrapper)
 
 compat_sys_sigreturn_wrapper:
        mov     x0, sp
index 906e3bd..6fabc19 100644 (file)
 #include <asm/cacheflush.h>
 #include <asm/unistd32.h>
 
-asmlinkage int compat_sys_fork(struct pt_regs *regs)
+asmlinkage int compat_sys_fork(void)
 {
-       return do_fork(SIGCHLD, regs->compat_sp, regs, 0, NULL, NULL);
+       return do_fork(SIGCHLD, 0, current_pt_regs(), 0, NULL, NULL);
 }
 
-asmlinkage int compat_sys_clone(unsigned long clone_flags, unsigned long newsp,
-                         int __user *parent_tidptr, int tls_val,
-                         int __user *child_tidptr, struct pt_regs *regs)
+asmlinkage int compat_sys_vfork(void)
 {
-       if (!newsp)
-               newsp = regs->compat_sp;
-
-       return do_fork(clone_flags, newsp, regs, 0, parent_tidptr, child_tidptr);
-}
-
-asmlinkage int compat_sys_vfork(struct pt_regs *regs)
-{
-       return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->compat_sp,
-                      regs, 0, NULL, NULL);
-}
-
-asmlinkage int compat_sys_execve(const char __user *filenamei,
-                                compat_uptr_t argv, compat_uptr_t envp,
-                                struct pt_regs *regs)
-{
-       int error;
-       struct filename *filename;
-
-       filename = getname(filenamei);
-       error = PTR_ERR(filename);
-       if (IS_ERR(filename))
-               goto out;
-       error = compat_do_execve(filename->name, compat_ptr(argv),
-                                       compat_ptr(envp), regs);
-       putname(filename);
-out:
-       return error;
+       return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0,
+                      current_pt_regs(), 0, NULL, NULL);
 }
 
 asmlinkage int compat_sys_sched_rr_get_interval(compat_pid_t pid,