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