0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef _ASM_X86_SYSCALL_H
0011 #define _ASM_X86_SYSCALL_H
0012
0013 #include <uapi/linux/audit.h>
0014 #include <linux/sched.h>
0015 #include <linux/err.h>
0016 #include <asm/thread_info.h> /* for TS_COMPAT */
0017 #include <asm/unistd.h>
0018
0019 typedef long (*sys_call_ptr_t)(const struct pt_regs *);
0020 extern const sys_call_ptr_t sys_call_table[];
0021
0022 #if defined(CONFIG_X86_32)
0023 #define ia32_sys_call_table sys_call_table
0024 #else
0025
0026
0027
0028
0029 extern const sys_call_ptr_t ia32_sys_call_table[];
0030 extern const sys_call_ptr_t x32_sys_call_table[];
0031 #endif
0032
0033
0034
0035
0036
0037
0038 static inline int syscall_get_nr(struct task_struct *task, struct pt_regs *regs)
0039 {
0040 return regs->orig_ax;
0041 }
0042
0043 static inline void syscall_rollback(struct task_struct *task,
0044 struct pt_regs *regs)
0045 {
0046 regs->ax = regs->orig_ax;
0047 }
0048
0049 static inline long syscall_get_error(struct task_struct *task,
0050 struct pt_regs *regs)
0051 {
0052 unsigned long error = regs->ax;
0053 #ifdef CONFIG_IA32_EMULATION
0054
0055
0056
0057
0058 if (task->thread_info.status & (TS_COMPAT|TS_I386_REGS_POKED))
0059
0060
0061
0062
0063 error = (long) (int) error;
0064 #endif
0065 return IS_ERR_VALUE(error) ? error : 0;
0066 }
0067
0068 static inline long syscall_get_return_value(struct task_struct *task,
0069 struct pt_regs *regs)
0070 {
0071 return regs->ax;
0072 }
0073
0074 static inline void syscall_set_return_value(struct task_struct *task,
0075 struct pt_regs *regs,
0076 int error, long val)
0077 {
0078 regs->ax = (long) error ?: val;
0079 }
0080
0081 #ifdef CONFIG_X86_32
0082
0083 static inline void syscall_get_arguments(struct task_struct *task,
0084 struct pt_regs *regs,
0085 unsigned long *args)
0086 {
0087 memcpy(args, ®s->bx, 6 * sizeof(args[0]));
0088 }
0089
0090 static inline int syscall_get_arch(struct task_struct *task)
0091 {
0092 return AUDIT_ARCH_I386;
0093 }
0094
0095 #else
0096
0097 static inline void syscall_get_arguments(struct task_struct *task,
0098 struct pt_regs *regs,
0099 unsigned long *args)
0100 {
0101 # ifdef CONFIG_IA32_EMULATION
0102 if (task->thread_info.status & TS_COMPAT) {
0103 *args++ = regs->bx;
0104 *args++ = regs->cx;
0105 *args++ = regs->dx;
0106 *args++ = regs->si;
0107 *args++ = regs->di;
0108 *args = regs->bp;
0109 } else
0110 # endif
0111 {
0112 *args++ = regs->di;
0113 *args++ = regs->si;
0114 *args++ = regs->dx;
0115 *args++ = regs->r10;
0116 *args++ = regs->r8;
0117 *args = regs->r9;
0118 }
0119 }
0120
0121 static inline int syscall_get_arch(struct task_struct *task)
0122 {
0123
0124 return (IS_ENABLED(CONFIG_IA32_EMULATION) &&
0125 task->thread_info.status & TS_COMPAT)
0126 ? AUDIT_ARCH_I386 : AUDIT_ARCH_X86_64;
0127 }
0128
0129 void do_syscall_64(struct pt_regs *regs, int nr);
0130 void do_int80_syscall_32(struct pt_regs *regs);
0131 long do_fast_syscall_32(struct pt_regs *regs);
0132
0133 #endif
0134
0135 #endif