Commit be6abfa769fa07ce89ac73273360b335ae978805

Authored by Al Viro
1 parent 58254e1002

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
... ... @@ -420,6 +420,8 @@
420 420 #define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
421 421 #define __ARCH_WANT_SYS_NEWFSTATAT
422 422 #endif
  423 +#define __ARCH_WANT_SYS_EXECVE
  424 +#define __ARCH_WANT_KERNEL_EXECVE
423 425  
424 426 /*
425 427 * "Conditional" syscalls
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
... ... @@ -54,13 +54,6 @@
54 54 .align 3
55 55 2: 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 57 _GLOBAL(setjmp)
65 58 mflr r0
66 59 PPC_STL r0,0(r3)
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)