1 /* 2 * Copyright (C) 2008-2009 Red Hat, Inc. All rights reserved. 3 * Copyright 2010 Tilera Corporation. All Rights Reserved. 4 * Copyright 2015 Regents of the University of California, Berkeley 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation, version 2. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * See asm-generic/syscall.h for descriptions of what we must do here. 16 */ 17 18 #ifndef _ASM_RISCV_SYSCALL_H 19 #define _ASM_RISCV_SYSCALL_H 20 21 #include <uapi/linux/audit.h> 22 #include <linux/sched.h> 23 #include <linux/err.h> 24 25 /* The array of function pointers for syscalls. */ 26 extern void *sys_call_table[]; 27 28 /* 29 * Only the low 32 bits of orig_r0 are meaningful, so we return int. 30 * This importantly ignores the high bits on 64-bit, so comparisons 31 * sign-extend the low 32 bits. 32 */ 33 static inline int syscall_get_nr(struct task_struct *task, 34 struct pt_regs *regs) 35 { 36 return regs->a7; 37 } 38 39 static inline void syscall_set_nr(struct task_struct *task, 40 struct pt_regs *regs, 41 int sysno) 42 { 43 regs->a7 = sysno; 44 } 45 46 static inline void syscall_rollback(struct task_struct *task, 47 struct pt_regs *regs) 48 { 49 regs->a0 = regs->orig_a0; 50 } 51 52 static inline long syscall_get_error(struct task_struct *task, 53 struct pt_regs *regs) 54 { 55 unsigned long error = regs->a0; 56 57 return IS_ERR_VALUE(error) ? error : 0; 58 } 59 60 static inline long syscall_get_return_value(struct task_struct *task, 61 struct pt_regs *regs) 62 { 63 return regs->a0; 64 } 65 66 static inline void syscall_set_return_value(struct task_struct *task, 67 struct pt_regs *regs, 68 int error, long val) 69 { 70 regs->a0 = (long) error ?: val; 71 } 72 73 static inline void syscall_get_arguments(struct task_struct *task, 74 struct pt_regs *regs, 75 unsigned long *args) 76 { 77 args[0] = regs->orig_a0; 78 args++; 79 memcpy(args, ®s->a1, 5 * sizeof(args[0])); 80 } 81 82 static inline void syscall_set_arguments(struct task_struct *task, 83 struct pt_regs *regs, 84 const unsigned long *args) 85 { 86 regs->orig_a0 = args[0]; 87 args++; 88 memcpy(®s->a1, args, 5 * sizeof(regs->a1)); 89 } 90 91 static inline int syscall_get_arch(struct task_struct *task) 92 { 93 #ifdef CONFIG_64BIT 94 return AUDIT_ARCH_RISCV64; 95 #else 96 return AUDIT_ARCH_RISCV32; 97 #endif 98 } 99 100 #endif /* _ASM_RISCV_SYSCALL_H */ 101