blob: 5209f1b182af66937ad178756702c1f06e4b7201 [file] [log] [blame]
/*
* Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Vineetg: July 2009
* -kernel_execve inline asm optimised to prevent un-needed reg shuffling
* Now have 6 instructions in generated code as opposed to 16.
*/
#include <linux/errno.h>
#include <linux/msg.h>
#include <linux/shm.h>
#include <linux/syscalls.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
struct sel_arg_struct {
unsigned long n;
fd_set *inp, *outp, *exp;
struct timeval *tvp;
};
asmlinkage int old_select(struct sel_arg_struct *arg)
{
struct sel_arg_struct a;
if (copy_from_user(&a, arg, sizeof(a)))
return -EFAULT;
/* sys_select() does the appropriate kernel locking */
return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
}
int kernel_execve(const char *filename, char *const argv[], char *const envp[])
{
/* Although the arguments (order, number) to this function are
* same as sys call, we don't need to setup args in regs again.
* However in case mainline kernel changes the order of args to
* kernel_execve, that assumtion will break.
* So to be safe, let gcc know the args for sys call.
* If they match no extra code will be generated
*/
register int arg2 asm ("r1") = (int)argv;
register int arg3 asm ("r2") = (int)envp;
register int filenm_n_ret asm ("r0") = (int)filename;
__asm__ __volatile__(
"mov r8, %1\n\t"
"trap0 \n\t"
:"+r"(filenm_n_ret)
:"i"(__NR_execve), "r"(arg2), "r"(arg3)
:"r8","memory");
return filenm_n_ret;
}
EXPORT_SYMBOL(kernel_execve);