diff options
Diffstat (limited to 'arch/sh64/kernel/sys_sh64.c')
-rw-r--r-- | arch/sh64/kernel/sys_sh64.c | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/arch/sh64/kernel/sys_sh64.c b/arch/sh64/kernel/sys_sh64.c index c6de1a95af4..ad0fa4e003e 100644 --- a/arch/sh64/kernel/sys_sh64.c +++ b/arch/sh64/kernel/sys_sh64.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <asm/uaccess.h> | 32 | #include <asm/uaccess.h> |
33 | #include <asm/ipc.h> | 33 | #include <asm/ipc.h> |
34 | #include <asm/ptrace.h> | 34 | #include <asm/ptrace.h> |
35 | #include <asm/unistd.h> | ||
35 | 36 | ||
36 | #define REG_3 3 | 37 | #define REG_3 3 |
37 | 38 | ||
@@ -283,3 +284,21 @@ asmlinkage int sys_uname(struct old_utsname * name) | |||
283 | up_read(&uts_sem); | 284 | up_read(&uts_sem); |
284 | return err?-EFAULT:0; | 285 | return err?-EFAULT:0; |
285 | } | 286 | } |
287 | |||
288 | /* | ||
289 | * Do a system call from kernel instead of calling sys_execve so we | ||
290 | * end up with proper pt_regs. | ||
291 | */ | ||
292 | int kernel_execve(const char *filename, char *const argv[], char *const envp[]) | ||
293 | { | ||
294 | register unsigned long __sc0 __asm__ ("r9") = ((0x13 << 16) | __NR_execve); | ||
295 | register unsigned long __sc2 __asm__ ("r2") = (unsigned long) filename; | ||
296 | register unsigned long __sc3 __asm__ ("r3") = (unsigned long) argv; | ||
297 | register unsigned long __sc4 __asm__ ("r4") = (unsigned long) envp; | ||
298 | __asm__ __volatile__ ("trapa %1 !\t\t\t execve(%2,%3,%4)" | ||
299 | : "=r" (__sc0) | ||
300 | : "r" (__sc0), "r" (__sc2), "r" (__sc3), "r" (__sc4) ); | ||
301 | __asm__ __volatile__ ("!dummy %0 %1 %2 %3" | ||
302 | : : "r" (__sc0), "r" (__sc2), "r" (__sc3), "r" (__sc4) : "memory"); | ||
303 | return __sc0; | ||
304 | } | ||