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

nios2: System calls handling

This patch adds support for system calls from userspaces. It uses the
asm-generic/unistd.h definitions with architecture spcific syscall.
The sys_call_table is just an array defined in a C file and it contains
pointers to the syscall functions.

Signed-off-by: Ley Foon Tan <lftan@altera.com>

+270
+138
arch/nios2/include/asm/syscall.h
··· 1 + /* 2 + * Copyright Altera Corporation (C) <2014>. All rights reserved 3 + * 4 + * This program is free software; you can redistribute it and/or modify it 5 + * under the terms and conditions of the GNU General Public License, 6 + * version 2, as published by the Free Software Foundation. 7 + * 8 + * This program is distributed in the hope it will be useful, but WITHOUT 9 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 11 + * more details. 12 + * 13 + * You should have received a copy of the GNU General Public License along with 14 + * this program. If not, see <http://www.gnu.org/licenses/>. 15 + */ 16 + 17 + #ifndef __ASM_NIOS2_SYSCALL_H__ 18 + #define __ASM_NIOS2_SYSCALL_H__ 19 + 20 + #include <linux/err.h> 21 + #include <linux/sched.h> 22 + 23 + static inline int syscall_get_nr(struct task_struct *task, struct pt_regs *regs) 24 + { 25 + return regs->r2; 26 + } 27 + 28 + static inline void syscall_rollback(struct task_struct *task, 29 + struct pt_regs *regs) 30 + { 31 + regs->r2 = regs->orig_r2; 32 + regs->r7 = regs->orig_r7; 33 + } 34 + 35 + static inline long syscall_get_error(struct task_struct *task, 36 + struct pt_regs *regs) 37 + { 38 + return regs->r7 ? regs->r2 : 0; 39 + } 40 + 41 + static inline long syscall_get_return_value(struct task_struct *task, 42 + struct pt_regs *regs) 43 + { 44 + return regs->r2; 45 + } 46 + 47 + static inline void syscall_set_return_value(struct task_struct *task, 48 + struct pt_regs *regs, int error, long val) 49 + { 50 + if (error) { 51 + /* error < 0, but nios2 uses > 0 return value */ 52 + regs->r2 = -error; 53 + regs->r7 = 1; 54 + } else { 55 + regs->r2 = val; 56 + regs->r7 = 0; 57 + } 58 + } 59 + 60 + static inline void syscall_get_arguments(struct task_struct *task, 61 + struct pt_regs *regs, unsigned int i, unsigned int n, 62 + unsigned long *args) 63 + { 64 + BUG_ON(i + n > 6); 65 + 66 + switch (i) { 67 + case 0: 68 + if (!n--) 69 + break; 70 + *args++ = regs->r4; 71 + case 1: 72 + if (!n--) 73 + break; 74 + *args++ = regs->r5; 75 + case 2: 76 + if (!n--) 77 + break; 78 + *args++ = regs->r6; 79 + case 3: 80 + if (!n--) 81 + break; 82 + *args++ = regs->r7; 83 + case 4: 84 + if (!n--) 85 + break; 86 + *args++ = regs->r8; 87 + case 5: 88 + if (!n--) 89 + break; 90 + *args++ = regs->r9; 91 + case 6: 92 + if (!n--) 93 + break; 94 + default: 95 + BUG(); 96 + } 97 + } 98 + 99 + static inline void syscall_set_arguments(struct task_struct *task, 100 + struct pt_regs *regs, unsigned int i, unsigned int n, 101 + const unsigned long *args) 102 + { 103 + BUG_ON(i + n > 6); 104 + 105 + switch (i) { 106 + case 0: 107 + if (!n--) 108 + break; 109 + regs->r4 = *args++; 110 + case 1: 111 + if (!n--) 112 + break; 113 + regs->r5 = *args++; 114 + case 2: 115 + if (!n--) 116 + break; 117 + regs->r6 = *args++; 118 + case 3: 119 + if (!n--) 120 + break; 121 + regs->r7 = *args++; 122 + case 4: 123 + if (!n--) 124 + break; 125 + regs->r8 = *args++; 126 + case 5: 127 + if (!n--) 128 + break; 129 + regs->r9 = *args++; 130 + case 6: 131 + if (!n) 132 + break; 133 + default: 134 + BUG(); 135 + } 136 + } 137 + 138 + #endif
+25
arch/nios2/include/asm/syscalls.h
··· 1 + /* 2 + * Copyright Altera Corporation (C) 2013. All rights reserved 3 + * 4 + * This program is free software; you can redistribute it and/or modify it 5 + * under the terms and conditions of the GNU General Public License, 6 + * version 2, as published by the Free Software Foundation. 7 + * 8 + * This program is distributed in the hope it will be useful, but WITHOUT 9 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 11 + * more details. 12 + * 13 + * You should have received a copy of the GNU General Public License along with 14 + * this program. If not, see <http://www.gnu.org/licenses/>. 15 + * 16 + */ 17 + #ifndef __ASM_NIOS2_SYSCALLS_H 18 + #define __ASM_NIOS2_SYSCALLS_H 19 + 20 + int sys_cacheflush(unsigned long addr, unsigned long len, 21 + unsigned int op); 22 + 23 + #include <asm-generic/syscalls.h> 24 + 25 + #endif /* __ASM_NIOS2_SYSCALLS_H */
+25
arch/nios2/include/uapi/asm/unistd.h
··· 1 + /* 2 + * Copyright (C) 2013 Altera Corporation 3 + * 4 + * This program is free software; you can redistribute it and/or modify it 5 + * under the terms and conditions of the GNU General Public License, 6 + * version 2, as published by the Free Software Foundation. 7 + * 8 + * This program is distributed in the hope it will be useful, but WITHOUT 9 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 11 + * more details. 12 + * 13 + * You should have received a copy of the GNU General Public License along with 14 + * this program. If not, see <http://www.gnu.org/licenses/>. 15 + * 16 + */ 17 + 18 + #define sys_mmap2 sys_mmap_pgoff 19 + 20 + /* Use the standard ABI for syscalls */ 21 + #include <asm-generic/unistd.h> 22 + 23 + /* Additional Nios II specific syscalls. */ 24 + #define __NR_cacheflush (__NR_arch_specific_syscall) 25 + __SYSCALL(__NR_cacheflush, sys_cacheflush)
+53
arch/nios2/kernel/sys_nios2.c
··· 1 + /* 2 + * Copyright (C) 2013 Altera Corporation 3 + * Copyright (C) 2011-2012 Tobias Klauser <tklauser@distanz.ch> 4 + * Copyright (C) 2004 Microtronix Datacom Ltd. 5 + * 6 + * This file is subject to the terms and conditions of the GNU General Public 7 + * License. See the file "COPYING" in the main directory of this archive 8 + * for more details. 9 + */ 10 + 11 + #include <linux/export.h> 12 + #include <linux/file.h> 13 + #include <linux/fs.h> 14 + #include <linux/slab.h> 15 + #include <linux/syscalls.h> 16 + 17 + #include <asm/cacheflush.h> 18 + #include <asm/traps.h> 19 + 20 + /* sys_cacheflush -- flush the processor cache. */ 21 + asmlinkage int sys_cacheflush(unsigned long addr, unsigned long len, 22 + unsigned int op) 23 + { 24 + struct vm_area_struct *vma; 25 + 26 + if (len == 0) 27 + return 0; 28 + 29 + /* We only support op 0 now, return error if op is non-zero.*/ 30 + if (op) 31 + return -EINVAL; 32 + 33 + /* Check for overflow */ 34 + if (addr + len < addr) 35 + return -EFAULT; 36 + 37 + /* 38 + * Verify that the specified address region actually belongs 39 + * to this process. 40 + */ 41 + vma = find_vma(current->mm, addr); 42 + if (vma == NULL || addr < vma->vm_start || addr + len > vma->vm_end) 43 + return -EFAULT; 44 + 45 + flush_cache_range(vma, addr, addr + len); 46 + 47 + return 0; 48 + } 49 + 50 + asmlinkage int sys_getpagesize(void) 51 + { 52 + return PAGE_SIZE; 53 + }
+29
arch/nios2/kernel/syscall_table.c
··· 1 + /* 2 + * Copyright Altera Corporation (C) 2013. All rights reserved 3 + * 4 + * This program is free software; you can redistribute it and/or modify it 5 + * under the terms and conditions of the GNU General Public License, 6 + * version 2, as published by the Free Software Foundation. 7 + * 8 + * This program is distributed in the hope it will be useful, but WITHOUT 9 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 11 + * more details. 12 + * 13 + * You should have received a copy of the GNU General Public License along with 14 + * this program. If not, see <http://www.gnu.org/licenses/>. 15 + * 16 + */ 17 + 18 + #include <linux/syscalls.h> 19 + #include <linux/signal.h> 20 + #include <linux/unistd.h> 21 + 22 + #include <asm/syscalls.h> 23 + 24 + #undef __SYSCALL 25 + #define __SYSCALL(nr, call) [nr] = (call), 26 + 27 + void *sys_call_table[__NR_syscalls] = { 28 + #include <asm/unistd.h> 29 + };