[PATCH] xtensa: fix system call interface

This is a long outstanding patch to finally fix the syscall interface.  The
constants used for the system calls are those we have provided in our libc
patches.  This patch also fixes the shmbuf and stat structure, and fcntl
definitions.

Signed-off-by: Chris Zankel <chris@zankel.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
Chris Zankel
2006-12-10 02:18:52 -08:00
committed by Linus Torvalds
parent 173d668138
commit fc4fb2adf9
14 changed files with 1048 additions and 962 deletions

View File

@@ -87,6 +87,11 @@ int main(void)
DEFINE(MM_CONTEXT, offsetof (struct mm_struct, context));
BLANK();
DEFINE(PT_SINGLESTEP_BIT, PT_SINGLESTEP_BIT);
/* constants */
DEFINE(_CLONE_VM, CLONE_VM);
DEFINE(_CLONE_UNTRACED, CLONE_UNTRACED);
return 0;
}

View File

@@ -1004,13 +1004,10 @@ ENTRY(fast_syscall_kernel)
rsr a0, DEPC # get syscall-nr
_beqz a0, fast_syscall_spill_registers
addi a0, a0, -__NR_sysxtensa
_beqz a0, fast_syscall_sysxtensa
_beqi a0, __NR_xtensa, fast_syscall_xtensa
j kernel_exception
ENTRY(fast_syscall_user)
/* Skip syscall. */
@@ -1024,9 +1021,7 @@ ENTRY(fast_syscall_user)
rsr a0, DEPC # get syscall-nr
_beqz a0, fast_syscall_spill_registers
addi a0, a0, -__NR_sysxtensa
_beqz a0, fast_syscall_sysxtensa
_beqi a0, __NR_xtensa, fast_syscall_xtensa
j user_exception
@@ -1047,18 +1042,19 @@ ENTRY(fast_syscall_unrecoverable)
/*
* sysxtensa syscall handler
*
* int sysxtensa (XTENSA_ATOMIC_SET, ptr, val, unused);
* int sysxtensa (XTENSA_ATOMIC_ADD, ptr, val, unused);
* int sysxtensa (XTENSA_ATOMIC_EXG_ADD, ptr, val, unused);
* int sysxtensa (XTENSA_ATOMIC_CMP_SWP, ptr, oldval, newval);
* a2 a6 a3 a4 a5
* int sysxtensa (SYS_XTENSA_ATOMIC_SET, ptr, val, unused);
* int sysxtensa (SYS_XTENSA_ATOMIC_ADD, ptr, val, unused);
* int sysxtensa (SYS_XTENSA_ATOMIC_EXG_ADD, ptr, val, unused);
* int sysxtensa (SYS_XTENSA_ATOMIC_CMP_SWP, ptr, oldval, newval);
* a2 a6 a3 a4 a5
*
* Entry condition:
*
* a0: trashed, original value saved on stack (PT_AREG0)
* a0: a2 (syscall-nr), original value saved on stack (PT_AREG0)
* a1: a1
* a2: new stack pointer, original in DEPC
* a3: dispatch table
* a2: new stack pointer, original in a0 and DEPC
* a3: dispatch table, original in excsave_1
* a4..a15: unchanged
* depc: a2, original value saved on stack (PT_DEPC)
* excsave_1: a3
*
@@ -1091,59 +1087,62 @@ ENTRY(fast_syscall_unrecoverable)
#define CATCH \
67:
ENTRY(fast_syscall_sysxtensa)
ENTRY(fast_syscall_xtensa)
_beqz a6, 1f
_blti a6, SYSXTENSA_COUNT, 2f
1: j user_exception
2: xsr a3, EXCSAVE_1 # restore a3, excsave1
s32i a7, a2, PT_AREG7
xsr a3, EXCSAVE_1 # restore a3, excsave1
s32i a7, a2, PT_AREG7 # we need an additional register
movi a7, 4 # sizeof(unsigned int)
access_ok a0, a3, a7, a2, .Leac
access_ok a3, a7, a0, a2, .Leac # a0: scratch reg, a2: sp
_beqi a6, SYSXTENSA_ATOMIC_SET, .Lset
_beqi a6, SYSXTENSA_ATOMIC_EXG_ADD, .Lexg
_beqi a6, SYSXTENSA_ATOMIC_ADD, .Ladd
addi a6, a6, -1 # assuming SYS_XTENSA_ATOMIC_SET = 1
_bgeui a6, SYS_XTENSA_COUNT - 1, .Lill
_bnei a6, SYS_XTENSA_ATOMIC_CMP_SWP - 1, .Lnswp
/* Fall through for SYSXTENSA_ATOMIC_CMP_SWP */
/* Fall through for ATOMIC_CMP_SWP. */
.Lswp: /* Atomic compare and swap */
TRY l32i a7, a3, 0 # read old value
bne a7, a4, 1f # same as old value? jump
s32i a5, a3, 0 # different, modify value
movi a7, 1 # and return 1
j .Lret
TRY l32i a0, a3, 0 # read old value
bne a0, a4, 1f # same as old value? jump
TRY s32i a5, a3, 0 # different, modify value
l32i a7, a2, PT_AREG7 # restore a7
l32i a0, a2, PT_AREG0 # restore a0
movi a2, 1 # and return 1
addi a6, a6, 1 # restore a6 (really necessary?)
rfe
1: movi a7, 0 # same values: return 0
j .Lret
1: l32i a7, a2, PT_AREG7 # restore a7
l32i a0, a2, PT_AREG0 # restore a0
movi a2, 0 # return 0 (note that we cannot set
addi a6, a6, 1 # restore a6 (really necessary?)
rfe
.Ladd: /* Atomic add */
.Lexg: /* Atomic (exchange) add */
.Lnswp: /* Atomic set, add, and exg_add. */
TRY l32i a7, a3, 0
add a4, a4, a7
s32i a4, a3, 0
j .Lret
TRY l32i a7, a3, 0 # orig
add a0, a4, a7 # + arg
moveqz a0, a4, a6 # set
TRY s32i a0, a3, 0 # write new value
.Lset: /* Atomic set */
TRY l32i a7, a3, 0 # read old value as return value
s32i a4, a3, 0 # write new value
.Lret: mov a0, a2
mov a0, a2
mov a2, a7
l32i a7, a0, PT_AREG7
l32i a3, a0, PT_AREG3
l32i a0, a0, PT_AREG0
l32i a7, a0, PT_AREG7 # restore a7
l32i a0, a0, PT_AREG0 # restore a0
addi a6, a6, 1 # restore a6 (really necessary?)
rfe
CATCH
.Leac: movi a7, -EFAULT
j .Lret
.Leac: l32i a7, a2, PT_AREG7 # restore a7
l32i a0, a2, PT_AREG0 # restore a0
movi a2, -EFAULT
rfe
.Lill: l32i a7, a2, PT_AREG0 # restore a7
l32i a0, a2, PT_AREG0 # restore a0
movi a2, -EINVAL
rfe
@@ -1906,6 +1905,103 @@ ENTRY(fast_coprocessor)
#endif /* XCHAL_EXTRA_SA_SIZE */
/*
* System Calls.
*
* void system_call (struct pt_regs* regs, int exccause)
* a2 a3
*/
ENTRY(system_call)
entry a1, 32
/* regs->syscall = regs->areg[2] */
l32i a3, a2, PT_AREG2
mov a6, a2
movi a4, do_syscall_trace_enter
s32i a3, a2, PT_SYSCALL
callx4 a4
/* syscall = sys_call_table[syscall_nr] */
movi a4, sys_call_table;
movi a5, __NR_syscall_count
movi a6, -ENOSYS
bgeu a3, a5, 1f
addx4 a4, a3, a4
l32i a4, a4, 0
movi a5, sys_ni_syscall;
beq a4, a5, 1f
/* Load args: arg0 - arg5 are passed via regs. */
l32i a6, a2, PT_AREG6
l32i a7, a2, PT_AREG3
l32i a8, a2, PT_AREG4
l32i a9, a2, PT_AREG5
l32i a10, a2, PT_AREG8
l32i a11, a2, PT_AREG9
/* Pass one additional argument to the syscall: pt_regs (on stack) */
s32i a2, a1, 0
callx4 a4
1: /* regs->areg[2] = return_value */
s32i a6, a2, PT_AREG2
movi a4, do_syscall_trace_leave
mov a6, a2
callx4 a4
retw
/*
* Create a kernel thread
*
* int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
* a2 a2 a3 a4
*/
ENTRY(kernel_thread)
entry a1, 16
mov a5, a2 # preserve fn over syscall
mov a7, a3 # preserve args over syscall
movi a3, _CLONE_VM | _CLONE_UNTRACED
movi a2, __NR_clone
or a6, a4, a3 # arg0: flags
mov a3, a1 # arg1: sp
syscall
beq a3, a1, 1f # branch if parent
mov a6, a7 # args
callx4 a5 # fn(args)
movi a2, __NR_exit
syscall # return value of fn(args) still in a6
1: retw
/*
* Do a system call from kernel instead of calling sys_execve, so we end up
* with proper pt_regs.
*
* int kernel_execve(const char *fname, char *const argv[], charg *const envp[])
* a2 a2 a3 a4
*/
ENTRY(kernel_execve)
entry a1, 16
mov a6, a2 # arg0 is in a6
movi a2, __NR_execve
syscall
retw
/*
* Task switch.
*
@@ -1964,33 +2060,9 @@ ENTRY(ret_from_fork)
movi a4, schedule_tail
callx4 a4
movi a4, do_syscall_trace
movi a4, do_syscall_trace_leave
mov a6, a1
callx4 a4
j common_exception_return
/*
* Table of syscalls
*/
.data
.align 4
.global sys_call_table
sys_call_table:
#define SYSCALL(call, narg) .word call
#include "syscalls.h"
/*
* Number of arguments of each syscall
*/
.global sys_narg_table
sys_narg_table:
#undef SYSCALL
#define SYSCALL(call, narg) .byte narg
#include "syscalls.h"

