aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/syscall.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel/syscall.c')
-rw-r--r--arch/mips/kernel/syscall.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
index 970e3e96b1d0..26e1a7e78d13 100644
--- a/arch/mips/kernel/syscall.c
+++ b/arch/mips/kernel/syscall.c
@@ -406,3 +406,32 @@ asmlinkage void bad_stack(void)
406{ 406{
407 do_exit(SIGSEGV); 407 do_exit(SIGSEGV);
408} 408}
409
410/*
411 * Do a system call from kernel instead of calling sys_execve so we
412 * end up with proper pt_regs.
413 */
414int kernel_execve(const char *filename, char *const argv[], char *const envp[])
415{
416 register unsigned long __a0 asm("$4") = (unsigned long) filename;
417 register unsigned long __a1 asm("$5") = (unsigned long) argv;
418 register unsigned long __a2 asm("$6") = (unsigned long) envp;
419 register unsigned long __a3 asm("$7");
420 unsigned long __v0;
421
422 __asm__ volatile (" \n"
423 " .set noreorder \n"
424 " li $2, %5 # __NR_execve \n"
425 " syscall \n"
426 " move %0, $2 \n"
427 " .set reorder \n"
428 : "=&r" (__v0), "=r" (__a3)
429 : "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_execve)
430 : "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24",
431 "memory");
432
433 if (__a3 == 0)
434 return __v0;
435
436 return -__v0;
437}