aboutsummaryrefslogtreecommitdiff
path: root/arch/sparc/kernel/sys_sparc.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc/kernel/sys_sparc.c')
-rw-r--r--arch/sparc/kernel/sys_sparc.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c
index 002ab4dbe5c..a954a0c0000 100644
--- a/arch/sparc/kernel/sys_sparc.c
+++ b/arch/sparc/kernel/sys_sparc.c
@@ -24,6 +24,7 @@
#include <asm/uaccess.h>
#include <asm/ipc.h>
+#include <asm/unistd.h>
/* #define DEBUG_UNIMP_SYSCALL */
@@ -488,3 +489,25 @@ out:
up_read(&uts_sem);
return err;
}
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+ long __res;
+ register long __g1 __asm__ ("g1") = __NR_execve;
+ register long __o0 __asm__ ("o0") = (long)(filename);
+ register long __o1 __asm__ ("o1") = (long)(argv);
+ register long __o2 __asm__ ("o2") = (long)(envp);
+ asm volatile ("t 0x10\n\t"
+ "bcc 1f\n\t"
+ "mov %%o0, %0\n\t"
+ "sub %%g0, %%o0, %0\n\t"
+ "1:\n\t"
+ : "=r" (__res), "=&r" (__o0)
+ : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__g1)
+ : "cc");
+ return __res;
+}