m68k: switch to generic sys_execve()/kernel_execve()
Al Viro [Sun, 16 Sep 2012 16:06:34 +0000 (12:06 -0400)]
The tricky part here is that task_pt_regs() on m68k works *only* for
process inside do_signal().  However, we need something much simpler -
pt_regs of a process inside do_signal() may be at different offsets
from the stack bottom, depending on the way we'd entered the kernel,
but for a task inside sys_execve() it *is* at constant offset.
Moreover, for a kernel thread about to become a userland process the
same location is also fine - setting sp to that will leave the kernel
stack pointer at the very bottom of the kernel stack when we finally
switch to userland.

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

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

index 65322b1..5e08b59 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 045cfd6..c702ad7 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 8a01f58..946cb01 100644 (file)
@@ -122,6 +122,11 @@ ENTRY(ret_from_kernel_thread)
        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 b3d4760..4e54b4c 100644 (file)
@@ -298,26 +298,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 9a5932e..3a480b3 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;