Commit be6abfa769fa07ce89ac73273360b335ae978805
1 parent
58254e1002
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
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>
Showing 8 changed files with 21 additions and 51 deletions Side-by-side Diff
arch/powerpc/include/asm/ptrace.h
... | ... | @@ -125,6 +125,8 @@ |
125 | 125 | extern int ptrace_put_reg(struct task_struct *task, int regno, |
126 | 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 | 131 | * We use the least-significant bit of the trap field to indicate |
130 | 132 | * whether we have saved the full set of registers, or only a |
arch/powerpc/include/asm/syscalls.h
... | ... | @@ -17,9 +17,6 @@ |
17 | 17 | asmlinkage unsigned long sys_mmap2(unsigned long addr, size_t len, |
18 | 18 | unsigned long prot, unsigned long flags, |
19 | 19 | unsigned long fd, unsigned long pgoff); |
20 | -asmlinkage 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); | |
23 | 20 | asmlinkage int sys_clone(unsigned long clone_flags, unsigned long usp, |
24 | 21 | int __user *parent_tidp, void __user *child_threadptr, |
25 | 22 | int __user *child_tidp, int p6, struct pt_regs *regs); |
arch/powerpc/include/asm/unistd.h
arch/powerpc/kernel/entry_32.S
... | ... | @@ -446,6 +446,11 @@ |
446 | 446 | li r3,0 |
447 | 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 | 454 | /* Traced system call support */ |
450 | 455 | syscall_dotrace: |
451 | 456 | SAVE_NVGPRS(r1) |
arch/powerpc/kernel/entry_64.S
... | ... | @@ -380,6 +380,12 @@ |
380 | 380 | li r3,0 |
381 | 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 | 389 | .section ".toc","aw" |
384 | 390 | DSCR_DEFAULT: |
385 | 391 | .tc dscr_default[TC],dscr_default |
arch/powerpc/kernel/misc.S
arch/powerpc/kernel/process.c
... | ... | @@ -1064,26 +1064,13 @@ |
1064 | 1064 | regs, 0, NULL, NULL); |
1065 | 1065 | } |
1066 | 1066 | |
1067 | -int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2, | |
1068 | - unsigned long a3, unsigned long a4, unsigned long a5, | |
1069 | - struct pt_regs *regs) | |
1070 | -{ | |
1071 | - int error; | |
1072 | - char *filename; | |
1067 | +void __ret_from_kernel_execve(struct pt_regs *normal) | |
1068 | +__noreturn; | |
1073 | 1069 | |
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); | |
1085 | -out: | |
1086 | - return error; | |
1070 | +void ret_from_kernel_execve(struct pt_regs *normal) | |
1071 | +{ | |
1072 | + set_thread_flag(TIF_RESTOREALL); | |
1073 | + __ret_from_kernel_execve(normal); | |
1087 | 1074 | } |
1088 | 1075 | |
1089 | 1076 | static inline int valid_irq_stack(unsigned long sp, struct task_struct *p, |
arch/powerpc/kernel/sys_ppc32.c
... | ... | @@ -187,28 +187,6 @@ |
187 | 187 | return ret; |
188 | 188 | } |
189 | 189 | |
190 | -long 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 | - | |
208 | -out: | |
209 | - return error; | |
210 | -} | |
211 | - | |
212 | 190 | /* Note: it is necessary to treat option as an unsigned int, |
213 | 191 | * with the corresponding cast to a signed int to insure that the |
214 | 192 | * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) |