Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 be6abfa7 58254e10

+21 -51
+2
arch/powerpc/include/asm/ptrace.h
··· 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
-3
arch/powerpc/include/asm/syscalls.h
··· 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);
+2
arch/powerpc/include/asm/unistd.h
··· 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
+5
arch/powerpc/kernel/entry_32.S
··· 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)
+6
arch/powerpc/kernel/entry_64.S
··· 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
-7
arch/powerpc/kernel/misc.S
··· 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)
+6 -19
arch/powerpc/kernel/process.c
··· 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,
-22
arch/powerpc/kernel/sys_ppc32.c
··· 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)