Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ARC: Syscall support (no-legacy-syscall ABI)

This includes support for generic clone/for/vfork/execve

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Al Viro <viro@ZenIV.linux.org.uk>
Acked-by: Arnd Bergmann <arnd@arndb.de>

+228
+1
arch/arc/Kconfig
··· 9 9 config ARC 10 10 def_bool y 11 11 select ARCH_NO_VIRT_TO_BUS 12 + select CLONE_BACKWARDS 12 13 # ARC Busybox based initramfs absolutely relies on DEVTMPFS for /dev 13 14 select DEVTMPFS if !INITRAMFS_SOURCE="" 14 15 select GENERIC_ATOMIC64
+5
arch/arc/include/asm/ptrace.h
··· 86 86 sp = -1; \ 87 87 sp; \ 88 88 }) 89 + 90 + /* return 1 if in syscall, 0 if Intr or Exception */ 91 + #define in_syscall(regs) (((regs->orig_r8) >= 0 && \ 92 + (regs->orig_r8 <= NR_syscalls)) ? 1 : 0) 93 + 89 94 #endif /* !__ASSEMBLY__ */ 90 95 91 96 #endif /* __KERNEL__ */
+72
arch/arc/include/asm/syscall.h
··· 1 + /* 2 + * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License version 2 as 6 + * published by the Free Software Foundation. 7 + */ 8 + 9 + #ifndef _ASM_ARC_SYSCALL_H 10 + #define _ASM_ARC_SYSCALL_H 1 11 + 12 + #include <linux/err.h> 13 + #include <linux/sched.h> 14 + #include <asm/unistd.h> 15 + #include <asm/ptrace.h> /* in_syscall() */ 16 + 17 + static inline long 18 + syscall_get_nr(struct task_struct *task, struct pt_regs *regs) 19 + { 20 + if (user_mode(regs) && in_syscall(regs)) 21 + return regs->orig_r8; 22 + else 23 + return -1; 24 + } 25 + 26 + static inline void 27 + syscall_rollback(struct task_struct *task, struct pt_regs *regs) 28 + { 29 + /* XXX: I can't fathom how pt_regs->r8 will be clobbered ? */ 30 + regs->r8 = regs->orig_r8; 31 + } 32 + 33 + static inline long 34 + syscall_get_error(struct task_struct *task, struct pt_regs *regs) 35 + { 36 + /* 0 if syscall succeeded, otherwise -Errorcode */ 37 + return IS_ERR_VALUE(regs->r0) ? regs->r0 : 0; 38 + } 39 + 40 + static inline long 41 + syscall_get_return_value(struct task_struct *task, struct pt_regs *regs) 42 + { 43 + return regs->r0; 44 + } 45 + 46 + static inline void 47 + syscall_set_return_value(struct task_struct *task, struct pt_regs *regs, 48 + int error, long val) 49 + { 50 + regs->r0 = (long) error ?: val; 51 + } 52 + 53 + /* 54 + * @i: argument index [0,5] 55 + * @n: number of arguments; n+i must be [1,6]. 56 + */ 57 + static inline void 58 + syscall_get_arguments(struct task_struct *task, struct pt_regs *regs, 59 + unsigned int i, unsigned int n, unsigned long *args) 60 + { 61 + unsigned long *inside_ptregs = &(regs->r0); 62 + inside_ptregs -= i; 63 + 64 + BUG_ON((i + n) > 6); 65 + 66 + while (n--) { 67 + args[i++] = (*inside_ptregs); 68 + inside_ptregs--; 69 + } 70 + } 71 + 72 + #endif
+29
arch/arc/include/asm/syscalls.h
··· 1 + /* 2 + * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License version 2 as 6 + * published by the Free Software Foundation. 7 + */ 8 + 9 + #ifndef _ASM_ARC_SYSCALLS_H 10 + #define _ASM_ARC_SYSCALLS_H 1 11 + 12 + #ifdef __KERNEL__ 13 + 14 + #include <linux/compiler.h> 15 + #include <linux/linkage.h> 16 + #include <linux/types.h> 17 + 18 + int sys_clone_wrapper(int, int, int, int, int); 19 + int sys_fork_wrapper(void); 20 + int sys_vfork_wrapper(void); 21 + int sys_cacheflush(uint32_t, uint32_t uint32_t); 22 + int sys_arc_settls(void *); 23 + int sys_arc_gettls(void); 24 + 25 + #include <asm-generic/syscalls.h> 26 + 27 + #endif /* __KERNEL__ */ 28 + 29 + #endif
+34
arch/arc/include/asm/unistd.h
··· 1 + /* 2 + * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License version 2 as 6 + * published by the Free Software Foundation. 7 + */ 8 + 9 + /******** no-legacy-syscalls-ABI *******/ 10 + 11 + #define __ARCH_WANT_SYS_EXECVE 12 + #define __ARCH_WANT_SYS_CLONE 13 + #define __ARCH_WANT_SYS_VFORK 14 + #define __ARCH_WANT_SYS_FORK 15 + 16 + #define sys_mmap2 sys_mmap_pgoff 17 + 18 + #include <asm-generic/unistd.h> 19 + 20 + #define NR_syscalls __NR_syscalls 21 + 22 + /* ARC specific syscall */ 23 + #define __NR_cacheflush (__NR_arch_specific_syscall + 0) 24 + #define __NR_arc_settls (__NR_arch_specific_syscall + 1) 25 + #define __NR_arc_gettls (__NR_arch_specific_syscall + 2) 26 + 27 + __SYSCALL(__NR_cacheflush, sys_cacheflush) 28 + __SYSCALL(__NR_arc_settls, sys_arc_settls) 29 + __SYSCALL(__NR_arc_gettls, sys_arc_gettls) 30 + 31 + 32 + /* Generic syscall (fs/filesystems.c - lost in asm-generic/unistd.h */ 33 + #define __NR_sysfs (__NR_arch_specific_syscall + 3) 34 + __SYSCALL(__NR_sysfs, sys_sysfs)
+27
arch/arc/kernel/entry.S
··· 569 569 bl @schedule_tail 570 570 b @ret_from_exception 571 571 ARC_EXIT ret_from_fork 572 + 573 + ;################### Special Sys Call Wrappers ########################## 574 + 575 + ; TBD: call do_fork directly from here 576 + ARC_ENTRY sys_fork_wrapper 577 + SAVE_CALLEE_SAVED_USER 578 + bl @sys_fork 579 + DISCARD_CALLEE_SAVED_USER 580 + 581 + b ret_from_system_call 582 + ARC_EXIT sys_fork_wrapper 583 + 584 + ARC_ENTRY sys_vfork_wrapper 585 + SAVE_CALLEE_SAVED_USER 586 + bl @sys_vfork 587 + DISCARD_CALLEE_SAVED_USER 588 + 589 + b ret_from_system_call 590 + ARC_EXIT sys_vfork_wrapper 591 + 592 + ARC_ENTRY sys_clone_wrapper 593 + SAVE_CALLEE_SAVED_USER 594 + bl @sys_clone 595 + DISCARD_CALLEE_SAVED_USER 596 + 597 + b ret_from_system_call 598 + ARC_EXIT sys_clone_wrapper
+42
arch/arc/kernel/process.c
··· 1 + /* 2 + * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License version 2 as 6 + * published by the Free Software Foundation. 7 + * 8 + * Amit Bhor, Kanika Nema: Codito Technologies 2004 9 + */ 10 + 11 + #include <linux/errno.h> 12 + #include <linux/module.h> 13 + #include <linux/sched.h> 14 + #include <linux/mm.h> 15 + #include <linux/fs.h> 16 + #include <linux/unistd.h> 17 + #include <linux/ptrace.h> 18 + #include <linux/slab.h> 19 + #include <linux/syscalls.h> 20 + #include <linux/elf.h> 21 + #include <linux/tick.h> 22 + 23 + SYSCALL_DEFINE1(arc_settls, void *, user_tls_data_ptr) 24 + { 25 + task_thread_info(current)->thr_ptr = (unsigned int)user_tls_data_ptr; 26 + return 0; 27 + } 28 + 29 + /* 30 + * We return the user space TLS data ptr as sys-call return code 31 + * Ideally it should be copy to user. 32 + * However we can cheat by the fact that some sys-calls do return 33 + * absurdly high values 34 + * Since the tls dat aptr is not going to be in range of 0xFFFF_xxxx 35 + * it won't be considered a sys-call error 36 + * and it will be loads better than copy-to-user, which is a definite 37 + * D-TLB Miss 38 + */ 39 + SYSCALL_DEFINE0(arc_gettls) 40 + { 41 + return task_thread_info(current)->thr_ptr; 42 + }
+18
arch/arc/kernel/sys.c
··· 1 + 2 + #include <linux/syscalls.h> 3 + #include <linux/signal.h> 4 + #include <linux/unistd.h> 5 + 6 + #include <asm/syscalls.h> 7 + 8 + #define sys_clone sys_clone_wrapper 9 + #define sys_fork sys_fork_wrapper 10 + #define sys_vfork sys_vfork_wrapper 11 + 12 + #undef __SYSCALL 13 + #define __SYSCALL(nr, call) [nr] = (call), 14 + 15 + void *sys_call_table[NR_syscalls] = { 16 + [0 ... NR_syscalls-1] = sys_ni_syscall, 17 + #include <asm/unistd.h> 18 + };