1/* 2 * Copyright (C) 2012 ARM Ltd. 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 2 as 6 * published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 */ 16#ifndef __ASM_COMPAT_H 17#define __ASM_COMPAT_H 18#ifdef __KERNEL__ 19#ifdef CONFIG_COMPAT 20 21/* 22 * Architecture specific compatibility types 23 */ 24#include <linux/types.h> 25#include <linux/sched.h> 26#include <linux/ptrace.h> 27 28#define COMPAT_USER_HZ 100 29#define COMPAT_UTS_MACHINE "armv8l\0\0" 30 31typedef u32 compat_size_t; 32typedef s32 compat_ssize_t; 33typedef s32 compat_time_t; 34typedef s32 compat_clock_t; 35typedef s32 compat_pid_t; 36typedef u32 __compat_uid_t; 37typedef u32 __compat_gid_t; 38typedef u16 __compat_uid16_t; 39typedef u16 __compat_gid16_t; 40typedef u32 __compat_uid32_t; 41typedef u32 __compat_gid32_t; 42typedef u16 compat_mode_t; 43typedef u32 compat_ino_t; 44typedef u32 compat_dev_t; 45typedef s32 compat_off_t; 46typedef s64 compat_loff_t; 47typedef s32 compat_nlink_t; 48typedef u16 compat_ipc_pid_t; 49typedef s32 compat_daddr_t; 50typedef u32 compat_caddr_t; 51typedef __kernel_fsid_t compat_fsid_t; 52typedef s32 compat_key_t; 53typedef s32 compat_timer_t; 54 55typedef s16 compat_short_t; 56typedef s32 compat_int_t; 57typedef s32 compat_long_t; 58typedef s64 compat_s64; 59typedef u16 compat_ushort_t; 60typedef u32 compat_uint_t; 61typedef u32 compat_ulong_t; 62typedef u64 compat_u64; 63typedef u32 compat_uptr_t; 64 65struct compat_timespec { 66 compat_time_t tv_sec; 67 s32 tv_nsec; 68}; 69 70struct compat_timeval { 71 compat_time_t tv_sec; 72 s32 tv_usec; 73}; 74 75struct compat_stat { 76 compat_dev_t st_dev; 77 compat_ino_t st_ino; 78 compat_mode_t st_mode; 79 compat_ushort_t st_nlink; 80 __compat_uid16_t st_uid; 81 __compat_gid16_t st_gid; 82 compat_dev_t st_rdev; 83 compat_off_t st_size; 84 compat_off_t st_blksize; 85 compat_off_t st_blocks; 86 compat_time_t st_atime; 87 compat_ulong_t st_atime_nsec; 88 compat_time_t st_mtime; 89 compat_ulong_t st_mtime_nsec; 90 compat_time_t st_ctime; 91 compat_ulong_t st_ctime_nsec; 92 compat_ulong_t __unused4[2]; 93}; 94 95struct compat_flock { 96 short l_type; 97 short l_whence; 98 compat_off_t l_start; 99 compat_off_t l_len; 100 compat_pid_t l_pid; 101}; 102 103#define F_GETLK64 12 /* using 'struct flock64' */ 104#define F_SETLK64 13 105#define F_SETLKW64 14 106 107struct compat_flock64 { 108 short l_type; 109 short l_whence; 110 compat_loff_t l_start; 111 compat_loff_t l_len; 112 compat_pid_t l_pid; 113}; 114 115struct compat_statfs { 116 int f_type; 117 int f_bsize; 118 int f_blocks; 119 int f_bfree; 120 int f_bavail; 121 int f_files; 122 int f_ffree; 123 compat_fsid_t f_fsid; 124 int f_namelen; /* SunOS ignores this field. */ 125 int f_frsize; 126 int f_flags; 127 int f_spare[4]; 128}; 129 130#define COMPAT_RLIM_INFINITY 0xffffffff 131 132typedef u32 compat_old_sigset_t; 133 134#define _COMPAT_NSIG 64 135#define _COMPAT_NSIG_BPW 32 136 137typedef u32 compat_sigset_word; 138 139typedef union compat_sigval { 140 compat_int_t sival_int; 141 compat_uptr_t sival_ptr; 142} compat_sigval_t; 143 144typedef struct compat_siginfo { 145 int si_signo; 146 int si_errno; 147 int si_code; 148 149 union { 150 /* The padding is the same size as AArch64. */ 151 int _pad[128/sizeof(int) - 3]; 152 153 /* kill() */ 154 struct { 155 compat_pid_t _pid; /* sender's pid */ 156 __compat_uid32_t _uid; /* sender's uid */ 157 } _kill; 158 159 /* POSIX.1b timers */ 160 struct { 161 compat_timer_t _tid; /* timer id */ 162 int _overrun; /* overrun count */ 163 compat_sigval_t _sigval; /* same as below */ 164 int _sys_private; /* not to be passed to user */ 165 } _timer; 166 167 /* POSIX.1b signals */ 168 struct { 169 compat_pid_t _pid; /* sender's pid */ 170 __compat_uid32_t _uid; /* sender's uid */ 171 compat_sigval_t _sigval; 172 } _rt; 173 174 /* SIGCHLD */ 175 struct { 176 compat_pid_t _pid; /* which child */ 177 __compat_uid32_t _uid; /* sender's uid */ 178 int _status; /* exit code */ 179 compat_clock_t _utime; 180 compat_clock_t _stime; 181 } _sigchld; 182 183 /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ 184 struct { 185 compat_uptr_t _addr; /* faulting insn/memory ref. */ 186 short _addr_lsb; /* LSB of the reported address */ 187 } _sigfault; 188 189 /* SIGPOLL */ 190 struct { 191 compat_long_t _band; /* POLL_IN, POLL_OUT, POLL_MSG */ 192 int _fd; 193 } _sigpoll; 194 } _sifields; 195} compat_siginfo_t; 196 197#define COMPAT_OFF_T_MAX 0x7fffffff 198#define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL 199 200/* 201 * A pointer passed in from user mode. This should not 202 * be used for syscall parameters, just declare them 203 * as pointers because the syscall entry code will have 204 * appropriately converted them already. 205 */ 206 207static inline void __user *compat_ptr(compat_uptr_t uptr) 208{ 209 return (void __user *)(unsigned long)uptr; 210} 211 212static inline compat_uptr_t ptr_to_compat(void __user *uptr) 213{ 214 return (u32)(unsigned long)uptr; 215} 216 217#define compat_user_stack_pointer() (current_pt_regs()->compat_sp) 218 219static inline void __user *arch_compat_alloc_user_space(long len) 220{ 221 return (void __user *)compat_user_stack_pointer() - len; 222} 223 224struct compat_ipc64_perm { 225 compat_key_t key; 226 __compat_uid32_t uid; 227 __compat_gid32_t gid; 228 __compat_uid32_t cuid; 229 __compat_gid32_t cgid; 230 unsigned short mode; 231 unsigned short __pad1; 232 unsigned short seq; 233 unsigned short __pad2; 234 compat_ulong_t unused1; 235 compat_ulong_t unused2; 236}; 237 238struct compat_semid64_ds { 239 struct compat_ipc64_perm sem_perm; 240 compat_time_t sem_otime; 241 compat_ulong_t __unused1; 242 compat_time_t sem_ctime; 243 compat_ulong_t __unused2; 244 compat_ulong_t sem_nsems; 245 compat_ulong_t __unused3; 246 compat_ulong_t __unused4; 247}; 248 249struct compat_msqid64_ds { 250 struct compat_ipc64_perm msg_perm; 251 compat_time_t msg_stime; 252 compat_ulong_t __unused1; 253 compat_time_t msg_rtime; 254 compat_ulong_t __unused2; 255 compat_time_t msg_ctime; 256 compat_ulong_t __unused3; 257 compat_ulong_t msg_cbytes; 258 compat_ulong_t msg_qnum; 259 compat_ulong_t msg_qbytes; 260 compat_pid_t msg_lspid; 261 compat_pid_t msg_lrpid; 262 compat_ulong_t __unused4; 263 compat_ulong_t __unused5; 264}; 265 266struct compat_shmid64_ds { 267 struct compat_ipc64_perm shm_perm; 268 compat_size_t shm_segsz; 269 compat_time_t shm_atime; 270 compat_ulong_t __unused1; 271 compat_time_t shm_dtime; 272 compat_ulong_t __unused2; 273 compat_time_t shm_ctime; 274 compat_ulong_t __unused3; 275 compat_pid_t shm_cpid; 276 compat_pid_t shm_lpid; 277 compat_ulong_t shm_nattch; 278 compat_ulong_t __unused4; 279 compat_ulong_t __unused5; 280}; 281 282static inline int is_compat_task(void) 283{ 284 return test_thread_flag(TIF_32BIT); 285} 286 287static inline int is_compat_thread(struct thread_info *thread) 288{ 289 return test_ti_thread_flag(thread, TIF_32BIT); 290} 291 292#else /* !CONFIG_COMPAT */ 293 294static inline int is_compat_task(void) 295{ 296 return 0; 297} 298 299static inline int is_compat_thread(struct thread_info *thread) 300{ 301 return 0; 302} 303 304#endif /* CONFIG_COMPAT */ 305#endif /* __KERNEL__ */ 306#endif /* __ASM_COMPAT_H */ 307