aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2012-08-31 15:48:05 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2012-09-30 23:35:51 -0400
commitbe6abfa769fa07ce89ac73273360b335ae978805 (patch)
treee6b9ba23767a93839c5e4e14f197d4781bf95cf4
parent58254e1002a82eb383c5977ad9fd5a451b91fe29 (diff)
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>
-rw-r--r--arch/powerpc/include/asm/ptrace.h2
-rw-r--r--arch/powerpc/include/asm/syscalls.h3
-rw-r--r--arch/powerpc/include/asm/unistd.h2
-rw-r--r--arch/powerpc/kernel/entry_32.S5
-rw-r--r--arch/powerpc/kernel/entry_64.S6
-rw-r--r--arch/powerpc/kernel/misc.S7
-rw-r--r--arch/powerpc/kernel/process.c25
-rw-r--r--arch/powerpc/kernel/sys_ppc32.c22
8 files changed, 21 insertions, 51 deletions
diff --git a/arch/powerpc/include/asm/ptrace.h b/arch/powerpc/include/asm/ptrace.h
index 9c21ed42aba..f76b88c367d 100644
--- a/arch/powerpc/include/asm/ptrace.h
+++ b/arch/powerpc/include/asm/ptrace.h
@@ -125,6 +125,8 @@ extern unsigned long ptrace_get_reg(struct task_struct *task, int regno);
125extern int ptrace_put_reg(struct task_struct *task, int regno, 125extern int ptrace_put_reg(struct task_struct *task, int regno,
126 unsigned long data); 126 unsigned long data);
127 127
128#define current_pt_regs() \
129 ((struct pt_regs *)((unsigned long)current_thread_info() + THREAD_SIZE) - 1)
128/* 130/*
129 * We use the least-significant bit of the trap field to indicate 131 * We use the least-significant bit of the trap field to indicate
130 * whether we have saved the full set of registers, or only a 132 * whether we have saved the full set of registers, or only a
diff --git a/arch/powerpc/include/asm/syscalls.h b/arch/powerpc/include/asm/syscalls.h
index 4084e567d28..329db4ec12c 100644
--- a/arch/powerpc/include/asm/syscalls.h
+++ b/arch/powerpc/include/asm/syscalls.h
@@ -17,9 +17,6 @@ asmlinkage unsigned long sys_mmap(unsigned long addr, size_t len,
17asmlinkage unsigned long sys_mmap2(unsigned long addr, size_t len, 17asmlinkage unsigned long sys_mmap2(unsigned long addr, size_t len,
18 unsigned long prot, unsigned long flags, 18 unsigned long prot, unsigned long flags,
19 unsigned long fd, unsigned long pgoff); 19 unsigned long fd, unsigned long pgoff);
20asmlinkage int sys_execve(unsigned long a0, unsigned long a1,
21 unsigned long a2, unsigned long a3, unsigned long a4,
22 unsigned long a5, struct pt_regs *regs);
23asmlinkage int sys_clone(unsigned long clone_flags, unsigned long usp, 20asmlinkage int sys_clone(unsigned long clone_flags, unsigned long usp,
24 int __user *parent_tidp, void __user *child_threadptr, 21 int __user *parent_tidp, void __user *child_threadptr,
25 int __user *child_tidp, int p6, struct pt_regs *regs); 22 int __user *child_tidp, int p6, struct pt_regs *regs);
diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h
index bd377a36861..26a6825909b 100644
--- a/arch/powerpc/include/asm/unistd.h
+++ b/arch/powerpc/include/asm/unistd.h
@@ -420,6 +420,8 @@
420#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND 420#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
421#define __ARCH_WANT_SYS_NEWFSTATAT 421#define __ARCH_WANT_SYS_NEWFSTATAT
422#endif 422#endif
423#define __ARCH_WANT_SYS_EXECVE
424#define __ARCH_WANT_KERNEL_EXECVE
423 425
424/* 426/*
425 * "Conditional" syscalls 427 * "Conditional" syscalls
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 6eb330a87c3..e6be75fc491 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -446,6 +446,11 @@ ret_from_kernel_thread:
446 li r3,0 446 li r3,0
447 b do_exit # no return 447 b do_exit # no return
448 448
449 .globl __ret_from_kernel_execve
450__ret_from_kernel_execve:
451 addi r1,r3,-STACK_FRAME_OVERHEAD
452 b ret_from_syscall
453
449/* Traced system call support */ 454/* Traced system call support */
450syscall_dotrace: 455syscall_dotrace:
451 SAVE_NVGPRS(r1) 456 SAVE_NVGPRS(r1)
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index d7f4fafc751..1ca3d9fa48c 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -380,6 +380,12 @@ _GLOBAL(ret_from_kernel_thread)
380 li r3,0 380 li r3,0
381 b .do_exit # no return 381 b .do_exit # no return
382 382
383_GLOBAL(__ret_from_kernel_execve)
384 addi r1,r3,-STACK_FRAME_OVERHEAD
385 li r10,1
386 std r10,SOFTE(r1)
387 b syscall_exit
388
383 .section ".toc","aw" 389 .section ".toc","aw"
384DSCR_DEFAULT: 390DSCR_DEFAULT:
385 .tc dscr_default[TC],dscr_default 391 .tc dscr_default[TC],dscr_default
diff --git a/arch/powerpc/kernel/misc.S b/arch/powerpc/kernel/misc.S
index ba16874fe29..7ce26d45777 100644
--- a/arch/powerpc/kernel/misc.S
+++ b/arch/powerpc/kernel/misc.S
@@ -54,13 +54,6 @@ _GLOBAL(add_reloc_offset)
54 .align 3 54 .align 3
552: PPC_LONG 1b 552: PPC_LONG 1b
56 56
57_GLOBAL(kernel_execve)
58 li r0,__NR_execve
59 sc
60 bnslr
61 neg r3,r3
62 blr
63
64_GLOBAL(setjmp) 57_GLOBAL(setjmp)
65 mflr r0 58 mflr r0
66 PPC_STL r0,0(r3) 59 PPC_STL r0,0(r3)
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 3b06898fa17..6fdf044f475 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1064,26 +1064,13 @@ int sys_vfork(unsigned long p1, unsigned long p2, unsigned long p3,
1064 regs, 0, NULL, NULL); 1064 regs, 0, NULL, NULL);
1065} 1065}
1066 1066
1067int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2, 1067void __ret_from_kernel_execve(struct pt_regs *normal)
1068 unsigned long a3, unsigned long a4, unsigned long a5, 1068__noreturn;
1069 struct pt_regs *regs) 1069
1070void ret_from_kernel_execve(struct pt_regs *normal)
1070{ 1071{
1071 int error; 1072 set_thread_flag(TIF_RESTOREALL);
1072 char *filename; 1073 __ret_from_kernel_execve(normal);
1073
1074 filename = getname((const char __user *) a0);
1075 error = PTR_ERR(filename);
1076 if (IS_ERR(filename))
1077 goto out;
1078 flush_fp_to_thread(current);
1079 flush_altivec_to_thread(current);
1080 flush_spe_to_thread(current);
1081 error = do_execve(filename,
1082 (const char __user *const __user *) a1,
1083 (const char __user *const __user *) a2, regs);
1084 putname(filename);
1085out:
1086 return error;
1087} 1074}
1088 1075
1089static inline int valid_irq_stack(unsigned long sp, struct task_struct *p, 1076static inline int valid_irq_stack(unsigned long sp, struct task_struct *p,
diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c
index 81c570633ea..a1ae73a0f35 100644
--- a/arch/powerpc/kernel/sys_ppc32.c
+++ b/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
187 return ret; 187 return ret;
188} 188}
189 189
190long compat_sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
191 unsigned long a3, unsigned long a4, unsigned long a5,
192 struct pt_regs *regs)
193{
194 int error;
195 char * filename;
196
197 filename = getname((char __user *) a0);
198 error = PTR_ERR(filename);
199 if (IS_ERR(filename))
200 goto out;
201 flush_fp_to_thread(current);
202 flush_altivec_to_thread(current);
203
204 error = compat_do_execve(filename, compat_ptr(a1), compat_ptr(a2), regs);
205
206 putname(filename);
207
208out:
209 return error;
210}
211
212/* Note: it is necessary to treat option as an unsigned int, 190/* Note: it is necessary to treat option as an unsigned int,
213 * with the corresponding cast to a signed int to insure that the 191 * with the corresponding cast to a signed int to insure that the
214 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 192 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)