1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */ 2*4882a593Smuzhiyun #ifndef _ASM_X86_COMPAT_H 3*4882a593Smuzhiyun #define _ASM_X86_COMPAT_H 4*4882a593Smuzhiyun 5*4882a593Smuzhiyun /* 6*4882a593Smuzhiyun * Architecture specific compatibility types 7*4882a593Smuzhiyun */ 8*4882a593Smuzhiyun #include <linux/types.h> 9*4882a593Smuzhiyun #include <linux/sched.h> 10*4882a593Smuzhiyun #include <linux/sched/task_stack.h> 11*4882a593Smuzhiyun #include <asm/processor.h> 12*4882a593Smuzhiyun #include <asm/user32.h> 13*4882a593Smuzhiyun #include <asm/unistd.h> 14*4882a593Smuzhiyun 15*4882a593Smuzhiyun #include <asm-generic/compat.h> 16*4882a593Smuzhiyun 17*4882a593Smuzhiyun #define COMPAT_USER_HZ 100 18*4882a593Smuzhiyun #define COMPAT_UTS_MACHINE "i686\0\0" 19*4882a593Smuzhiyun 20*4882a593Smuzhiyun typedef u16 __compat_uid_t; 21*4882a593Smuzhiyun typedef u16 __compat_gid_t; 22*4882a593Smuzhiyun typedef u32 __compat_uid32_t; 23*4882a593Smuzhiyun typedef u32 __compat_gid32_t; 24*4882a593Smuzhiyun typedef u16 compat_mode_t; 25*4882a593Smuzhiyun typedef u16 compat_dev_t; 26*4882a593Smuzhiyun typedef u16 compat_nlink_t; 27*4882a593Smuzhiyun typedef u16 compat_ipc_pid_t; 28*4882a593Smuzhiyun typedef u32 compat_caddr_t; 29*4882a593Smuzhiyun typedef __kernel_fsid_t compat_fsid_t; 30*4882a593Smuzhiyun 31*4882a593Smuzhiyun struct compat_stat { 32*4882a593Smuzhiyun u32 st_dev; 33*4882a593Smuzhiyun compat_ino_t st_ino; 34*4882a593Smuzhiyun compat_mode_t st_mode; 35*4882a593Smuzhiyun compat_nlink_t st_nlink; 36*4882a593Smuzhiyun __compat_uid_t st_uid; 37*4882a593Smuzhiyun __compat_gid_t st_gid; 38*4882a593Smuzhiyun u32 st_rdev; 39*4882a593Smuzhiyun u32 st_size; 40*4882a593Smuzhiyun u32 st_blksize; 41*4882a593Smuzhiyun u32 st_blocks; 42*4882a593Smuzhiyun u32 st_atime; 43*4882a593Smuzhiyun u32 st_atime_nsec; 44*4882a593Smuzhiyun u32 st_mtime; 45*4882a593Smuzhiyun u32 st_mtime_nsec; 46*4882a593Smuzhiyun u32 st_ctime; 47*4882a593Smuzhiyun u32 st_ctime_nsec; 48*4882a593Smuzhiyun u32 __unused4; 49*4882a593Smuzhiyun u32 __unused5; 50*4882a593Smuzhiyun }; 51*4882a593Smuzhiyun 52*4882a593Smuzhiyun struct compat_flock { 53*4882a593Smuzhiyun short l_type; 54*4882a593Smuzhiyun short l_whence; 55*4882a593Smuzhiyun compat_off_t l_start; 56*4882a593Smuzhiyun compat_off_t l_len; 57*4882a593Smuzhiyun compat_pid_t l_pid; 58*4882a593Smuzhiyun }; 59*4882a593Smuzhiyun 60*4882a593Smuzhiyun #define F_GETLK64 12 /* using 'struct flock64' */ 61*4882a593Smuzhiyun #define F_SETLK64 13 62*4882a593Smuzhiyun #define F_SETLKW64 14 63*4882a593Smuzhiyun 64*4882a593Smuzhiyun /* 65*4882a593Smuzhiyun * IA32 uses 4 byte alignment for 64 bit quantities, 66*4882a593Smuzhiyun * so we need to pack this structure. 67*4882a593Smuzhiyun */ 68*4882a593Smuzhiyun struct compat_flock64 { 69*4882a593Smuzhiyun short l_type; 70*4882a593Smuzhiyun short l_whence; 71*4882a593Smuzhiyun compat_loff_t l_start; 72*4882a593Smuzhiyun compat_loff_t l_len; 73*4882a593Smuzhiyun compat_pid_t l_pid; 74*4882a593Smuzhiyun } __attribute__((packed)); 75*4882a593Smuzhiyun 76*4882a593Smuzhiyun struct compat_statfs { 77*4882a593Smuzhiyun int f_type; 78*4882a593Smuzhiyun int f_bsize; 79*4882a593Smuzhiyun int f_blocks; 80*4882a593Smuzhiyun int f_bfree; 81*4882a593Smuzhiyun int f_bavail; 82*4882a593Smuzhiyun int f_files; 83*4882a593Smuzhiyun int f_ffree; 84*4882a593Smuzhiyun compat_fsid_t f_fsid; 85*4882a593Smuzhiyun int f_namelen; /* SunOS ignores this field. */ 86*4882a593Smuzhiyun int f_frsize; 87*4882a593Smuzhiyun int f_flags; 88*4882a593Smuzhiyun int f_spare[4]; 89*4882a593Smuzhiyun }; 90*4882a593Smuzhiyun 91*4882a593Smuzhiyun #define COMPAT_RLIM_INFINITY 0xffffffff 92*4882a593Smuzhiyun 93*4882a593Smuzhiyun typedef u32 compat_old_sigset_t; /* at least 32 bits */ 94*4882a593Smuzhiyun 95*4882a593Smuzhiyun #define _COMPAT_NSIG 64 96*4882a593Smuzhiyun #define _COMPAT_NSIG_BPW 32 97*4882a593Smuzhiyun 98*4882a593Smuzhiyun typedef u32 compat_sigset_word; 99*4882a593Smuzhiyun 100*4882a593Smuzhiyun #define COMPAT_OFF_T_MAX 0x7fffffff 101*4882a593Smuzhiyun 102*4882a593Smuzhiyun struct compat_ipc64_perm { 103*4882a593Smuzhiyun compat_key_t key; 104*4882a593Smuzhiyun __compat_uid32_t uid; 105*4882a593Smuzhiyun __compat_gid32_t gid; 106*4882a593Smuzhiyun __compat_uid32_t cuid; 107*4882a593Smuzhiyun __compat_gid32_t cgid; 108*4882a593Smuzhiyun unsigned short mode; 109*4882a593Smuzhiyun unsigned short __pad1; 110*4882a593Smuzhiyun unsigned short seq; 111*4882a593Smuzhiyun unsigned short __pad2; 112*4882a593Smuzhiyun compat_ulong_t unused1; 113*4882a593Smuzhiyun compat_ulong_t unused2; 114*4882a593Smuzhiyun }; 115*4882a593Smuzhiyun 116*4882a593Smuzhiyun struct compat_semid64_ds { 117*4882a593Smuzhiyun struct compat_ipc64_perm sem_perm; 118*4882a593Smuzhiyun compat_ulong_t sem_otime; 119*4882a593Smuzhiyun compat_ulong_t sem_otime_high; 120*4882a593Smuzhiyun compat_ulong_t sem_ctime; 121*4882a593Smuzhiyun compat_ulong_t sem_ctime_high; 122*4882a593Smuzhiyun compat_ulong_t sem_nsems; 123*4882a593Smuzhiyun compat_ulong_t __unused3; 124*4882a593Smuzhiyun compat_ulong_t __unused4; 125*4882a593Smuzhiyun }; 126*4882a593Smuzhiyun 127*4882a593Smuzhiyun struct compat_msqid64_ds { 128*4882a593Smuzhiyun struct compat_ipc64_perm msg_perm; 129*4882a593Smuzhiyun compat_ulong_t msg_stime; 130*4882a593Smuzhiyun compat_ulong_t msg_stime_high; 131*4882a593Smuzhiyun compat_ulong_t msg_rtime; 132*4882a593Smuzhiyun compat_ulong_t msg_rtime_high; 133*4882a593Smuzhiyun compat_ulong_t msg_ctime; 134*4882a593Smuzhiyun compat_ulong_t msg_ctime_high; 135*4882a593Smuzhiyun compat_ulong_t msg_cbytes; 136*4882a593Smuzhiyun compat_ulong_t msg_qnum; 137*4882a593Smuzhiyun compat_ulong_t msg_qbytes; 138*4882a593Smuzhiyun compat_pid_t msg_lspid; 139*4882a593Smuzhiyun compat_pid_t msg_lrpid; 140*4882a593Smuzhiyun compat_ulong_t __unused4; 141*4882a593Smuzhiyun compat_ulong_t __unused5; 142*4882a593Smuzhiyun }; 143*4882a593Smuzhiyun 144*4882a593Smuzhiyun struct compat_shmid64_ds { 145*4882a593Smuzhiyun struct compat_ipc64_perm shm_perm; 146*4882a593Smuzhiyun compat_size_t shm_segsz; 147*4882a593Smuzhiyun compat_ulong_t shm_atime; 148*4882a593Smuzhiyun compat_ulong_t shm_atime_high; 149*4882a593Smuzhiyun compat_ulong_t shm_dtime; 150*4882a593Smuzhiyun compat_ulong_t shm_dtime_high; 151*4882a593Smuzhiyun compat_ulong_t shm_ctime; 152*4882a593Smuzhiyun compat_ulong_t shm_ctime_high; 153*4882a593Smuzhiyun compat_pid_t shm_cpid; 154*4882a593Smuzhiyun compat_pid_t shm_lpid; 155*4882a593Smuzhiyun compat_ulong_t shm_nattch; 156*4882a593Smuzhiyun compat_ulong_t __unused4; 157*4882a593Smuzhiyun compat_ulong_t __unused5; 158*4882a593Smuzhiyun }; 159*4882a593Smuzhiyun 160*4882a593Smuzhiyun /* 161*4882a593Smuzhiyun * The type of struct elf_prstatus.pr_reg in compatible core dumps. 162*4882a593Smuzhiyun */ 163*4882a593Smuzhiyun typedef struct user_regs_struct compat_elf_gregset_t; 164*4882a593Smuzhiyun 165*4882a593Smuzhiyun /* Full regset -- prstatus on x32, otherwise on ia32 */ 166*4882a593Smuzhiyun #define PRSTATUS_SIZE(S, R) (R != sizeof(S.pr_reg) ? 144 : 296) 167*4882a593Smuzhiyun #define SET_PR_FPVALID(S, V, R) \ 168*4882a593Smuzhiyun do { *(int *) (((void *) &((S)->pr_reg)) + R) = (V); } \ 169*4882a593Smuzhiyun while (0) 170*4882a593Smuzhiyun 171*4882a593Smuzhiyun #ifdef CONFIG_X86_X32_ABI 172*4882a593Smuzhiyun #define COMPAT_USE_64BIT_TIME \ 173*4882a593Smuzhiyun (!!(task_pt_regs(current)->orig_ax & __X32_SYSCALL_BIT)) 174*4882a593Smuzhiyun #endif 175*4882a593Smuzhiyun arch_compat_alloc_user_space(long len)176*4882a593Smuzhiyunstatic inline void __user *arch_compat_alloc_user_space(long len) 177*4882a593Smuzhiyun { 178*4882a593Smuzhiyun compat_uptr_t sp; 179*4882a593Smuzhiyun 180*4882a593Smuzhiyun if (test_thread_flag(TIF_IA32)) { 181*4882a593Smuzhiyun sp = task_pt_regs(current)->sp; 182*4882a593Smuzhiyun } else { 183*4882a593Smuzhiyun /* -128 for the x32 ABI redzone */ 184*4882a593Smuzhiyun sp = task_pt_regs(current)->sp - 128; 185*4882a593Smuzhiyun } 186*4882a593Smuzhiyun 187*4882a593Smuzhiyun return (void __user *)round_down(sp - len, 16); 188*4882a593Smuzhiyun } 189*4882a593Smuzhiyun in_x32_syscall(void)190*4882a593Smuzhiyunstatic inline bool in_x32_syscall(void) 191*4882a593Smuzhiyun { 192*4882a593Smuzhiyun #ifdef CONFIG_X86_X32_ABI 193*4882a593Smuzhiyun if (task_pt_regs(current)->orig_ax & __X32_SYSCALL_BIT) 194*4882a593Smuzhiyun return true; 195*4882a593Smuzhiyun #endif 196*4882a593Smuzhiyun return false; 197*4882a593Smuzhiyun } 198*4882a593Smuzhiyun in_32bit_syscall(void)199*4882a593Smuzhiyunstatic inline bool in_32bit_syscall(void) 200*4882a593Smuzhiyun { 201*4882a593Smuzhiyun return in_ia32_syscall() || in_x32_syscall(); 202*4882a593Smuzhiyun } 203*4882a593Smuzhiyun 204*4882a593Smuzhiyun #ifdef CONFIG_COMPAT in_compat_syscall(void)205*4882a593Smuzhiyunstatic inline bool in_compat_syscall(void) 206*4882a593Smuzhiyun { 207*4882a593Smuzhiyun return in_32bit_syscall(); 208*4882a593Smuzhiyun } 209*4882a593Smuzhiyun #define in_compat_syscall in_compat_syscall /* override the generic impl */ 210*4882a593Smuzhiyun #define compat_need_64bit_alignment_fixup in_ia32_syscall 211*4882a593Smuzhiyun #endif 212*4882a593Smuzhiyun 213*4882a593Smuzhiyun struct compat_siginfo; 214*4882a593Smuzhiyun 215*4882a593Smuzhiyun #ifdef CONFIG_X86_X32_ABI 216*4882a593Smuzhiyun int copy_siginfo_to_user32(struct compat_siginfo __user *to, 217*4882a593Smuzhiyun const kernel_siginfo_t *from); 218*4882a593Smuzhiyun #define copy_siginfo_to_user32 copy_siginfo_to_user32 219*4882a593Smuzhiyun #endif /* CONFIG_X86_X32_ABI */ 220*4882a593Smuzhiyun 221*4882a593Smuzhiyun #endif /* _ASM_X86_COMPAT_H */ 222