1/* syscall parameter access functions 2 * 3 * Copyright (C) 2009 Red Hat, Inc. All Rights Reserved. 4 * Written by David Howells (dhowells@redhat.com) 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public Licence 8 * as published by the Free Software Foundation; either version 9 * 2 of the Licence, or (at your option) any later version. 10 */ 11 12#ifndef _ASM_SYSCALL_H 13#define _ASM_SYSCALL_H 14 15#include <linux/err.h> 16#include <asm/ptrace.h> 17 18/* 19 * Get the system call number or -1 20 */ 21static inline long syscall_get_nr(struct task_struct *task, 22 struct pt_regs *regs) 23{ 24 return regs->syscallno; 25} 26 27/* 28 * Restore the clobbered GR8 register 29 * (1st syscall arg was overwritten with syscall return or error) 30 */ 31static inline void syscall_rollback(struct task_struct *task, 32 struct pt_regs *regs) 33{ 34 regs->gr8 = regs->orig_gr8; 35} 36 37/* 38 * See if the syscall return value is an error, returning it if it is and 0 if 39 * not 40 */ 41static inline long syscall_get_error(struct task_struct *task, 42 struct pt_regs *regs) 43{ 44 return IS_ERR_VALUE(regs->gr8) ? regs->gr8 : 0; 45} 46 47/* 48 * Get the syscall return value 49 */ 50static inline long syscall_get_return_value(struct task_struct *task, 51 struct pt_regs *regs) 52{ 53 return regs->gr8; 54} 55 56/* 57 * Set the syscall return value 58 */ 59static inline void syscall_set_return_value(struct task_struct *task, 60 struct pt_regs *regs, 61 int error, long val) 62{ 63 if (error) 64 regs->gr8 = -error; 65 else 66 regs->gr8 = val; 67} 68 69/* 70 * Retrieve the system call arguments 71 */ 72static inline void syscall_get_arguments(struct task_struct *task, 73 struct pt_regs *regs, 74 unsigned int i, unsigned int n, 75 unsigned long *args) 76{ 77 /* 78 * Do this simply for now. If we need to start supporting 79 * fetching arguments from arbitrary indices, this will need some 80 * extra logic. Presently there are no in-tree users that depend 81 * on this behaviour. 82 */ 83 BUG_ON(i); 84 85 /* Argument pattern is: GR8, GR9, GR10, GR11, GR12, GR13 */ 86 switch (n) { 87 case 6: args[5] = regs->gr13; 88 case 5: args[4] = regs->gr12; 89 case 4: args[3] = regs->gr11; 90 case 3: args[2] = regs->gr10; 91 case 2: args[1] = regs->gr9; 92 case 1: args[0] = regs->gr8; 93 break; 94 default: 95 BUG(); 96 } 97} 98 99/* 100 * Alter the system call arguments 101 */ 102static inline void syscall_set_arguments(struct task_struct *task, 103 struct pt_regs *regs, 104 unsigned int i, unsigned int n, 105 const unsigned long *args) 106{ 107 /* Same note as above applies */ 108 BUG_ON(i); 109 110 switch (n) { 111 case 6: regs->gr13 = args[5]; 112 case 5: regs->gr12 = args[4]; 113 case 4: regs->gr11 = args[3]; 114 case 3: regs->gr10 = args[2]; 115 case 2: regs->gr9 = args[1]; 116 case 1: regs->gr8 = args[0]; 117 break; 118 default: 119 BUG(); 120 } 121} 122 123#endif /* _ASM_SYSCALL_H */ 124