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_error(struct task_struct *task, 38b8b572e1SStephen Rothwell struct pt_regs *regs) 39b8b572e1SStephen Rothwell { 40409d241bSNathan Lynch return (regs->ccr & 0x10000000) ? -regs->gpr[3] : 0; 41b8b572e1SStephen Rothwell } 42b8b572e1SStephen Rothwell 43b8b572e1SStephen Rothwell static inline long syscall_get_return_value(struct task_struct *task, 44b8b572e1SStephen Rothwell struct pt_regs *regs) 45b8b572e1SStephen Rothwell { 46b8b572e1SStephen Rothwell return regs->gpr[3]; 47b8b572e1SStephen Rothwell } 48b8b572e1SStephen Rothwell 49b8b572e1SStephen Rothwell static inline void syscall_set_return_value(struct task_struct *task, 50b8b572e1SStephen Rothwell struct pt_regs *regs, 51b8b572e1SStephen Rothwell int error, long val) 52b8b572e1SStephen Rothwell { 53b8b572e1SStephen Rothwell if (error) { 54409d241bSNathan Lynch regs->ccr |= 0x10000000L; 55b8b572e1SStephen Rothwell 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 { 67b8b572e1SStephen Rothwell BUG_ON(i + n > 6); 68b8b572e1SStephen Rothwell #ifdef CONFIG_PPC64 69b8b572e1SStephen Rothwell if (test_tsk_thread_flag(task, TIF_32BIT)) { 70b8b572e1SStephen Rothwell /* 71b8b572e1SStephen Rothwell * Zero-extend 32-bit argument values. The high bits are 72b8b572e1SStephen Rothwell * garbage ignored by the actual syscall dispatch. 73b8b572e1SStephen Rothwell */ 74b8b572e1SStephen Rothwell while (n-- > 0) 75b8b572e1SStephen Rothwell args[n] = (u32) regs->gpr[3 + i + n]; 76b8b572e1SStephen Rothwell return; 77b8b572e1SStephen Rothwell } 78b8b572e1SStephen Rothwell #endif 79b8b572e1SStephen Rothwell memcpy(args, ®s->gpr[3 + i], n * sizeof(args[0])); 80b8b572e1SStephen Rothwell } 81b8b572e1SStephen Rothwell 82b8b572e1SStephen Rothwell static inline void syscall_set_arguments(struct task_struct *task, 83b8b572e1SStephen Rothwell struct pt_regs *regs, 84b8b572e1SStephen Rothwell unsigned int i, unsigned int n, 85b8b572e1SStephen Rothwell const unsigned long *args) 86b8b572e1SStephen Rothwell { 87b8b572e1SStephen Rothwell BUG_ON(i + n > 6); 88b8b572e1SStephen Rothwell memcpy(®s->gpr[3 + i], args, n * sizeof(args[0])); 89b8b572e1SStephen Rothwell } 90b8b572e1SStephen Rothwell 91ce5d1128SEric Paris static inline int syscall_get_arch(void) 92ce5d1128SEric Paris { 9363f13448SRichard Guy Briggs int arch = is_32bit_task() ? AUDIT_ARCH_PPC : AUDIT_ARCH_PPC64; 9463f13448SRichard Guy Briggs #ifdef __LITTLE_ENDIAN__ 9563f13448SRichard Guy Briggs arch |= __AUDIT_ARCH_LE; 9663f13448SRichard Guy Briggs #endif 9763f13448SRichard Guy Briggs return arch; 98ce5d1128SEric Paris } 99b8b572e1SStephen Rothwell #endif /* _ASM_SYSCALL_H */ 100