1753c4dd6SMartin Schwidefsky /* 2753c4dd6SMartin Schwidefsky * Access to user system call parameters and results 3753c4dd6SMartin Schwidefsky * 4753c4dd6SMartin Schwidefsky * Copyright IBM Corp. 2008 5753c4dd6SMartin Schwidefsky * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) 6753c4dd6SMartin Schwidefsky * 7753c4dd6SMartin Schwidefsky * This program is free software; you can redistribute it and/or modify 8753c4dd6SMartin Schwidefsky * it under the terms of the GNU General Public License (version 2 only) 9753c4dd6SMartin Schwidefsky * as published by the Free Software Foundation. 10753c4dd6SMartin Schwidefsky */ 11753c4dd6SMartin Schwidefsky 12753c4dd6SMartin Schwidefsky #ifndef _ASM_SYSCALL_H 13753c4dd6SMartin Schwidefsky #define _ASM_SYSCALL_H 1 14753c4dd6SMartin Schwidefsky 159bf1226bSHeiko Carstens #include <linux/sched.h> 16753c4dd6SMartin Schwidefsky #include <asm/ptrace.h> 17753c4dd6SMartin Schwidefsky 18753c4dd6SMartin Schwidefsky static inline long syscall_get_nr(struct task_struct *task, 19753c4dd6SMartin Schwidefsky struct pt_regs *regs) 20753c4dd6SMartin Schwidefsky { 2159da2139SMartin Schwidefsky return regs->svcnr ? regs->svcnr : -1; 22753c4dd6SMartin Schwidefsky } 23753c4dd6SMartin Schwidefsky 24753c4dd6SMartin Schwidefsky static inline void syscall_rollback(struct task_struct *task, 25753c4dd6SMartin Schwidefsky struct pt_regs *regs) 26753c4dd6SMartin Schwidefsky { 27753c4dd6SMartin Schwidefsky regs->gprs[2] = regs->orig_gpr2; 28753c4dd6SMartin Schwidefsky } 29753c4dd6SMartin Schwidefsky 30753c4dd6SMartin Schwidefsky static inline long syscall_get_error(struct task_struct *task, 31753c4dd6SMartin Schwidefsky struct pt_regs *regs) 32753c4dd6SMartin Schwidefsky { 33753c4dd6SMartin Schwidefsky return (regs->gprs[2] >= -4096UL) ? -regs->gprs[2] : 0; 34753c4dd6SMartin Schwidefsky } 35753c4dd6SMartin Schwidefsky 36753c4dd6SMartin Schwidefsky static inline long syscall_get_return_value(struct task_struct *task, 37753c4dd6SMartin Schwidefsky struct pt_regs *regs) 38753c4dd6SMartin Schwidefsky { 39753c4dd6SMartin Schwidefsky return regs->gprs[2]; 40753c4dd6SMartin Schwidefsky } 41753c4dd6SMartin Schwidefsky 42753c4dd6SMartin Schwidefsky static inline void syscall_set_return_value(struct task_struct *task, 43753c4dd6SMartin Schwidefsky struct pt_regs *regs, 44753c4dd6SMartin Schwidefsky int error, long val) 45753c4dd6SMartin Schwidefsky { 46753c4dd6SMartin Schwidefsky regs->gprs[2] = error ? -error : val; 47753c4dd6SMartin Schwidefsky } 48753c4dd6SMartin Schwidefsky 49753c4dd6SMartin Schwidefsky static inline void syscall_get_arguments(struct task_struct *task, 50753c4dd6SMartin Schwidefsky struct pt_regs *regs, 51753c4dd6SMartin Schwidefsky unsigned int i, unsigned int n, 52753c4dd6SMartin Schwidefsky unsigned long *args) 53753c4dd6SMartin Schwidefsky { 5459da2139SMartin Schwidefsky unsigned long mask = -1UL; 5559da2139SMartin Schwidefsky 56753c4dd6SMartin Schwidefsky BUG_ON(i + n > 6); 57753c4dd6SMartin Schwidefsky #ifdef CONFIG_COMPAT 5859da2139SMartin Schwidefsky if (test_tsk_thread_flag(task, TIF_31BIT)) 5959da2139SMartin Schwidefsky mask = 0xffffffff; 60753c4dd6SMartin Schwidefsky #endif 61753c4dd6SMartin Schwidefsky if (i + n == 6) 6259da2139SMartin Schwidefsky args[--n] = regs->args[0] & mask; 6359da2139SMartin Schwidefsky while (n-- > 0) 6459da2139SMartin Schwidefsky if (i + n > 0) 6559da2139SMartin Schwidefsky args[n] = regs->gprs[2 + i + n] & mask; 6659da2139SMartin Schwidefsky if (i == 0) 6759da2139SMartin Schwidefsky args[0] = regs->orig_gpr2 & mask; 68753c4dd6SMartin Schwidefsky } 69753c4dd6SMartin Schwidefsky 70753c4dd6SMartin Schwidefsky static inline void syscall_set_arguments(struct task_struct *task, 71753c4dd6SMartin Schwidefsky struct pt_regs *regs, 72753c4dd6SMartin Schwidefsky unsigned int i, unsigned int n, 73753c4dd6SMartin Schwidefsky const unsigned long *args) 74753c4dd6SMartin Schwidefsky { 75753c4dd6SMartin Schwidefsky BUG_ON(i + n > 6); 76753c4dd6SMartin Schwidefsky if (i + n == 6) 77753c4dd6SMartin Schwidefsky regs->args[0] = args[--n]; 7859da2139SMartin Schwidefsky while (n-- > 0) 7959da2139SMartin Schwidefsky if (i + n > 0) 8059da2139SMartin Schwidefsky regs->gprs[2 + i + n] = args[n]; 8159da2139SMartin Schwidefsky if (i == 0) 8259da2139SMartin Schwidefsky regs->orig_gpr2 = args[0]; 83753c4dd6SMartin Schwidefsky } 84753c4dd6SMartin Schwidefsky 85753c4dd6SMartin Schwidefsky #endif /* _ASM_SYSCALL_H */ 86