arm: introduce ret_from_kernel_execve(), switch to generic kernel_execve()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
Родитель
9e14f828ee
Коммит
583d632fb3
|
@ -469,6 +469,7 @@
|
||||||
#define __ARCH_WANT_OLD_READDIR
|
#define __ARCH_WANT_OLD_READDIR
|
||||||
#define __ARCH_WANT_SYS_SOCKETCALL
|
#define __ARCH_WANT_SYS_SOCKETCALL
|
||||||
#endif
|
#endif
|
||||||
|
#define __ARCH_WANT_KERNEL_EXECVE
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "Conditional" syscalls
|
* "Conditional" syscalls
|
||||||
|
|
|
@ -103,6 +103,18 @@ ENTRY(ret_from_kernel_thread)
|
||||||
UNWIND(.fnend)
|
UNWIND(.fnend)
|
||||||
ENDPROC(ret_from_kernel_thread)
|
ENDPROC(ret_from_kernel_thread)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* turn a kernel thread into userland process
|
||||||
|
* use: ret_from_kernel_execve(struct pt_regs *normal)
|
||||||
|
*/
|
||||||
|
ENTRY(ret_from_kernel_execve)
|
||||||
|
mov why, #0 @ not a syscall
|
||||||
|
str why, [r0, #S_R0] @ ... and we want 0 in ->ARM_r0 as well
|
||||||
|
get_thread_info tsk @ thread structure
|
||||||
|
mov sp, r0 @ stack pointer just under pt_regs
|
||||||
|
b ret_slow_syscall
|
||||||
|
ENDPROC(ret_from_kernel_execve)
|
||||||
|
|
||||||
.equ NR_syscalls,0
|
.equ NR_syscalls,0
|
||||||
#define CALL(x) .equ NR_syscalls,NR_syscalls+1
|
#define CALL(x) .equ NR_syscalls,NR_syscalls+1
|
||||||
#include "calls.S"
|
#include "calls.S"
|
||||||
|
|
|
@ -79,48 +79,6 @@ out:
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
int kernel_execve(const char *filename,
|
|
||||||
const char *const argv[],
|
|
||||||
const char *const envp[])
|
|
||||||
{
|
|
||||||
struct pt_regs regs;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
memset(®s, 0, sizeof(struct pt_regs));
|
|
||||||
ret = do_execve(filename,
|
|
||||||
(const char __user *const __user *)argv,
|
|
||||||
(const char __user *const __user *)envp, ®s);
|
|
||||||
if (ret < 0)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Save argc to the register structure for userspace.
|
|
||||||
*/
|
|
||||||
regs.ARM_r0 = ret;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We were successful. We won't be returning to our caller, but
|
|
||||||
* instead to user space by manipulating the kernel stack.
|
|
||||||
*/
|
|
||||||
asm( "add r0, %0, %1\n\t"
|
|
||||||
"mov r1, %2\n\t"
|
|
||||||
"mov r2, %3\n\t"
|
|
||||||
"bl memmove\n\t" /* copy regs to top of stack */
|
|
||||||
"mov r8, #0\n\t" /* not a syscall */
|
|
||||||
"mov r9, %0\n\t" /* thread structure */
|
|
||||||
"mov sp, r0\n\t" /* reposition stack pointer */
|
|
||||||
"b ret_to_user"
|
|
||||||
:
|
|
||||||
: "r" (current_thread_info()),
|
|
||||||
"Ir" (THREAD_START_SP - sizeof(regs)),
|
|
||||||
"r" (®s),
|
|
||||||
"Ir" (sizeof(regs))
|
|
||||||
: "r0", "r1", "r2", "r3", "r8", "r9", "ip", "lr", "memory");
|
|
||||||
|
|
||||||
out:
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Since loff_t is a 64 bit type we avoid a lot of ABI hassle
|
* Since loff_t is a 64 bit type we avoid a lot of ABI hassle
|
||||||
* with a different argument ordering.
|
* with a different argument ordering.
|
||||||
|
|
Загрузка…
Ссылка в новой задаче