11965aae3SH. Peter Anvin #ifndef _ASM_X86_COMPAT_H 21965aae3SH. Peter Anvin #define _ASM_X86_COMPAT_H 3bb898558SAl Viro 4bb898558SAl Viro /* 5bb898558SAl Viro * Architecture specific compatibility types 6bb898558SAl Viro */ 7bb898558SAl Viro #include <linux/types.h> 8bb898558SAl Viro #include <linux/sched.h> 9d375cf15SAndy Lutomirski #include <linux/sched/task_stack.h> 10d1a797f3SH. Peter Anvin #include <asm/processor.h> 11bb898558SAl Viro #include <asm/user32.h> 12fca460f9SH. Peter Anvin #include <asm/unistd.h> 13bb898558SAl Viro 14bb898558SAl Viro #define COMPAT_USER_HZ 100 15e28cbf22SChristoph Hellwig #define COMPAT_UTS_MACHINE "i686\0\0" 16bb898558SAl Viro 17bb898558SAl Viro typedef u32 compat_size_t; 18bb898558SAl Viro typedef s32 compat_ssize_t; 19bb898558SAl Viro typedef s32 compat_time_t; 20bb898558SAl Viro typedef s32 compat_clock_t; 21bb898558SAl Viro typedef s32 compat_pid_t; 22bb898558SAl Viro typedef u16 __compat_uid_t; 23bb898558SAl Viro typedef u16 __compat_gid_t; 24bb898558SAl Viro typedef u32 __compat_uid32_t; 25bb898558SAl Viro typedef u32 __compat_gid32_t; 26bb898558SAl Viro typedef u16 compat_mode_t; 27bb898558SAl Viro typedef u32 compat_ino_t; 28bb898558SAl Viro typedef u16 compat_dev_t; 29bb898558SAl Viro typedef s32 compat_off_t; 30bb898558SAl Viro typedef s64 compat_loff_t; 31bb898558SAl Viro typedef u16 compat_nlink_t; 32bb898558SAl Viro typedef u16 compat_ipc_pid_t; 33bb898558SAl Viro typedef s32 compat_daddr_t; 34bb898558SAl Viro typedef u32 compat_caddr_t; 35bb898558SAl Viro typedef __kernel_fsid_t compat_fsid_t; 36bb898558SAl Viro typedef s32 compat_timer_t; 37bb898558SAl Viro typedef s32 compat_key_t; 38bb898558SAl Viro 39bb898558SAl Viro typedef s32 compat_int_t; 40bb898558SAl Viro typedef s32 compat_long_t; 41bb898558SAl Viro typedef s64 __attribute__((aligned(4))) compat_s64; 42bb898558SAl Viro typedef u32 compat_uint_t; 43bb898558SAl Viro typedef u32 compat_ulong_t; 44a4455082SDave Hansen typedef u32 compat_u32; 45bb898558SAl Viro typedef u64 __attribute__((aligned(4))) compat_u64; 46751f409dSDenys Vlasenko typedef u32 compat_uptr_t; 47bb898558SAl Viro 48bb898558SAl Viro struct compat_timespec { 49bb898558SAl Viro compat_time_t tv_sec; 50bb898558SAl Viro s32 tv_nsec; 51bb898558SAl Viro }; 52bb898558SAl Viro 53bb898558SAl Viro struct compat_timeval { 54bb898558SAl Viro compat_time_t tv_sec; 55bb898558SAl Viro s32 tv_usec; 56bb898558SAl Viro }; 57bb898558SAl Viro 58bb898558SAl Viro struct compat_stat { 59bb898558SAl Viro compat_dev_t st_dev; 60bb898558SAl Viro u16 __pad1; 61bb898558SAl Viro compat_ino_t st_ino; 62bb898558SAl Viro compat_mode_t st_mode; 63bb898558SAl Viro compat_nlink_t st_nlink; 64bb898558SAl Viro __compat_uid_t st_uid; 65bb898558SAl Viro __compat_gid_t st_gid; 66bb898558SAl Viro compat_dev_t st_rdev; 67bb898558SAl Viro u16 __pad2; 68bb898558SAl Viro u32 st_size; 69bb898558SAl Viro u32 st_blksize; 70bb898558SAl Viro u32 st_blocks; 71bb898558SAl Viro u32 st_atime; 72bb898558SAl Viro u32 st_atime_nsec; 73bb898558SAl Viro u32 st_mtime; 74bb898558SAl Viro u32 st_mtime_nsec; 75bb898558SAl Viro u32 st_ctime; 76bb898558SAl Viro u32 st_ctime_nsec; 77bb898558SAl Viro u32 __unused4; 78bb898558SAl Viro u32 __unused5; 79bb898558SAl Viro }; 80bb898558SAl Viro 81bb898558SAl Viro struct compat_flock { 82bb898558SAl Viro short l_type; 83bb898558SAl Viro short l_whence; 84bb898558SAl Viro compat_off_t l_start; 85bb898558SAl Viro compat_off_t l_len; 86bb898558SAl Viro compat_pid_t l_pid; 87bb898558SAl Viro }; 88bb898558SAl Viro 89bb898558SAl Viro #define F_GETLK64 12 /* using 'struct flock64' */ 90bb898558SAl Viro #define F_SETLK64 13 91bb898558SAl Viro #define F_SETLKW64 14 92bb898558SAl Viro 93bb898558SAl Viro /* 94bb898558SAl Viro * IA32 uses 4 byte alignment for 64 bit quantities, 95bb898558SAl Viro * so we need to pack this structure. 96bb898558SAl Viro */ 97bb898558SAl Viro struct compat_flock64 { 98bb898558SAl Viro short l_type; 99bb898558SAl Viro short l_whence; 100bb898558SAl Viro compat_loff_t l_start; 101bb898558SAl Viro compat_loff_t l_len; 102bb898558SAl Viro compat_pid_t l_pid; 103bb898558SAl Viro } __attribute__((packed)); 104bb898558SAl Viro 105bb898558SAl Viro struct compat_statfs { 106bb898558SAl Viro int f_type; 107bb898558SAl Viro int f_bsize; 108bb898558SAl Viro int f_blocks; 109bb898558SAl Viro int f_bfree; 110bb898558SAl Viro int f_bavail; 111bb898558SAl Viro int f_files; 112bb898558SAl Viro int f_ffree; 113bb898558SAl Viro compat_fsid_t f_fsid; 114bb898558SAl Viro int f_namelen; /* SunOS ignores this field. */ 115bb898558SAl Viro int f_frsize; 1161448c721SEric W. Biederman int f_flags; 1171448c721SEric W. Biederman int f_spare[4]; 118bb898558SAl Viro }; 119bb898558SAl Viro 120bb898558SAl Viro #define COMPAT_RLIM_INFINITY 0xffffffff 121bb898558SAl Viro 122bb898558SAl Viro typedef u32 compat_old_sigset_t; /* at least 32 bits */ 123bb898558SAl Viro 124bb898558SAl Viro #define _COMPAT_NSIG 64 125bb898558SAl Viro #define _COMPAT_NSIG_BPW 32 126bb898558SAl Viro 127bb898558SAl Viro typedef u32 compat_sigset_word; 128bb898558SAl Viro 129751f409dSDenys Vlasenko typedef union compat_sigval { 130751f409dSDenys Vlasenko compat_int_t sival_int; 131751f409dSDenys Vlasenko compat_uptr_t sival_ptr; 132751f409dSDenys Vlasenko } compat_sigval_t; 133751f409dSDenys Vlasenko 134751f409dSDenys Vlasenko typedef struct compat_siginfo { 135751f409dSDenys Vlasenko int si_signo; 136751f409dSDenys Vlasenko int si_errno; 137751f409dSDenys Vlasenko int si_code; 138751f409dSDenys Vlasenko 139751f409dSDenys Vlasenko union { 140751f409dSDenys Vlasenko int _pad[128/sizeof(int) - 3]; 141751f409dSDenys Vlasenko 142751f409dSDenys Vlasenko /* kill() */ 143751f409dSDenys Vlasenko struct { 144751f409dSDenys Vlasenko unsigned int _pid; /* sender's pid */ 145751f409dSDenys Vlasenko unsigned int _uid; /* sender's uid */ 146751f409dSDenys Vlasenko } _kill; 147751f409dSDenys Vlasenko 148751f409dSDenys Vlasenko /* POSIX.1b timers */ 149751f409dSDenys Vlasenko struct { 150751f409dSDenys Vlasenko compat_timer_t _tid; /* timer id */ 151751f409dSDenys Vlasenko int _overrun; /* overrun count */ 152751f409dSDenys Vlasenko compat_sigval_t _sigval; /* same as below */ 153751f409dSDenys Vlasenko int _sys_private; /* not to be passed to user */ 154751f409dSDenys Vlasenko int _overrun_incr; /* amount to add to overrun */ 155751f409dSDenys Vlasenko } _timer; 156751f409dSDenys Vlasenko 157751f409dSDenys Vlasenko /* POSIX.1b signals */ 158751f409dSDenys Vlasenko struct { 159751f409dSDenys Vlasenko unsigned int _pid; /* sender's pid */ 160751f409dSDenys Vlasenko unsigned int _uid; /* sender's uid */ 161751f409dSDenys Vlasenko compat_sigval_t _sigval; 162751f409dSDenys Vlasenko } _rt; 163751f409dSDenys Vlasenko 164751f409dSDenys Vlasenko /* SIGCHLD */ 165751f409dSDenys Vlasenko struct { 166751f409dSDenys Vlasenko unsigned int _pid; /* which child */ 167751f409dSDenys Vlasenko unsigned int _uid; /* sender's uid */ 168751f409dSDenys Vlasenko int _status; /* exit code */ 169751f409dSDenys Vlasenko compat_clock_t _utime; 170751f409dSDenys Vlasenko compat_clock_t _stime; 171751f409dSDenys Vlasenko } _sigchld; 172751f409dSDenys Vlasenko 173751f409dSDenys Vlasenko /* SIGCHLD (x32 version) */ 174751f409dSDenys Vlasenko struct { 175751f409dSDenys Vlasenko unsigned int _pid; /* which child */ 176751f409dSDenys Vlasenko unsigned int _uid; /* sender's uid */ 177751f409dSDenys Vlasenko int _status; /* exit code */ 178751f409dSDenys Vlasenko compat_s64 _utime; 179751f409dSDenys Vlasenko compat_s64 _stime; 180751f409dSDenys Vlasenko } _sigchld_x32; 181751f409dSDenys Vlasenko 182751f409dSDenys Vlasenko /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ 183751f409dSDenys Vlasenko struct { 184751f409dSDenys Vlasenko unsigned int _addr; /* faulting insn/memory ref. */ 185a4455082SDave Hansen short int _addr_lsb; /* Valid LSB of the reported address. */ 186a4455082SDave Hansen union { 187a4455082SDave Hansen /* used when si_code=SEGV_BNDERR */ 188a4455082SDave Hansen struct { 189a4455082SDave Hansen compat_uptr_t _lower; 190a4455082SDave Hansen compat_uptr_t _upper; 191a4455082SDave Hansen } _addr_bnd; 192a4455082SDave Hansen /* used when si_code=SEGV_PKUERR */ 193a4455082SDave Hansen compat_u32 _pkey; 194a4455082SDave Hansen }; 195751f409dSDenys Vlasenko } _sigfault; 196751f409dSDenys Vlasenko 197751f409dSDenys Vlasenko /* SIGPOLL */ 198751f409dSDenys Vlasenko struct { 199751f409dSDenys Vlasenko int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ 200751f409dSDenys Vlasenko int _fd; 201751f409dSDenys Vlasenko } _sigpoll; 202751f409dSDenys Vlasenko 203751f409dSDenys Vlasenko struct { 204751f409dSDenys Vlasenko unsigned int _call_addr; /* calling insn */ 205751f409dSDenys Vlasenko int _syscall; /* triggering system call number */ 206751f409dSDenys Vlasenko unsigned int _arch; /* AUDIT_ARCH_* of syscall */ 207751f409dSDenys Vlasenko } _sigsys; 208751f409dSDenys Vlasenko } _sifields; 209751f409dSDenys Vlasenko } compat_siginfo_t; 210751f409dSDenys Vlasenko 211bb898558SAl Viro #define COMPAT_OFF_T_MAX 0x7fffffff 212bb898558SAl Viro #define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL 213bb898558SAl Viro 214bb898558SAl Viro struct compat_ipc64_perm { 215bb898558SAl Viro compat_key_t key; 216bb898558SAl Viro __compat_uid32_t uid; 217bb898558SAl Viro __compat_gid32_t gid; 218bb898558SAl Viro __compat_uid32_t cuid; 219bb898558SAl Viro __compat_gid32_t cgid; 220bb898558SAl Viro unsigned short mode; 221bb898558SAl Viro unsigned short __pad1; 222bb898558SAl Viro unsigned short seq; 223bb898558SAl Viro unsigned short __pad2; 224bb898558SAl Viro compat_ulong_t unused1; 225bb898558SAl Viro compat_ulong_t unused2; 226bb898558SAl Viro }; 227bb898558SAl Viro 228bb898558SAl Viro struct compat_semid64_ds { 229bb898558SAl Viro struct compat_ipc64_perm sem_perm; 230bb898558SAl Viro compat_time_t sem_otime; 231bb898558SAl Viro compat_ulong_t __unused1; 232bb898558SAl Viro compat_time_t sem_ctime; 233bb898558SAl Viro compat_ulong_t __unused2; 234bb898558SAl Viro compat_ulong_t sem_nsems; 235bb898558SAl Viro compat_ulong_t __unused3; 236bb898558SAl Viro compat_ulong_t __unused4; 237bb898558SAl Viro }; 238bb898558SAl Viro 239bb898558SAl Viro struct compat_msqid64_ds { 240bb898558SAl Viro struct compat_ipc64_perm msg_perm; 241bb898558SAl Viro compat_time_t msg_stime; 242bb898558SAl Viro compat_ulong_t __unused1; 243bb898558SAl Viro compat_time_t msg_rtime; 244bb898558SAl Viro compat_ulong_t __unused2; 245bb898558SAl Viro compat_time_t msg_ctime; 246bb898558SAl Viro compat_ulong_t __unused3; 247bb898558SAl Viro compat_ulong_t msg_cbytes; 248bb898558SAl Viro compat_ulong_t msg_qnum; 249bb898558SAl Viro compat_ulong_t msg_qbytes; 250bb898558SAl Viro compat_pid_t msg_lspid; 251bb898558SAl Viro compat_pid_t msg_lrpid; 252bb898558SAl Viro compat_ulong_t __unused4; 253bb898558SAl Viro compat_ulong_t __unused5; 254bb898558SAl Viro }; 255bb898558SAl Viro 256bb898558SAl Viro struct compat_shmid64_ds { 257bb898558SAl Viro struct compat_ipc64_perm shm_perm; 258bb898558SAl Viro compat_size_t shm_segsz; 259bb898558SAl Viro compat_time_t shm_atime; 260bb898558SAl Viro compat_ulong_t __unused1; 261bb898558SAl Viro compat_time_t shm_dtime; 262bb898558SAl Viro compat_ulong_t __unused2; 263bb898558SAl Viro compat_time_t shm_ctime; 264bb898558SAl Viro compat_ulong_t __unused3; 265bb898558SAl Viro compat_pid_t shm_cpid; 266bb898558SAl Viro compat_pid_t shm_lpid; 267bb898558SAl Viro compat_ulong_t shm_nattch; 268bb898558SAl Viro compat_ulong_t __unused4; 269bb898558SAl Viro compat_ulong_t __unused5; 270bb898558SAl Viro }; 271bb898558SAl Viro 272bb898558SAl Viro /* 273bb898558SAl Viro * The type of struct elf_prstatus.pr_reg in compatible core dumps. 274bb898558SAl Viro */ 275d1a797f3SH. Peter Anvin typedef struct user_regs_struct compat_elf_gregset_t; 276d1a797f3SH. Peter Anvin 27790954e7bSDmitry Safonov /* Full regset -- prstatus on x32, otherwise on ia32 */ 27890954e7bSDmitry Safonov #define PRSTATUS_SIZE(S, R) (R != sizeof(S.pr_reg) ? 144 : 296) 27990954e7bSDmitry Safonov #define SET_PR_FPVALID(S, V, R) \ 28090954e7bSDmitry Safonov do { *(int *) (((void *) &((S)->pr_reg)) + R) = (V); } \ 281d1a797f3SH. Peter Anvin while (0) 282d1a797f3SH. Peter Anvin 2837b2dd368SDmitry Safonov #ifdef CONFIG_X86_X32_ABI 284d1a797f3SH. Peter Anvin #define COMPAT_USE_64BIT_TIME \ 285d1a797f3SH. Peter Anvin (!!(task_pt_regs(current)->orig_ax & __X32_SYSCALL_BIT)) 286d1a797f3SH. Peter Anvin #endif 287bb898558SAl Viro 288bb898558SAl Viro /* 289bb898558SAl Viro * A pointer passed in from user mode. This should not 290bb898558SAl Viro * be used for syscall parameters, just declare them 291bb898558SAl Viro * as pointers because the syscall entry code will have 292bb898558SAl Viro * appropriately converted them already. 293bb898558SAl Viro */ 294bb898558SAl Viro 295bb898558SAl Viro static inline void __user *compat_ptr(compat_uptr_t uptr) 296bb898558SAl Viro { 297bb898558SAl Viro return (void __user *)(unsigned long)uptr; 298bb898558SAl Viro } 299bb898558SAl Viro 300bb898558SAl Viro static inline compat_uptr_t ptr_to_compat(void __user *uptr) 301bb898558SAl Viro { 302bb898558SAl Viro return (u32)(unsigned long)uptr; 303bb898558SAl Viro } 304bb898558SAl Viro 305c41d68a5SH. Peter Anvin static inline void __user *arch_compat_alloc_user_space(long len) 306bb898558SAl Viro { 307d1a797f3SH. Peter Anvin compat_uptr_t sp; 308d1a797f3SH. Peter Anvin 309d1a797f3SH. Peter Anvin if (test_thread_flag(TIF_IA32)) { 310d1a797f3SH. Peter Anvin sp = task_pt_regs(current)->sp; 311d1a797f3SH. Peter Anvin } else { 312d1a797f3SH. Peter Anvin /* -128 for the x32 ABI redzone */ 313263042e4SDenys Vlasenko sp = task_pt_regs(current)->sp - 128; 314d1a797f3SH. Peter Anvin } 315d1a797f3SH. Peter Anvin 316d1a797f3SH. Peter Anvin return (void __user *)round_down(sp - len, 16); 317bb898558SAl Viro } 318bb898558SAl Viro 319abfb9498SDmitry Safonov static inline bool in_x32_syscall(void) 320a628b684SH. Peter Anvin { 321fca460f9SH. Peter Anvin #ifdef CONFIG_X86_X32_ABI 322fca460f9SH. Peter Anvin if (task_pt_regs(current)->orig_ax & __X32_SYSCALL_BIT) 323fca460f9SH. Peter Anvin return true; 324fca460f9SH. Peter Anvin #endif 325fca460f9SH. Peter Anvin return false; 326bb898558SAl Viro } 327bb898558SAl Viro 328f970165bSAndy Lutomirski static inline bool in_compat_syscall(void) 329a628b684SH. Peter Anvin { 330abfb9498SDmitry Safonov return in_ia32_syscall() || in_x32_syscall(); 331a628b684SH. Peter Anvin } 332f970165bSAndy Lutomirski #define in_compat_syscall in_compat_syscall /* override the generic impl */ 333a628b684SH. Peter Anvin 3341965aae3SH. Peter Anvin #endif /* _ASM_X86_COMPAT_H */ 335