Browse Source

powerpc: switch to generic sys_execve()/kernel_execve()

the only non-obvious part is that current_pt_regs() is really needed
here - task_pt_regs() is NULL for kernel threads; it's OK for ptrace
uses (the thing task_pt_regs() is intended for), but not for us.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Al Viro 13 years ago
parent
commit
be6abfa769

+ 2 - 0
arch/powerpc/include/asm/ptrace.h

@@ -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

+ 0 - 3
arch/powerpc/include/asm/syscalls.h

@@ -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);

+ 2 - 0
arch/powerpc/include/asm/unistd.h

@@ -420,6 +420,8 @@
 #define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
 #define __ARCH_WANT_SYS_NEWFSTATAT
 #endif
+#define __ARCH_WANT_SYS_EXECVE
+#define __ARCH_WANT_KERNEL_EXECVE
 
 /*
  * "Conditional" syscalls

+ 5 - 0
arch/powerpc/kernel/entry_32.S

@@ -446,6 +446,11 @@ ret_from_kernel_thread:
 	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)

+ 6 - 0
arch/powerpc/kernel/entry_64.S

@@ -380,6 +380,12 @@ _GLOBAL(ret_from_kernel_thread)
 	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

+ 0 - 7
arch/powerpc/kernel/misc.S

@@ -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)

+ 6 - 19
arch/powerpc/kernel/process.c

@@ -1064,26 +1064,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,

+ 0 - 22
arch/powerpc/kernel/sys_ppc32.c

@@ -187,28 +187,6 @@ asmlinkage int compat_sys_sendfile64(int out_fd, int in_fd, compat_loff_t __user
 	return ret;
 }
 
-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)