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 typedef s64 __attribute__((aligned(4))) compat_s64; 31 typedef u64 __attribute__((aligned(4))) compat_u64; 32 33 struct compat_stat { 34 compat_dev_t st_dev; 35 u16 __pad1; 36 compat_ino_t st_ino; 37 compat_mode_t st_mode; 38 compat_nlink_t st_nlink; 39 __compat_uid_t st_uid; 40 __compat_gid_t st_gid; 41 compat_dev_t st_rdev; 42 u16 __pad2; 43 u32 st_size; 44 u32 st_blksize; 45 u32 st_blocks; 46 u32 st_atime; 47 u32 st_atime_nsec; 48 u32 st_mtime; 49 u32 st_mtime_nsec; 50 u32 st_ctime; 51 u32 st_ctime_nsec; 52 u32 __unused4; 53 u32 __unused5; 54 }; 55 56 struct compat_flock { 57 short l_type; 58 short l_whence; 59 compat_off_t l_start; 60 compat_off_t l_len; 61 compat_pid_t l_pid; 62 }; 63 64 #define F_GETLK64 12 /* using 'struct flock64' */ 65 #define F_SETLK64 13 66 #define F_SETLKW64 14 67 68 /* 69 * IA32 uses 4 byte alignment for 64 bit quantities, 70 * so we need to pack this structure. 71 */ 72 struct compat_flock64 { 73 short l_type; 74 short l_whence; 75 compat_loff_t l_start; 76 compat_loff_t l_len; 77 compat_pid_t l_pid; 78 } __attribute__((packed)); 79 80 struct compat_statfs { 81 int f_type; 82 int f_bsize; 83 int f_blocks; 84 int f_bfree; 85 int f_bavail; 86 int f_files; 87 int f_ffree; 88 compat_fsid_t f_fsid; 89 int f_namelen; /* SunOS ignores this field. */ 90 int f_frsize; 91 int f_flags; 92 int f_spare[4]; 93 }; 94 95 #define COMPAT_RLIM_INFINITY 0xffffffff 96 97 typedef u32 compat_old_sigset_t; /* at least 32 bits */ 98 99 #define _COMPAT_NSIG 64 100 #define _COMPAT_NSIG_BPW 32 101 102 typedef u32 compat_sigset_word; 103 104 #define COMPAT_OFF_T_MAX 0x7fffffff 105 106 struct compat_ipc64_perm { 107 compat_key_t key; 108 __compat_uid32_t uid; 109 __compat_gid32_t gid; 110 __compat_uid32_t cuid; 111 __compat_gid32_t cgid; 112 unsigned short mode; 113 unsigned short __pad1; 114 unsigned short seq; 115 unsigned short __pad2; 116 compat_ulong_t unused1; 117 compat_ulong_t unused2; 118 }; 119 120 struct compat_semid64_ds { 121 struct compat_ipc64_perm sem_perm; 122 compat_ulong_t sem_otime; 123 compat_ulong_t sem_otime_high; 124 compat_ulong_t sem_ctime; 125 compat_ulong_t sem_ctime_high; 126 compat_ulong_t sem_nsems; 127 compat_ulong_t __unused3; 128 compat_ulong_t __unused4; 129 }; 130 131 struct compat_msqid64_ds { 132 struct compat_ipc64_perm msg_perm; 133 compat_ulong_t msg_stime; 134 compat_ulong_t msg_stime_high; 135 compat_ulong_t msg_rtime; 136 compat_ulong_t msg_rtime_high; 137 compat_ulong_t msg_ctime; 138 compat_ulong_t msg_ctime_high; 139 compat_ulong_t msg_cbytes; 140 compat_ulong_t msg_qnum; 141 compat_ulong_t msg_qbytes; 142 compat_pid_t msg_lspid; 143 compat_pid_t msg_lrpid; 144 compat_ulong_t __unused4; 145 compat_ulong_t __unused5; 146 }; 147 148 struct compat_shmid64_ds { 149 struct compat_ipc64_perm shm_perm; 150 compat_size_t shm_segsz; 151 compat_ulong_t shm_atime; 152 compat_ulong_t shm_atime_high; 153 compat_ulong_t shm_dtime; 154 compat_ulong_t shm_dtime_high; 155 compat_ulong_t shm_ctime; 156 compat_ulong_t shm_ctime_high; 157 compat_pid_t shm_cpid; 158 compat_pid_t shm_lpid; 159 compat_ulong_t shm_nattch; 160 compat_ulong_t __unused4; 161 compat_ulong_t __unused5; 162 }; 163 164 /* 165 * The type of struct elf_prstatus.pr_reg in compatible core dumps. 166 */ 167 typedef struct user_regs_struct compat_elf_gregset_t; 168 169 /* Full regset -- prstatus on x32, otherwise on ia32 */ 170 #define PRSTATUS_SIZE(S, R) (R != sizeof(S.pr_reg) ? 144 : 296) 171 #define SET_PR_FPVALID(S, V, R) \ 172 do { *(int *) (((void *) &((S)->pr_reg)) + R) = (V); } \ 173 while (0) 174 175 #ifdef CONFIG_X86_X32_ABI 176 #define COMPAT_USE_64BIT_TIME \ 177 (!!(task_pt_regs(current)->orig_ax & __X32_SYSCALL_BIT)) 178 #endif 179 180 /* 181 * A pointer passed in from user mode. This should not 182 * be used for syscall parameters, just declare them 183 * as pointers because the syscall entry code will have 184 * appropriately converted them already. 185 */ 186 187 static inline void __user *compat_ptr(compat_uptr_t uptr) 188 { 189 return (void __user *)(unsigned long)uptr; 190 } 191 192 static inline compat_uptr_t ptr_to_compat(void __user *uptr) 193 { 194 return (u32)(unsigned long)uptr; 195 } 196 197 static inline void __user *arch_compat_alloc_user_space(long len) 198 { 199 compat_uptr_t sp; 200 201 if (test_thread_flag(TIF_IA32)) { 202 sp = task_pt_regs(current)->sp; 203 } else { 204 /* -128 for the x32 ABI redzone */ 205 sp = task_pt_regs(current)->sp - 128; 206 } 207 208 return (void __user *)round_down(sp - len, 16); 209 } 210 211 static inline bool in_x32_syscall(void) 212 { 213 #ifdef CONFIG_X86_X32_ABI 214 if (task_pt_regs(current)->orig_ax & __X32_SYSCALL_BIT) 215 return true; 216 #endif 217 return false; 218 } 219 220 static inline bool in_32bit_syscall(void) 221 { 222 return in_ia32_syscall() || in_x32_syscall(); 223 } 224 225 #ifdef CONFIG_COMPAT 226 static inline bool in_compat_syscall(void) 227 { 228 return in_32bit_syscall(); 229 } 230 #define in_compat_syscall in_compat_syscall /* override the generic impl */ 231 #endif 232 233 struct compat_siginfo; 234 int __copy_siginfo_to_user32(struct compat_siginfo __user *to, 235 const kernel_siginfo_t *from, bool x32_ABI); 236 237 #endif /* _ASM_X86_COMPAT_H */ 238