File Index
Files and directories
Sign in
FILE

syscall.h

File preview with syntax highlighting.

linux-6.19.14/arch/arm/include/asm/syscall.h C
  1/* SPDX-License-Identifier: GPL-2.0 */
  2/*
  3 * Access to user system call parameters and results
  4 *
  5 * See asm-generic/syscall.h for descriptions of what we must do here.
  6 */
  7
  8#ifndef _ASM_ARM_SYSCALL_H
  9#define _ASM_ARM_SYSCALL_H
 10
 11#include <uapi/linux/audit.h> /* for AUDIT_ARCH_* */
 12#include <linux/elf.h> /* for ELF_EM */
 13#include <linux/err.h>
 14#include <linux/sched.h>
 15
 16#include <asm/unistd.h>
 17
 18#define NR_syscalls (__NR_syscalls)
 19
 20extern const unsigned long sys_call_table[];
 21
 22static inline int syscall_get_nr(struct task_struct *task,
 23				 struct pt_regs *regs)
 24{
 25	if (IS_ENABLED(CONFIG_AEABI) && !IS_ENABLED(CONFIG_OABI_COMPAT))
 26		return task_thread_info(task)->abi_syscall;
 27
 28	if (task_thread_info(task)->abi_syscall == -1)
 29		return -1;
 30
 31	return task_thread_info(task)->abi_syscall & __NR_SYSCALL_MASK;
 32}
 33
 34static inline bool __in_oabi_syscall(struct task_struct *task)
 35{
 36	return IS_ENABLED(CONFIG_OABI_COMPAT) &&
 37		(task_thread_info(task)->abi_syscall & __NR_OABI_SYSCALL_BASE);
 38}
 39
 40static inline bool in_oabi_syscall(void)
 41{
 42	return __in_oabi_syscall(current);
 43}
 44
 45static inline void syscall_rollback(struct task_struct *task,
 46				    struct pt_regs *regs)
 47{
 48	regs->ARM_r0 = regs->ARM_ORIG_r0;
 49}
 50
 51static inline long syscall_get_error(struct task_struct *task,
 52				     struct pt_regs *regs)
 53{
 54	unsigned long error = regs->ARM_r0;
 55	return IS_ERR_VALUE(error) ? error : 0;
 56}
 57
 58static inline long syscall_get_return_value(struct task_struct *task,
 59					    struct pt_regs *regs)
 60{
 61	return regs->ARM_r0;
 62}
 63
 64static inline void syscall_set_return_value(struct task_struct *task,
 65					    struct pt_regs *regs,
 66					    int error, long val)
 67{
 68	regs->ARM_r0 = (long) error ? error : val;
 69}
 70
 71static inline void syscall_set_nr(struct task_struct *task,
 72				  struct pt_regs *regs,
 73				  int nr)
 74{
 75	if (nr == -1) {
 76		task_thread_info(task)->abi_syscall = -1;
 77		/*
 78		 * When the syscall number is set to -1, the syscall will be
 79		 * skipped.  In this case the syscall return value has to be
 80		 * set explicitly, otherwise the first syscall argument is
 81		 * returned as the syscall return value.
 82		 */
 83		syscall_set_return_value(task, regs, -ENOSYS, 0);
 84		return;
 85	}
 86	if ((IS_ENABLED(CONFIG_AEABI) && !IS_ENABLED(CONFIG_OABI_COMPAT))) {
 87		task_thread_info(task)->abi_syscall = nr;
 88		return;
 89	}
 90	task_thread_info(task)->abi_syscall =
 91		(task_thread_info(task)->abi_syscall & ~__NR_SYSCALL_MASK) |
 92		(nr & __NR_SYSCALL_MASK);
 93}
 94
 95#define SYSCALL_MAX_ARGS 7
 96
 97static inline void syscall_get_arguments(struct task_struct *task,
 98					 struct pt_regs *regs,
 99					 unsigned long *args)
100{
101	args[0] = regs->ARM_ORIG_r0;
102	args++;
103
104	memcpy(args, &regs->ARM_r0 + 1, 5 * sizeof(args[0]));
105}
106
107static inline void syscall_set_arguments(struct task_struct *task,
108					 struct pt_regs *regs,
109					 const unsigned long *args)
110{
111	memcpy(&regs->ARM_r0, args, 6 * sizeof(args[0]));
112	/*
113	 * Also copy the first argument into ARM_ORIG_r0
114	 * so that syscall_get_arguments() would return it
115	 * instead of the previous value.
116	 */
117	regs->ARM_ORIG_r0 = regs->ARM_r0;
118}
119
120static inline int syscall_get_arch(struct task_struct *task)
121{
122	/* ARM tasks don't change audit architectures on the fly. */
123	return AUDIT_ARCH_ARM;
124}
125
126#endif /* _ASM_ARM_SYSCALL_H */
~/ Read-only file preview.