View File

@@ -160,36 +160,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
}
/*
* Create a kernel thread
*/
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
{
long retval;
__asm__ __volatile__
("mov a5, %4\n\t" /* preserve fn in a5 */
"mov a6, %3\n\t" /* preserve and setup arg in a6 */
"movi a2, %1\n\t" /* load __NR_clone for syscall*/
"mov a3, sp\n\t" /* sp check and sys_clone */
"mov a4, %5\n\t" /* load flags for syscall */
"syscall\n\t"
"beq a3, sp, 1f\n\t" /* branch if parent */
"callx4 a5\n\t" /* call fn */
"movi a2, %2\n\t" /* load __NR_exit for syscall */
"mov a3, a6\n\t" /* load fn return value */
"syscall\n"
"1:\n\t"
"mov %0, a2\n\t" /* parent returns zero */
:"=r" (retval)
:"i" (__NR_clone), "i" (__NR_exit),
"r" (arg), "r" (fn),
"r" (flags | CLONE_VM)
: "a2", "a3", "a4", "a5", "a6" );
return retval;
}
/*
* These bracket the sleeping functions..
*/
@@ -452,3 +422,44 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *r)
{
return dump_task_fpu(regs, current, r);
}
asmlinkage
long xtensa_clone(unsigned long clone_flags, unsigned long newsp,
void __user *parent_tid, void *child_tls,
void __user *child_tid, long a5,
struct pt_regs *regs)
{
if (!newsp)
newsp = regs->areg[1];
return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid);
}
/*
* * xtensa_execve() executes a new program.
* */
asmlinkage
long xtensa_execve(char __user *name, char __user * __user *argv,
char __user * __user *envp,
long a3, long a4, long a5,
struct pt_regs *regs)
{
long error;
char * filename;
filename = getname(name);
error = PTR_ERR(filename);
if (IS_ERR(filename))
goto out;
// FIXME: release coprocessor??
error = do_execve(filename, argv, envp, regs);
if (error == 0) {
task_lock(current);
current->ptrace &= ~PT_DTRACE;
task_unlock(current);
}
putname(filename);
out:
return error;
}

