1753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky/* 2753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky * Access to user system call parameters and results 3753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky * 4753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky * Copyright IBM Corp. 2008 5753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) 6753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky * 7753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky * This program is free software; you can redistribute it and/or modify 8753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky * it under the terms of the GNU General Public License (version 2 only) 9753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky * as published by the Free Software Foundation. 10753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky */ 11753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky 12753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky#ifndef _ASM_SYSCALL_H 13753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky#define _ASM_SYSCALL_H 1 14753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky 15579ec9e1ab0bdca2dbc3c942aa1a530a6ec8c349Eric Paris#include <uapi/linux/audit.h> 169bf1226b33dc2f94fc37ffd70ee161e2bda1ff5cHeiko Carstens#include <linux/sched.h> 1720b40a794baf3b4b0320c0a77ce944d5d1a01f25Martin Schwidefsky#include <linux/err.h> 18753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky#include <asm/ptrace.h> 19753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky 20e7b8e675d9c71b868b66f62f725a948047514719Mike Frysinger/* 21e7b8e675d9c71b868b66f62f725a948047514719Mike Frysinger * The syscall table always contains 32 bit pointers since we know that the 22e7b8e675d9c71b868b66f62f725a948047514719Mike Frysinger * address of the function to be called is (way) below 4GB. So the "int" 23e7b8e675d9c71b868b66f62f725a948047514719Mike Frysinger * type here is what we want [need] for both 32 bit and 64 bit systems. 24e7b8e675d9c71b868b66f62f725a948047514719Mike Frysinger */ 25e7b8e675d9c71b868b66f62f725a948047514719Mike Frysingerextern const unsigned int sys_call_table[]; 26616498813b11ffefe1ed36b9f2e4fd2cdbd22f15Martin Schwidefskyextern const unsigned int sys_call_table_emu[]; 27e7b8e675d9c71b868b66f62f725a948047514719Mike Frysinger 28753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefskystatic inline long syscall_get_nr(struct task_struct *task, 29753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky struct pt_regs *regs) 30753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky{ 31d3a73acbc26a4a81a01a35fd162973e53d0386f5Martin Schwidefsky return test_pt_regs_flag(regs, PIF_SYSCALL) ? 32aa33c8cbbae2eb98489a3a363099b362146a8f4cMartin Schwidefsky (regs->int_code & 0xffff) : -1; 33753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky} 34753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky 35753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefskystatic inline void syscall_rollback(struct task_struct *task, 36753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky struct pt_regs *regs) 37753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky{ 38753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky regs->gprs[2] = regs->orig_gpr2; 39753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky} 40753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky 41753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefskystatic inline long syscall_get_error(struct task_struct *task, 42753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky struct pt_regs *regs) 43753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky{ 4420b40a794baf3b4b0320c0a77ce944d5d1a01f25Martin Schwidefsky return IS_ERR_VALUE(regs->gprs[2]) ? regs->gprs[2] : 0; 45753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky} 46753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky 47753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefskystatic inline long syscall_get_return_value(struct task_struct *task, 48753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky struct pt_regs *regs) 49753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky{ 50753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky return regs->gprs[2]; 51753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky} 52753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky 53753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefskystatic inline void syscall_set_return_value(struct task_struct *task, 54753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky struct pt_regs *regs, 55753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky int error, long val) 56753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky{ 57dc295880c6752076f8b94ba3885d0bfff09e3e82Jan Willeke regs->gprs[2] = error ? error : val; 58753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky} 59753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky 60753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefskystatic inline void syscall_get_arguments(struct task_struct *task, 61753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky struct pt_regs *regs, 62753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky unsigned int i, unsigned int n, 63753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky unsigned long *args) 64753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky{ 6559da21398e680e8100625d689c8bebee6a139e93Martin Schwidefsky unsigned long mask = -1UL; 6659da21398e680e8100625d689c8bebee6a139e93Martin Schwidefsky 67753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky BUG_ON(i + n > 6); 68753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky#ifdef CONFIG_COMPAT 6959da21398e680e8100625d689c8bebee6a139e93Martin Schwidefsky if (test_tsk_thread_flag(task, TIF_31BIT)) 7059da21398e680e8100625d689c8bebee6a139e93Martin Schwidefsky mask = 0xffffffff; 71753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky#endif 7259da21398e680e8100625d689c8bebee6a139e93Martin Schwidefsky while (n-- > 0) 7359da21398e680e8100625d689c8bebee6a139e93Martin Schwidefsky if (i + n > 0) 7459da21398e680e8100625d689c8bebee6a139e93Martin Schwidefsky args[n] = regs->gprs[2 + i + n] & mask; 7559da21398e680e8100625d689c8bebee6a139e93Martin Schwidefsky if (i == 0) 7659da21398e680e8100625d689c8bebee6a139e93Martin Schwidefsky args[0] = regs->orig_gpr2 & mask; 77753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky} 78753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky 79753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefskystatic inline void syscall_set_arguments(struct task_struct *task, 80753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky struct pt_regs *regs, 81753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky unsigned int i, unsigned int n, 82753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky const unsigned long *args) 83753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky{ 84753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky BUG_ON(i + n > 6); 8559da21398e680e8100625d689c8bebee6a139e93Martin Schwidefsky while (n-- > 0) 8659da21398e680e8100625d689c8bebee6a139e93Martin Schwidefsky if (i + n > 0) 8759da21398e680e8100625d689c8bebee6a139e93Martin Schwidefsky regs->gprs[2 + i + n] = args[n]; 8859da21398e680e8100625d689c8bebee6a139e93Martin Schwidefsky if (i == 0) 8959da21398e680e8100625d689c8bebee6a139e93Martin Schwidefsky regs->orig_gpr2 = args[0]; 90753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky} 91753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky 925e937a9ae9137899c6641d718bd3820861099a09Eric Parisstatic inline int syscall_get_arch(void) 93c63cb468f373f479ff52b4a1b75f8ecdeaaf4f16Heiko Carstens{ 94c63cb468f373f479ff52b4a1b75f8ecdeaaf4f16Heiko Carstens#ifdef CONFIG_COMPAT 955e937a9ae9137899c6641d718bd3820861099a09Eric Paris if (test_tsk_thread_flag(current, TIF_31BIT)) 96c63cb468f373f479ff52b4a1b75f8ecdeaaf4f16Heiko Carstens return AUDIT_ARCH_S390; 97c63cb468f373f479ff52b4a1b75f8ecdeaaf4f16Heiko Carstens#endif 98c63cb468f373f479ff52b4a1b75f8ecdeaaf4f16Heiko Carstens return sizeof(long) == 8 ? AUDIT_ARCH_S390X : AUDIT_ARCH_S390; 99c63cb468f373f479ff52b4a1b75f8ecdeaaf4f16Heiko Carstens} 100753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1Martin Schwidefsky#endif /* _ASM_SYSCALL_H */ 101