mirror of
https://github.com/torvalds/linux.git
synced 2024-11-12 07:01:57 +00:00
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>
This commit is contained in:
parent
78229db4c4
commit
f673c032ed
@ -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
|
||||
|
@ -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]
|
||||
|
12
arch/score/kernel/sys_call_table.c
Normal file
12
arch/score/kernel/sys_call_table.c
Normal file
@ -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>
|
||||
};
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user