diff options
author | Arnd Bergmann <arnd@arndb.de> | 2009-06-19 11:31:54 +0200 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2009-06-19 14:10:33 +0200 |
commit | f673c032ed13ed8f3fda5922c2190da2892398bc (patch) | |
tree | 8e1145ed21188c77ffdfacba2b22a529c8ddb938 /arch/score | |
parent | 78229db4c4f78f27ecf772fe7489a70530ba9862 (diff) |
score: add generic sys_call_table
This adds back a sys_call_table to the score architecture, which
got lost in the conversion to the generic unistd.h file.
It's rather worrying that the code got submitted without a
system call table, which evidently means that it got zero
testing.
Since the system call table has a different layout from the old
one (which was modeled after the mips-o32 one), I also try to
fix the entry.S path to use it. In the modified calling conventions,
all system call arguments are passed as registers r4 through r9,
instead of r4 through r7 plus stack for the fifth and sixth argument.
This matches what other architectures to when they normally pass
arguments on the stack.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'arch/score')
-rw-r--r-- | arch/score/kernel/Makefile | 3 | ||||
-rw-r--r-- | arch/score/kernel/entry.S | 47 | ||||
-rw-r--r-- | arch/score/kernel/sys_call_table.c | 12 | ||||
-rw-r--r-- | arch/score/kernel/sys_score.c | 9 |
4 files changed, 18 insertions, 53 deletions
diff --git a/arch/score/kernel/Makefile b/arch/score/kernel/Makefile index 1e5de89d5c73..f218673b5d3d 100644 --- a/arch/score/kernel/Makefile +++ b/arch/score/kernel/Makefile @@ -5,6 +5,7 @@ extra-y := head.o vmlinux.lds obj-y += entry.o init_task.o irq.o process.o ptrace.o \ - setup.o signal.o sys_score.o time.o traps.o + setup.o signal.o sys_score.o time.o traps.o \ + sys_call_table.o obj-$(CONFIG_MODULES) += module.o diff --git a/arch/score/kernel/entry.S b/arch/score/kernel/entry.S index 0af89b2f16b0..2f169175bbd9 100644 --- a/arch/score/kernel/entry.S +++ b/arch/score/kernel/entry.S @@ -400,6 +400,8 @@ ENTRY(handle_sys) sw r4, [r0, PT_ORIG_R4] #for restart syscall sw r7, [r0, PT_ORIG_R7] #for restart syscall sw r27, [r0, PT_IS_SYSCALL] # it from syscall + sw r8, [r0, 16] # argument 5 from user r8 + sw r9, [r0, 20] # argument 6 from user r9 lw r9, [r0, PT_EPC] # skip syscall on return addi r9, 4 @@ -408,19 +410,14 @@ ENTRY(handle_sys) cmpi.c r27, __NR_syscalls # check syscall number bgtu illegal_syscall - slli r8, r27, 3 # get syscall routine + slli r8, r27, 2 # get syscall routine la r11, sys_call_table add r11, r11, r8 lw r10, [r11] # get syscall entry - lw r11, [r11, 4] # get number of args cmpz.c r10 beq illegal_syscall - cmpi.c r11, 4 # more than 4 arguments? - bgtu stackargs - -stack_done: lw r8, [r28, TI_FLAGS] li r9, _TIF_SYSCALL_TRACE and.c r8, r8, r9 @@ -475,44 +472,6 @@ syscall_trace_entry: 1: sw r4, [r0, PT_R2] # result j syscall_exit -stackargs: - lw r8, [r0, PT_R0] - andri.c r9, r8, 3 # test whether user sp is align a word - bne bad_stack - subi r11, 5 - slli r9, r11, 2 - add.c r9, r9, r8 - - bmi bad_stack - la r9, 3f # calculate branch address - slli r11, r11, 3 - sub r9, r9, r11 - br r9 - -2: lw r9, [r8, 20] # argument 6 from usp - sw r9, [r0, 20] - -3: lw r9, [r8, 16] # argument 5 from usp - sw r9, [r0, 16] - j stack_done - - .section __ex_table,"a" - .word 2b, bad_stack - .word 3b, bad_stack - .previous - - /* - * The stackpointer for a call with more than 4 arguments is bad. - * We probably should handle this case a bit more drastic. - */ -bad_stack: - neg r27, r27 # error - sw r27, [r0, PT_ORIG_R4] - sw r27, [r0, PT_R4] - ldi r8, 1 # set error flag - sw r8, [r0, PT_R7] - j syscall_return - illegal_syscall: ldi r4, -ENOSYS # error sw r4, [r0, PT_ORIG_R4] diff --git a/arch/score/kernel/sys_call_table.c b/arch/score/kernel/sys_call_table.c new file mode 100644 index 000000000000..287369b88c43 --- /dev/null +++ b/arch/score/kernel/sys_call_table.c @@ -0,0 +1,12 @@ +#include <linux/syscalls.h> +#include <linux/signal.h> +#include <linux/unistd.h> + +#include <asm/syscalls.h> + +#undef __SYSCALL +#define __SYSCALL(nr, call) [nr] = (call), + +void *sys_call_table[__NR_syscalls] = { +#include <asm/unistd.h> +}; diff --git a/arch/score/kernel/sys_score.c b/arch/score/kernel/sys_score.c index 68655f4cbce9..331886104325 100644 --- a/arch/score/kernel/sys_score.c +++ b/arch/score/kernel/sys_score.c @@ -75,14 +75,7 @@ int score_clone(struct pt_regs *regs) if (!newsp) newsp = regs->regs[0]; parent_tidptr = (int __user *)regs->regs[6]; - - child_tidptr = NULL; - if (clone_flags & (CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)) { - int __user *__user *usp = (int __user *__user *)regs->regs[0]; - - if (get_user(child_tidptr, &usp[4])) - return -EFAULT; - } + child_tidptr = (int __user *)regs->regs[8]; return do_fork(clone_flags, newsp, regs, 0, parent_tidptr, child_tidptr); |