score: add generic sys_call_table
authorArnd Bergmann <arnd@arndb.de>
Fri, 19 Jun 2009 09:31:54 +0000 (11:31 +0200)
committerArnd Bergmann <arnd@arndb.de>
Fri, 19 Jun 2009 12:10:33 +0000 (14:10 +0200)
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>
arch/score/kernel/Makefile
arch/score/kernel/entry.S
arch/score/kernel/sys_call_table.c [new file with mode: 0644]
arch/score/kernel/sys_score.c

index 1e5de89..f218673 100644 (file)
@@ -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
index 0af89b2..2f16917 100644 (file)
@@ -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 (file)
index 0000000..287369b
--- /dev/null
@@ -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>
+};
index 68655f4..3318861 100644 (file)
@@ -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);