diff options
Diffstat (limited to 'arch/sparc/kernel/sys_sparc.c')
-rw-r--r-- | arch/sparc/kernel/sys_sparc.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c index 002ab4dbe5cb..a954a0c00000 100644 --- a/arch/sparc/kernel/sys_sparc.c +++ b/arch/sparc/kernel/sys_sparc.c | |||
@@ -24,6 +24,7 @@ | |||
24 | 24 | ||
25 | #include <asm/uaccess.h> | 25 | #include <asm/uaccess.h> |
26 | #include <asm/ipc.h> | 26 | #include <asm/ipc.h> |
27 | #include <asm/unistd.h> | ||
27 | 28 | ||
28 | /* #define DEBUG_UNIMP_SYSCALL */ | 29 | /* #define DEBUG_UNIMP_SYSCALL */ |
29 | 30 | ||
@@ -488,3 +489,25 @@ out: | |||
488 | up_read(&uts_sem); | 489 | up_read(&uts_sem); |
489 | return err; | 490 | return err; |
490 | } | 491 | } |
492 | |||
493 | /* | ||
494 | * Do a system call from kernel instead of calling sys_execve so we | ||
495 | * end up with proper pt_regs. | ||
496 | */ | ||
497 | int kernel_execve(const char *filename, char *const argv[], char *const envp[]) | ||
498 | { | ||
499 | long __res; | ||
500 | register long __g1 __asm__ ("g1") = __NR_execve; | ||
501 | register long __o0 __asm__ ("o0") = (long)(filename); | ||
502 | register long __o1 __asm__ ("o1") = (long)(argv); | ||
503 | register long __o2 __asm__ ("o2") = (long)(envp); | ||
504 | asm volatile ("t 0x10\n\t" | ||
505 | "bcc 1f\n\t" | ||
506 | "mov %%o0, %0\n\t" | ||
507 | "sub %%g0, %%o0, %0\n\t" | ||
508 | "1:\n\t" | ||
509 | : "=r" (__res), "=&r" (__o0) | ||
510 | : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__g1) | ||
511 | : "cc"); | ||
512 | return __res; | ||
513 | } | ||