1b8b572e1SStephen Rothwell /* 2b8b572e1SStephen Rothwell * Access to user system call parameters and results 3b8b572e1SStephen Rothwell * 4b8b572e1SStephen Rothwell * Copyright (C) 2008 Red Hat, Inc. All rights reserved. 5b8b572e1SStephen Rothwell * 6b8b572e1SStephen Rothwell * This copyrighted material is made available to anyone wishing to use, 7b8b572e1SStephen Rothwell * modify, copy, or redistribute it subject to the terms and conditions 8b8b572e1SStephen Rothwell * of the GNU General Public License v.2. 9b8b572e1SStephen Rothwell * 10b8b572e1SStephen Rothwell * See asm-generic/syscall.h for descriptions of what we must do here. 11b8b572e1SStephen Rothwell */ 12b8b572e1SStephen Rothwell 13b8b572e1SStephen Rothwell #ifndef _ASM_SYSCALL_H 14b8b572e1SStephen Rothwell #define _ASM_SYSCALL_H 1 15b8b572e1SStephen Rothwell 16ce5d1128SEric Paris #include <uapi/linux/audit.h> 17b8b572e1SStephen Rothwell #include <linux/sched.h> 1875dddcbdSEric Paris #include <linux/thread_info.h> 19b8b572e1SStephen Rothwell 2002424d89SIan Munsie /* ftrace syscalls requires exporting the sys_call_table */ 2102424d89SIan Munsie #ifdef CONFIG_FTRACE_SYSCALLS 221028ccf5SRomeo Cane extern const unsigned long sys_call_table[]; 2302424d89SIan Munsie #endif /* CONFIG_FTRACE_SYSCALLS */ 2402424d89SIan Munsie 25b8b572e1SStephen Rothwell static inline long syscall_get_nr(struct task_struct *task, 26b8b572e1SStephen Rothwell struct pt_regs *regs) 27b8b572e1SStephen Rothwell { 28b8b572e1SStephen Rothwell return TRAP(regs) == 0xc00 ? regs->gpr[0] : -1L; 29b8b572e1SStephen Rothwell } 30b8b572e1SStephen Rothwell 31b8b572e1SStephen Rothwell static inline void syscall_rollback(struct task_struct *task, 32b8b572e1SStephen Rothwell struct pt_regs *regs) 33b8b572e1SStephen Rothwell { 34b8b572e1SStephen Rothwell regs->gpr[3] = regs->orig_gpr3; 35b8b572e1SStephen Rothwell } 36b8b572e1SStephen Rothwell 37b8b572e1SStephen Rothwell static inline long syscall_get_return_value(struct task_struct *task, 38b8b572e1SStephen Rothwell struct pt_regs *regs) 39b8b572e1SStephen Rothwell { 40b8b572e1SStephen Rothwell return regs->gpr[3]; 41b8b572e1SStephen Rothwell } 42b8b572e1SStephen Rothwell 43b8b572e1SStephen Rothwell static inline void syscall_set_return_value(struct task_struct *task, 44b8b572e1SStephen Rothwell struct pt_regs *regs, 45b8b572e1SStephen Rothwell int error, long val) 46b8b572e1SStephen Rothwell { 471b1a3702SMichael Ellerman /* 481b1a3702SMichael Ellerman * In the general case it's not obvious that we must deal with CCR 491b1a3702SMichael Ellerman * here, as the syscall exit path will also do that for us. However 501b1a3702SMichael Ellerman * there are some places, eg. the signal code, which check ccr to 511b1a3702SMichael Ellerman * decide if the value in r3 is actually an error. 521b1a3702SMichael Ellerman */ 53b8b572e1SStephen Rothwell if (error) { 54409d241bSNathan Lynch regs->ccr |= 0x10000000L; 551b1a3702SMichael Ellerman regs->gpr[3] = error; 56b8b572e1SStephen Rothwell } else { 57409d241bSNathan Lynch regs->ccr &= ~0x10000000L; 58b8b572e1SStephen Rothwell regs->gpr[3] = val; 59b8b572e1SStephen Rothwell } 60b8b572e1SStephen Rothwell } 61b8b572e1SStephen Rothwell 62b8b572e1SStephen Rothwell static inline void syscall_get_arguments(struct task_struct *task, 63b8b572e1SStephen Rothwell struct pt_regs *regs, 64b8b572e1SStephen Rothwell unsigned int i, unsigned int n, 65b8b572e1SStephen Rothwell unsigned long *args) 66b8b572e1SStephen Rothwell { 67a7657844SMichael Ellerman unsigned long mask = -1UL; 68a7657844SMichael Ellerman 69b8b572e1SStephen Rothwell BUG_ON(i + n > 6); 70a7657844SMichael Ellerman 71a7657844SMichael Ellerman #ifdef CONFIG_COMPAT 72a7657844SMichael Ellerman if (test_tsk_thread_flag(task, TIF_32BIT)) 73a7657844SMichael Ellerman mask = 0xffffffff; 74b8b572e1SStephen Rothwell #endif 75a7657844SMichael Ellerman while (n--) 76a7657844SMichael Ellerman args[n] = regs->gpr[3 + i + n] & mask; 77b8b572e1SStephen Rothwell } 78b8b572e1SStephen Rothwell 79b8b572e1SStephen Rothwell static inline void syscall_set_arguments(struct task_struct *task, 80b8b572e1SStephen Rothwell struct pt_regs *regs, 81b8b572e1SStephen Rothwell unsigned int i, unsigned int n, 82b8b572e1SStephen Rothwell const unsigned long *args) 83b8b572e1SStephen Rothwell { 84b8b572e1SStephen Rothwell BUG_ON(i + n > 6); 85b8b572e1SStephen Rothwell memcpy(®s->gpr[3 + i], args, n * sizeof(args[0])); 86b8b572e1SStephen Rothwell } 87b8b572e1SStephen Rothwell 88ce5d1128SEric Paris static inline int syscall_get_arch(void) 89ce5d1128SEric Paris { 9063f13448SRichard Guy Briggs int arch = is_32bit_task() ? AUDIT_ARCH_PPC : AUDIT_ARCH_PPC64; 9163f13448SRichard Guy Briggs #ifdef __LITTLE_ENDIAN__ 9263f13448SRichard Guy Briggs arch |= __AUDIT_ARCH_LE; 9363f13448SRichard Guy Briggs #endif 9463f13448SRichard Guy Briggs return arch; 95ce5d1128SEric Paris } 96b8b572e1SStephen Rothwell #endif /* _ASM_SYSCALL_H */ 97