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 20typedef u16 __compat_uid_t; 21typedef u16 __compat_gid_t; 22typedef u32 __compat_uid32_t; 23typedef u32 __compat_gid32_t; 24typedef u16 compat_mode_t; 25typedef u16 compat_dev_t; 26typedef u16 compat_nlink_t; 27typedef u16 compat_ipc_pid_t; 28typedef u32 compat_caddr_t; 29typedef __kernel_fsid_t compat_fsid_t; 30typedef s64 __attribute__((aligned(4))) compat_s64; 31typedef u64 __attribute__((aligned(4))) compat_u64; 32 33struct 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 56struct 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 */ 72struct 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 80struct 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 97typedef u32 compat_old_sigset_t; /* at least 32 bits */ 98 99#define _COMPAT_NSIG 64 100#define _COMPAT_NSIG_BPW 32 101 102typedef u32 compat_sigset_word; 103 104#define COMPAT_OFF_T_MAX 0x7fffffff 105 106struct 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 120struct 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 131struct 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 148struct 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 */ 167typedef 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 187static inline void __user *compat_ptr(compat_uptr_t uptr) 188{ 189 return (void __user *)(unsigned long)uptr; 190} 191 192static inline compat_uptr_t ptr_to_compat(void __user *uptr) 193{ 194 return (u32)(unsigned long)uptr; 195} 196 197static 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 211static 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 220static inline bool in_32bit_syscall(void) 221{ 222 return in_ia32_syscall() || in_x32_syscall(); 223} 224 225#ifdef CONFIG_COMPAT 226static 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 233struct compat_siginfo; 234int __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