View File

@@ -332,12 +332,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
void do_syscall_trace(void)
{
if (!test_thread_flag(TIF_SYSCALL_TRACE))
return;
if (!(current->ptrace & PT_PTRACED))
return;
/*
* The 0x80 provides a way for the tracing parent to distinguish
* between a syscall stop and SIGTRAP delivery
@@ -354,3 +348,23 @@ void do_syscall_trace(void)
current->exit_code = 0;
}
}
void do_syscall_trace_enter(struct pt_regs *regs)
{
if (test_thread_flag(TIF_SYSCALL_TRACE)
&& (current->ptrace & PT_PTRACED))
do_syscall_trace();
#if 0
if (unlikely(current->audit_context))
audit_syscall_entry(current, AUDIT_ARCH_XTENSA..);
#endif
}
void do_syscall_trace_leave(struct pt_regs *regs)
{
if ((test_thread_flag(TIF_SYSCALL_TRACE))
&& (current->ptrace & PT_PTRACED))
do_syscall_trace();
}

View File

@@ -46,7 +46,7 @@ extern struct task_struct *coproc_owners[];
* Atomically swap in the new signal mask, and wait for a signal.
*/
int sys_sigsuspend(struct pt_regs *regs)
int xtensa_sigsuspend(struct pt_regs *regs)
{
old_sigset_t mask = (old_sigset_t) regs->areg[3];
sigset_t saveset;
@@ -68,7 +68,7 @@ int sys_sigsuspend(struct pt_regs *regs)
}
asmlinkage int
sys_rt_sigsuspend(struct pt_regs *regs)
xtensa_rt_sigsuspend(struct pt_regs *regs)
{
sigset_t *unewset = (sigset_t *) regs->areg[4];
size_t sigsetsize = (size_t) regs->areg[3];
@@ -96,7 +96,7 @@ sys_rt_sigsuspend(struct pt_regs *regs)
}
asmlinkage int
sys_sigaction(int sig, const struct old_sigaction *act,
xtensa_sigaction(int sig, const struct old_sigaction *act,
struct old_sigaction *oact)
{
struct k_sigaction new_ka, old_ka;
@@ -128,7 +128,7 @@ sys_sigaction(int sig, const struct old_sigaction *act,
}
asmlinkage int
sys_sigaltstack(struct pt_regs *regs)
xtensa_sigaltstack(struct pt_regs *regs)
{
const stack_t *uss = (stack_t *) regs->areg[4];
stack_t *uoss = (stack_t *) regs->areg[3];
@@ -350,7 +350,7 @@ setup_sigcontext(struct sigcontext *sc, struct _cpstate *cpstate,
return err;
}
asmlinkage int sys_sigreturn(struct pt_regs *regs)
asmlinkage int xtensa_sigreturn(struct pt_regs *regs)
{
struct sigframe *frame = (struct sigframe *)regs->areg[1];
sigset_t set;
@@ -382,7 +382,7 @@ badframe:
return 0;
}
asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
asmlinkage int xtensa_rt_sigreturn(struct pt_regs *regs)
{
struct rt_sigframe *frame = (struct rt_sigframe *)regs->areg[1];
sigset_t set;

View File

@@ -0,0 +1,95 @@
/*
* arch/xtensa/kernel/syscall.c
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2001 - 2005 Tensilica Inc.
* Copyright (C) 2000 Silicon Graphics, Inc.
* Copyright (C) 1995 - 2000 by Ralf Baechle
*
* Joe Taylor <joe@tensilica.com, joetylr@yahoo.com>
* Marc Gauthier <marc@tensilica.com, marc@alumni.uwaterloo.ca>
* Chris Zankel <chris@zankel.net>
* Kevin Chea
*
*/
#include <asm/uaccess.h>
#include <asm/syscalls.h>
#include <asm/unistd.h>
#include <linux/linkage.h>
#include <linux/stringify.h>
#include <linux/errno.h>
#include <linux/syscalls.h>
#include <linux/file.h>
#include <linux/fs.h>
#include <linux/mman.h>
#include <linux/shm.h>
typedef void (*syscall_t)(void);
syscall_t sys_call_table[__NR_syscall_count] /* FIXME __cacheline_aligned */= {
[0 ... __NR_syscall_count - 1] = (syscall_t)&sys_ni_syscall,
#undef __SYSCALL
#define __SYSCALL(nr,symbol,nargs) [ nr ] = (syscall_t)symbol,
#undef _XTENSA_UNISTD_H
#undef __KERNEL_SYSCALLS__
#include <asm/unistd.h>
};
/*
* xtensa_pipe() is the normal C calling standard for creating a pipe. It's not
* the way unix traditional does this, though.
*/
asmlinkage long xtensa_pipe(int __user *userfds)
{
int fd[2];
int error;
error = do_pipe(fd);
if (!error) {
if (copy_to_user(userfds, fd, 2 * sizeof(int)))
error = -EFAULT;
}
return error;
}
asmlinkage long xtensa_mmap2(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags,
unsigned long fd, unsigned long pgoff)
{
int error = -EBADF;
struct file * file = NULL;
flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
if (!(flags & MAP_ANONYMOUS)) {
file = fget(fd);
if (!file)
goto out;
}
down_write(&current->mm->mmap_sem);
error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
up_write(&current->mm->mmap_sem);
if (file)
fput(file);
out:
return error;
}
asmlinkage long xtensa_shmat(int shmid, char __user *shmaddr, int shmflg)
{
unsigned long ret;
long err;
err = do_shmat(shmid, shmaddr, shmflg, &ret);
if (err)
return err;
return (long)ret;
}

View File

@@ -1,288 +0,0 @@
/*
* arch/xtensa/kernel/syscalls.c
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2001 - 2005 Tensilica Inc.
* Copyright (C) 2000 Silicon Graphics, Inc.
* Copyright (C) 1995 - 2000 by Ralf Baechle
*
* Joe Taylor <joe@tensilica.com, joetylr@yahoo.com>
* Marc Gauthier <marc@tensilica.com, marc@alumni.uwaterloo.ca>
* Chris Zankel <chris@zankel.net>
* Kevin Chea
*
*/
#define DEBUG 0
#include <linux/linkage.h>
#include <linux/mm.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/mman.h>
#include <linux/sched.h>
#include <linux/file.h>
#include <linux/slab.h>
#include <linux/utsname.h>
#include <linux/unistd.h>
#include <linux/stringify.h>
#include <linux/syscalls.h>
#include <linux/sem.h>
#include <linux/msg.h>
#include <linux/shm.h>
#include <linux/errno.h>
#include <asm/ptrace.h>
#include <asm/signal.h>
#include <asm/uaccess.h>
#include <asm/hardirq.h>
#include <asm/mman.h>
#include <asm/shmparam.h>
#include <asm/page.h>
extern void do_syscall_trace(void);
typedef int (*syscall_t)(void *a0,...);
extern syscall_t sys_call_table[];
extern unsigned char sys_narg_table[];
/*
* sys_pipe() is the normal C calling standard for creating a pipe. It's not
* the way unix traditional does this, though.
*/
int sys_pipe(int __user *userfds)
{
int fd[2];
int error;
error = do_pipe(fd);
if (!error) {
if (copy_to_user(userfds, fd, 2 * sizeof(int)))
error = -EFAULT;
}
return error;
}
/*
* Common code for old and new mmaps.
*/
long sys_mmap(unsigned long addr, unsigned long len, unsigned long prot,
unsigned long flags, unsigned long fd, unsigned long pgoff)
{
int error = -EBADF;
struct file * file = NULL;
flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
if (!(flags & MAP_ANONYMOUS)) {
file = fget(fd);
if (!file)
goto out;
}
down_write(&current->mm->mmap_sem);
error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
up_write(&current->mm->mmap_sem);
if (file)
fput(file);
out:
return error;
}
int sys_clone(struct pt_regs *regs)
{
unsigned long clone_flags;
unsigned long newsp;
int __user *parent_tidptr, *child_tidptr;
clone_flags = regs->areg[4];
newsp = regs->areg[3];
parent_tidptr = (int __user *)regs->areg[5];
child_tidptr = (int __user *)regs->areg[6];
if (!newsp)
newsp = regs->areg[1];
return do_fork(clone_flags,newsp,regs,0,parent_tidptr,child_tidptr);
}
/*
* sys_execve() executes a new program.
*/
int sys_execve(struct pt_regs *regs)
{
int error;
char * filename;
filename = getname((char *) (long)regs->areg[5]);
error = PTR_ERR(filename);
if (IS_ERR(filename))
goto out;
error = do_execve(filename, (char **) (long)regs->areg[3],
(char **) (long)regs->areg[4], regs);
putname(filename);
out:
return error;
}
int sys_uname(struct old_utsname * name)
{
if (name && !copy_to_user(name, utsname(), sizeof (*name)))
return 0;
return -EFAULT;
}
/*
* Build the string table for the builtin "poor man's strace".
*/
#if DEBUG
#define SYSCALL(fun, narg) #fun,
static char *sfnames[] = {
#include "syscalls.h"
};
#undef SYS
#endif
void system_call (struct pt_regs *regs)
{
syscall_t syscall;
unsigned long parm0, parm1, parm2, parm3, parm4, parm5;
int nargs, res;
unsigned int syscallnr;
int ps;
#if DEBUG
int i;
unsigned long parms[6];
char *sysname;
#endif
regs->syscall = regs->areg[2];
do_syscall_trace();
/* Have to load after syscall_trace because strace
* sometimes changes regs->syscall.
*/
syscallnr = regs->syscall;
parm0 = parm1 = parm2 = parm3 = parm4 = parm5 = 0;
/* Restore interrupt level to syscall invoker's.
* If this were in assembly, we wouldn't disable
* interrupts in the first place:
*/
local_save_flags (ps);
local_irq_restore((ps & ~PS_INTLEVEL_MASK) |
(regs->ps & PS_INTLEVEL_MASK) );
if (syscallnr > __NR_Linux_syscalls) {
regs->areg[2] = -ENOSYS;
return;
}
syscall = sys_call_table[syscallnr];
nargs = sys_narg_table[syscallnr];
if (syscall == NULL) {
regs->areg[2] = -ENOSYS;
return;
}
/* There shouldn't be more than six arguments in the table! */
if (nargs > 6)
panic("Internal error - too many syscall arguments (%d)!\n",
nargs);
/* Linux takes system-call arguments in registers. The ABI
* and Xtensa software conventions require the system-call
* number in a2. If an argument exists in a2, we move it to
* the next available register. Note that for improved
* efficiency, we do NOT shift all parameters down one
* register to maintain the original order.
*
* At best case (zero arguments), we just write the syscall
* number to a2. At worst case (1 to 6 arguments), we move
* the argument in a2 to the next available register, then
* write the syscall number to a2.
*
* For clarity, the following truth table enumerates all
* possibilities.
*
* arguments syscall number arg0, arg1, arg2, arg3, arg4, arg5
* --------- -------------- ----------------------------------
* 0 a2
* 1 a2 a3
* 2 a2 a4, a3
* 3 a2 a5, a3, a4
* 4 a2 a6, a3, a4, a5
* 5 a2 a7, a3, a4, a5, a6
* 6 a2 a8, a3, a4, a5, a6, a7
*/
if (nargs) {
parm0 = regs->areg[nargs+2];
parm1 = regs->areg[3];
parm2 = regs->areg[4];
parm3 = regs->areg[5];
parm4 = regs->areg[6];
parm5 = regs->areg[7];
} else /* nargs == 0 */
parm0 = (unsigned long) regs;
#if DEBUG
parms[0] = parm0;
parms[1] = parm1;
parms[2] = parm2;
parms[3] = parm3;
parms[4] = parm4;
parms[5] = parm5;
sysname = sfnames[syscallnr];
if (strncmp(sysname, "sys_", 4) == 0)
sysname = sysname + 4;
printk("\017SYSCALL:I:%x:%d:%s %s(", regs->pc, current->pid,
current->comm, sysname);
for (i = 0; i < nargs; i++)
printk((i>0) ? ", %#lx" : "%#lx", parms[i]);
printk(")\n");
#endif
res = syscall((void *)parm0, parm1, parm2, parm3, parm4, parm5);
#if DEBUG
printk("\017SYSCALL:O:%d:%s %s(",current->pid, current->comm, sysname);
for (i = 0; i < nargs; i++)
printk((i>0) ? ", %#lx" : "%#lx", parms[i]);
if (res < 4096)
printk(") = %d\n", res);
else
printk(") = %#x\n", res);
#endif /* DEBUG */
regs->areg[2] = res;
do_syscall_trace();
}
/*
* 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;
asm volatile (
" mov a5, %2 \n"
" mov a4, %4 \n"
" mov a3, %3 \n"
" movi a2, %1 \n"
" syscall \n"
" mov %0, a2 \n"
: "=a" (__res)
: "i" (__NR_execve), "a" (filename), "a" (argv), "a" (envp)
: "a2", "a3", "a4", "a5");
return __res;
}

View File

@@ -1,247 +0,0 @@
/*
* arch/xtensa/kernel/syscalls.h
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 1995, 1996, 1997, 1998 by Ralf Baechle
* Copyright (C) 2001 - 2005 Tensilica Inc.
*
* Changes by Joe Taylor <joe@tensilica.com>
*/
/*
* This file is being included twice - once to build a list of all
* syscalls and once to build a table of how many arguments each syscall
* accepts. Syscalls that receive a pointer to the saved registers are
* marked as having zero arguments.
*
* The binary compatibility calls are in a separate list.
*
* Entry '0' used to be system_call. It's removed to disable indirect
* system calls for now so user tasks can't recurse. See mips'
* sys_syscall for a comparable example.
*/
SYSCALL(0, 0) /* 00 */
SYSCALL(sys_exit, 1)
SYSCALL(sys_ni_syscall, 0)
SYSCALL(sys_read, 3)
SYSCALL(sys_write, 3)
SYSCALL(sys_open, 3) /* 05 */
SYSCALL(sys_close, 1)
SYSCALL(sys_ni_syscall, 3)
SYSCALL(sys_creat, 2)
SYSCALL(sys_link, 2)
SYSCALL(sys_unlink, 1) /* 10 */
SYSCALL(sys_execve, 0)
SYSCALL(sys_chdir, 1)
SYSCALL(sys_ni_syscall, 1)
SYSCALL(sys_mknod, 3)
SYSCALL(sys_chmod, 2) /* 15 */
SYSCALL(sys_lchown, 3)
SYSCALL(sys_ni_syscall, 0)
SYSCALL(sys_newstat, 2)
SYSCALL(sys_lseek, 3)
SYSCALL(sys_getpid, 0) /* 20 */
SYSCALL(sys_mount, 5)
SYSCALL(sys_ni_syscall, 1)
SYSCALL(sys_setuid, 1)
SYSCALL(sys_getuid, 0)
SYSCALL(sys_ni_syscall, 1) /* 25 */
SYSCALL(sys_ptrace, 4)
SYSCALL(sys_ni_syscall, 1)
SYSCALL(sys_newfstat, 2)
SYSCALL(sys_ni_syscall, 0)
SYSCALL(sys_utime, 2) /* 30 */
SYSCALL(sys_ni_syscall, 0)
SYSCALL(sys_ni_syscall, 0)
SYSCALL(sys_access, 2)
SYSCALL(sys_ni_syscall, 1)
SYSCALL(sys_ni_syscall, 0) /* 35 */
SYSCALL(sys_sync, 0)
SYSCALL(sys_kill, 2)
SYSCALL(sys_rename, 2)
SYSCALL(sys_mkdir, 2)
SYSCALL(sys_rmdir, 1) /* 40 */
SYSCALL(sys_dup, 1)
SYSCALL(sys_pipe, 1)
SYSCALL(sys_times, 1)
SYSCALL(sys_ni_syscall, 0)
SYSCALL(sys_brk, 1) /* 45 */
SYSCALL(sys_setgid, 1)
SYSCALL(sys_getgid, 0)
SYSCALL(sys_ni_syscall, 0)
SYSCALL(sys_geteuid, 0)
SYSCALL(sys_getegid, 0) /* 50 */
SYSCALL(sys_acct, 1)
SYSCALL(sys_umount, 2)
SYSCALL(sys_ni_syscall, 0)
SYSCALL(sys_ioctl, 3)
SYSCALL(sys_fcntl, 3) /* 55 */
SYSCALL(sys_ni_syscall, 2)
SYSCALL(sys_setpgid, 2)
SYSCALL(sys_ni_syscall, 0)
SYSCALL(sys_ni_syscall, 0)
SYSCALL(sys_umask, 1) /* 60 */
SYSCALL(sys_chroot, 1)
SYSCALL(sys_ustat, 2)
SYSCALL(sys_dup2, 2)
SYSCALL(sys_getppid, 0)
SYSCALL(sys_ni_syscall, 0) /* 65 */
SYSCALL(sys_setsid, 0)
SYSCALL(sys_sigaction, 3)
SYSCALL(sys_ni_syscall, 0)
SYSCALL(sys_ni_syscall, 1)
SYSCALL(sys_setreuid, 2) /* 70 */
SYSCALL(sys_setregid, 2)
SYSCALL(sys_sigsuspend, 0)
SYSCALL(sys_ni_syscall, 1)
SYSCALL(sys_sethostname, 2)
SYSCALL(sys_setrlimit, 2) /* 75 */
SYSCALL(sys_getrlimit, 2)
SYSCALL(sys_getrusage, 2)
SYSCALL(sys_gettimeofday, 2)
SYSCALL(sys_settimeofday, 2)
SYSCALL(sys_getgroups, 2) /* 80 */
SYSCALL(sys_setgroups, 2)
SYSCALL(sys_ni_syscall, 0)
SYSCALL(sys_symlink, 2)
SYSCALL(sys_newlstat, 2)
SYSCALL(sys_readlink, 3) /* 85 */
SYSCALL(sys_uselib, 1)
SYSCALL(sys_swapon, 2)
SYSCALL(sys_reboot, 3)
SYSCALL(sys_ni_syscall, 3)
SYSCALL(sys_ni_syscall, 6) /* 90 */
SYSCALL(sys_munmap, 2)
SYSCALL(sys_truncate, 2)
SYSCALL(sys_ftruncate, 2)
SYSCALL(sys_fchmod, 2)
SYSCALL(sys_fchown, 3) /* 95 */
SYSCALL(sys_getpriority, 2)
SYSCALL(sys_setpriority, 3)
SYSCALL(sys_ni_syscall, 0)
SYSCALL(sys_statfs, 2)
SYSCALL(sys_fstatfs, 2) /* 100 */
SYSCALL(sys_ni_syscall, 3)
SYSCALL(sys_ni_syscall, 2)
SYSCALL(sys_syslog, 3)
SYSCALL(sys_setitimer, 3)
SYSCALL(sys_getitimer, 2) /* 105 */
SYSCALL(sys_newstat, 2)
SYSCALL(sys_newlstat, 2)
SYSCALL(sys_newfstat, 2)
SYSCALL(sys_uname, 1)
SYSCALL(sys_ni_syscall, 0) /* 110 */
SYSCALL(sys_vhangup, 0)
SYSCALL(sys_ni_syscall, 0)
SYSCALL(sys_ni_syscall, 0)
SYSCALL(sys_wait4, 4)
SYSCALL(sys_swapoff, 1) /* 115 */
SYSCALL(sys_sysinfo, 1)
SYSCALL(sys_ni_syscall, 0)
SYSCALL(sys_fsync, 1)
SYSCALL(sys_sigreturn, 0)
SYSCALL(sys_clone, 0) /* 120 */
SYSCALL(sys_setdomainname, 2)
SYSCALL(sys_newuname, 1)
SYSCALL(sys_ni_syscall, 0)
SYSCALL(sys_adjtimex, 1)
SYSCALL(sys_mprotect, 3) /* 125 */
SYSCALL(sys_ni_syscall, 3)
SYSCALL(sys_ni_syscall, 2)
SYSCALL(sys_init_module, 2)
SYSCALL(sys_delete_module, 1)
SYSCALL(sys_ni_syscall, 1) /* 130 */
SYSCALL(sys_quotactl, 0)
SYSCALL(sys_getpgid, 1)
SYSCALL(sys_fchdir, 1)
SYSCALL(sys_bdflush, 2)
SYSCALL(sys_sysfs, 3) /* 135 */
SYSCALL(sys_personality, 1)
SYSCALL(sys_ni_syscall, 0)
SYSCALL(sys_setfsuid, 1)
SYSCALL(sys_setfsgid, 1)
SYSCALL(sys_llseek, 5) /* 140 */
SYSCALL(sys_getdents, 3)
SYSCALL(sys_select, 5)
SYSCALL(sys_flock, 2)
SYSCALL(sys_msync, 3)
SYSCALL(sys_readv, 3) /* 145 */
SYSCALL(sys_writev, 3)
SYSCALL(sys_ni_syscall, 3)
SYSCALL(sys_ni_syscall, 3)
SYSCALL(sys_ni_syscall, 4) /* handled in fast syscall handler. */
SYSCALL(sys_ni_syscall, 0) /* 150 */
SYSCALL(sys_getsid, 1)
SYSCALL(sys_fdatasync, 1)
SYSCALL(sys_sysctl, 1)
SYSCALL(sys_mlock, 2)
SYSCALL(sys_munlock, 2) /* 155 */
SYSCALL(sys_mlockall, 1)
SYSCALL(sys_munlockall, 0)
SYSCALL(sys_sched_setparam,2)
SYSCALL(sys_sched_getparam,2)
SYSCALL(sys_sched_setscheduler,3) /* 160 */
SYSCALL(sys_sched_getscheduler,1)
SYSCALL(sys_sched_yield,0)
SYSCALL(sys_sched_get_priority_max,1)
SYSCALL(sys_sched_get_priority_min,1)
SYSCALL(sys_sched_rr_get_interval,2) /* 165 */
SYSCALL(sys_nanosleep,2)
SYSCALL(sys_mremap,4)
SYSCALL(sys_accept, 3)
SYSCALL(sys_bind, 3)
SYSCALL(sys_connect, 3) /* 170 */
SYSCALL(sys_getpeername, 3)
SYSCALL(sys_getsockname, 3)
SYSCALL(sys_getsockopt, 5)
SYSCALL(sys_listen, 2)
SYSCALL(sys_recv, 4) /* 175 */
SYSCALL(sys_recvfrom, 6)
SYSCALL(sys_recvmsg, 3)
SYSCALL(sys_send, 4)
SYSCALL(sys_sendmsg, 3)
SYSCALL(sys_sendto, 6) /* 180 */
SYSCALL(sys_setsockopt, 5)
SYSCALL(sys_shutdown, 2)
SYSCALL(sys_socket, 3)
SYSCALL(sys_socketpair, 4)
SYSCALL(sys_setresuid, 3) /* 185 */
SYSCALL(sys_getresuid, 3)
SYSCALL(sys_ni_syscall, 5)
SYSCALL(sys_poll, 3)
SYSCALL(sys_nfsservctl, 3)
SYSCALL(sys_setresgid, 3) /* 190 */
SYSCALL(sys_getresgid, 3)
SYSCALL(sys_prctl, 5)
SYSCALL(sys_rt_sigreturn, 0)
SYSCALL(sys_rt_sigaction, 4)
SYSCALL(sys_rt_sigprocmask, 4) /* 195 */
SYSCALL(sys_rt_sigpending, 2)
SYSCALL(sys_rt_sigtimedwait, 4)
SYSCALL(sys_rt_sigqueueinfo, 3)
SYSCALL(sys_rt_sigsuspend, 0)
SYSCALL(sys_pread64, 5) /* 200 */
SYSCALL(sys_pwrite64, 5)
SYSCALL(sys_chown, 3)
SYSCALL(sys_getcwd, 2)
SYSCALL(sys_capget, 2)
SYSCALL(sys_capset, 2) /* 205 */
SYSCALL(sys_sigaltstack, 0)
SYSCALL(sys_sendfile, 4)
SYSCALL(sys_ni_syscall, 0)
SYSCALL(sys_ni_syscall, 0)
SYSCALL(sys_mmap, 6) /* 210 */
SYSCALL(sys_truncate64, 2)
SYSCALL(sys_ftruncate64, 2)
SYSCALL(sys_stat64, 2)
SYSCALL(sys_lstat64, 2)
SYSCALL(sys_fstat64, 2) /* 215 */
SYSCALL(sys_pivot_root, 2)
SYSCALL(sys_mincore, 3)
SYSCALL(sys_madvise, 3)
SYSCALL(sys_getdents64, 3)
SYSCALL(sys_ni_syscall, 0) /* 220 */