13dd681d9SWill Deacon /* 23dd681d9SWill Deacon * Copyright (C) 2012 ARM Ltd. 33dd681d9SWill Deacon * 43dd681d9SWill Deacon * This program is free software; you can redistribute it and/or modify 53dd681d9SWill Deacon * it under the terms of the GNU General Public License version 2 as 63dd681d9SWill Deacon * published by the Free Software Foundation. 73dd681d9SWill Deacon * 83dd681d9SWill Deacon * This program is distributed in the hope that it will be useful, 93dd681d9SWill Deacon * but WITHOUT ANY WARRANTY; without even the implied warranty of 103dd681d9SWill Deacon * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 113dd681d9SWill Deacon * GNU General Public License for more details. 123dd681d9SWill Deacon * 133dd681d9SWill Deacon * You should have received a copy of the GNU General Public License 143dd681d9SWill Deacon * along with this program. If not, see <http://www.gnu.org/licenses/>. 153dd681d9SWill Deacon */ 163dd681d9SWill Deacon #ifndef __ASM_COMPAT_H 173dd681d9SWill Deacon #define __ASM_COMPAT_H 183dd681d9SWill Deacon #ifdef __KERNEL__ 193dd681d9SWill Deacon #ifdef CONFIG_COMPAT 203dd681d9SWill Deacon 213dd681d9SWill Deacon /* 223dd681d9SWill Deacon * Architecture specific compatibility types 233dd681d9SWill Deacon */ 243dd681d9SWill Deacon #include <linux/types.h> 253dd681d9SWill Deacon #include <linux/sched.h> 26*68db0cf1SIngo Molnar #include <linux/sched/task_stack.h> 273dd681d9SWill Deacon 283dd681d9SWill Deacon #define COMPAT_USER_HZ 100 29a795a38eSWill Deacon #ifdef __AARCH64EB__ 30a795a38eSWill Deacon #define COMPAT_UTS_MACHINE "armv8b\0\0" 31a795a38eSWill Deacon #else 323dd681d9SWill Deacon #define COMPAT_UTS_MACHINE "armv8l\0\0" 33a795a38eSWill Deacon #endif 343dd681d9SWill Deacon 353dd681d9SWill Deacon typedef u32 compat_size_t; 363dd681d9SWill Deacon typedef s32 compat_ssize_t; 373dd681d9SWill Deacon typedef s32 compat_time_t; 383dd681d9SWill Deacon typedef s32 compat_clock_t; 393dd681d9SWill Deacon typedef s32 compat_pid_t; 40971a5b6fSVictor Kamensky typedef u16 __compat_uid_t; 41971a5b6fSVictor Kamensky typedef u16 __compat_gid_t; 42f15a2a12SCatalin Marinas typedef u16 __compat_uid16_t; 43f15a2a12SCatalin Marinas typedef u16 __compat_gid16_t; 443dd681d9SWill Deacon typedef u32 __compat_uid32_t; 453dd681d9SWill Deacon typedef u32 __compat_gid32_t; 46f15a2a12SCatalin Marinas typedef u16 compat_mode_t; 473dd681d9SWill Deacon typedef u32 compat_ino_t; 483dd681d9SWill Deacon typedef u32 compat_dev_t; 493dd681d9SWill Deacon typedef s32 compat_off_t; 503dd681d9SWill Deacon typedef s64 compat_loff_t; 51f15a2a12SCatalin Marinas typedef s32 compat_nlink_t; 523dd681d9SWill Deacon typedef u16 compat_ipc_pid_t; 533dd681d9SWill Deacon typedef s32 compat_daddr_t; 543dd681d9SWill Deacon typedef u32 compat_caddr_t; 553dd681d9SWill Deacon typedef __kernel_fsid_t compat_fsid_t; 563dd681d9SWill Deacon typedef s32 compat_key_t; 573dd681d9SWill Deacon typedef s32 compat_timer_t; 583dd681d9SWill Deacon 59f15a2a12SCatalin Marinas typedef s16 compat_short_t; 603dd681d9SWill Deacon typedef s32 compat_int_t; 613dd681d9SWill Deacon typedef s32 compat_long_t; 623dd681d9SWill Deacon typedef s64 compat_s64; 63f15a2a12SCatalin Marinas typedef u16 compat_ushort_t; 643dd681d9SWill Deacon typedef u32 compat_uint_t; 653dd681d9SWill Deacon typedef u32 compat_ulong_t; 663dd681d9SWill Deacon typedef u64 compat_u64; 67751f409dSDenys Vlasenko typedef u32 compat_uptr_t; 683dd681d9SWill Deacon 693dd681d9SWill Deacon struct compat_timespec { 703dd681d9SWill Deacon compat_time_t tv_sec; 713dd681d9SWill Deacon s32 tv_nsec; 723dd681d9SWill Deacon }; 733dd681d9SWill Deacon 743dd681d9SWill Deacon struct compat_timeval { 753dd681d9SWill Deacon compat_time_t tv_sec; 763dd681d9SWill Deacon s32 tv_usec; 773dd681d9SWill Deacon }; 783dd681d9SWill Deacon 793dd681d9SWill Deacon struct compat_stat { 80a795a38eSWill Deacon #ifdef __AARCH64EB__ 81a795a38eSWill Deacon short st_dev; 82a795a38eSWill Deacon short __pad1; 83a795a38eSWill Deacon #else 843dd681d9SWill Deacon compat_dev_t st_dev; 85a795a38eSWill Deacon #endif 863dd681d9SWill Deacon compat_ino_t st_ino; 873dd681d9SWill Deacon compat_mode_t st_mode; 88f15a2a12SCatalin Marinas compat_ushort_t st_nlink; 89f15a2a12SCatalin Marinas __compat_uid16_t st_uid; 90f15a2a12SCatalin Marinas __compat_gid16_t st_gid; 91a795a38eSWill Deacon #ifdef __AARCH64EB__ 92a795a38eSWill Deacon short st_rdev; 93a795a38eSWill Deacon short __pad2; 94a795a38eSWill Deacon #else 953dd681d9SWill Deacon compat_dev_t st_rdev; 96a795a38eSWill Deacon #endif 973dd681d9SWill Deacon compat_off_t st_size; 983dd681d9SWill Deacon compat_off_t st_blksize; 993dd681d9SWill Deacon compat_off_t st_blocks; 1003dd681d9SWill Deacon compat_time_t st_atime; 101f15a2a12SCatalin Marinas compat_ulong_t st_atime_nsec; 1023dd681d9SWill Deacon compat_time_t st_mtime; 103f15a2a12SCatalin Marinas compat_ulong_t st_mtime_nsec; 1043dd681d9SWill Deacon compat_time_t st_ctime; 105f15a2a12SCatalin Marinas compat_ulong_t st_ctime_nsec; 106f15a2a12SCatalin Marinas compat_ulong_t __unused4[2]; 1073dd681d9SWill Deacon }; 1083dd681d9SWill Deacon 1093dd681d9SWill Deacon struct compat_flock { 1103dd681d9SWill Deacon short l_type; 1113dd681d9SWill Deacon short l_whence; 1123dd681d9SWill Deacon compat_off_t l_start; 1133dd681d9SWill Deacon compat_off_t l_len; 1143dd681d9SWill Deacon compat_pid_t l_pid; 1153dd681d9SWill Deacon }; 1163dd681d9SWill Deacon 1173dd681d9SWill Deacon #define F_GETLK64 12 /* using 'struct flock64' */ 1183dd681d9SWill Deacon #define F_SETLK64 13 1193dd681d9SWill Deacon #define F_SETLKW64 14 1203dd681d9SWill Deacon 1213dd681d9SWill Deacon struct compat_flock64 { 1223dd681d9SWill Deacon short l_type; 1233dd681d9SWill Deacon short l_whence; 1243dd681d9SWill Deacon compat_loff_t l_start; 1253dd681d9SWill Deacon compat_loff_t l_len; 1263dd681d9SWill Deacon compat_pid_t l_pid; 1273dd681d9SWill Deacon }; 1283dd681d9SWill Deacon 1293dd681d9SWill Deacon struct compat_statfs { 1303dd681d9SWill Deacon int f_type; 1313dd681d9SWill Deacon int f_bsize; 1323dd681d9SWill Deacon int f_blocks; 1333dd681d9SWill Deacon int f_bfree; 1343dd681d9SWill Deacon int f_bavail; 1353dd681d9SWill Deacon int f_files; 1363dd681d9SWill Deacon int f_ffree; 1373dd681d9SWill Deacon compat_fsid_t f_fsid; 1383dd681d9SWill Deacon int f_namelen; /* SunOS ignores this field. */ 1393dd681d9SWill Deacon int f_frsize; 1403dd681d9SWill Deacon int f_flags; 1413dd681d9SWill Deacon int f_spare[4]; 1423dd681d9SWill Deacon }; 1433dd681d9SWill Deacon 1443dd681d9SWill Deacon #define COMPAT_RLIM_INFINITY 0xffffffff 1453dd681d9SWill Deacon 1463dd681d9SWill Deacon typedef u32 compat_old_sigset_t; 1473dd681d9SWill Deacon 1483dd681d9SWill Deacon #define _COMPAT_NSIG 64 1493dd681d9SWill Deacon #define _COMPAT_NSIG_BPW 32 1503dd681d9SWill Deacon 1513dd681d9SWill Deacon typedef u32 compat_sigset_word; 1523dd681d9SWill Deacon 153751f409dSDenys Vlasenko typedef union compat_sigval { 154751f409dSDenys Vlasenko compat_int_t sival_int; 155751f409dSDenys Vlasenko compat_uptr_t sival_ptr; 156751f409dSDenys Vlasenko } compat_sigval_t; 157751f409dSDenys Vlasenko 158751f409dSDenys Vlasenko typedef struct compat_siginfo { 159751f409dSDenys Vlasenko int si_signo; 160751f409dSDenys Vlasenko int si_errno; 161751f409dSDenys Vlasenko int si_code; 162751f409dSDenys Vlasenko 163751f409dSDenys Vlasenko union { 164751f409dSDenys Vlasenko int _pad[128/sizeof(int) - 3]; 165751f409dSDenys Vlasenko 166751f409dSDenys Vlasenko /* kill() */ 167751f409dSDenys Vlasenko struct { 168751f409dSDenys Vlasenko compat_pid_t _pid; /* sender's pid */ 169751f409dSDenys Vlasenko __compat_uid32_t _uid; /* sender's uid */ 170751f409dSDenys Vlasenko } _kill; 171751f409dSDenys Vlasenko 172751f409dSDenys Vlasenko /* POSIX.1b timers */ 173751f409dSDenys Vlasenko struct { 174751f409dSDenys Vlasenko compat_timer_t _tid; /* timer id */ 175751f409dSDenys Vlasenko int _overrun; /* overrun count */ 176751f409dSDenys Vlasenko compat_sigval_t _sigval; /* same as below */ 177751f409dSDenys Vlasenko int _sys_private; /* not to be passed to user */ 178751f409dSDenys Vlasenko } _timer; 179751f409dSDenys Vlasenko 180751f409dSDenys Vlasenko /* POSIX.1b signals */ 181751f409dSDenys Vlasenko struct { 182751f409dSDenys Vlasenko compat_pid_t _pid; /* sender's pid */ 183751f409dSDenys Vlasenko __compat_uid32_t _uid; /* sender's uid */ 184751f409dSDenys Vlasenko compat_sigval_t _sigval; 185751f409dSDenys Vlasenko } _rt; 186751f409dSDenys Vlasenko 187751f409dSDenys Vlasenko /* SIGCHLD */ 188751f409dSDenys Vlasenko struct { 189751f409dSDenys Vlasenko compat_pid_t _pid; /* which child */ 190751f409dSDenys Vlasenko __compat_uid32_t _uid; /* sender's uid */ 191751f409dSDenys Vlasenko int _status; /* exit code */ 192751f409dSDenys Vlasenko compat_clock_t _utime; 193751f409dSDenys Vlasenko compat_clock_t _stime; 194751f409dSDenys Vlasenko } _sigchld; 195751f409dSDenys Vlasenko 196751f409dSDenys Vlasenko /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ 197751f409dSDenys Vlasenko struct { 198751f409dSDenys Vlasenko compat_uptr_t _addr; /* faulting insn/memory ref. */ 199751f409dSDenys Vlasenko short _addr_lsb; /* LSB of the reported address */ 200751f409dSDenys Vlasenko } _sigfault; 201751f409dSDenys Vlasenko 202751f409dSDenys Vlasenko /* SIGPOLL */ 203751f409dSDenys Vlasenko struct { 204751f409dSDenys Vlasenko compat_long_t _band; /* POLL_IN, POLL_OUT, POLL_MSG */ 205751f409dSDenys Vlasenko int _fd; 206751f409dSDenys Vlasenko } _sigpoll; 207cc5e9097SAKASHI Takahiro 208cc5e9097SAKASHI Takahiro /* SIGSYS */ 209cc5e9097SAKASHI Takahiro struct { 210cc5e9097SAKASHI Takahiro compat_uptr_t _call_addr; /* calling user insn */ 211cc5e9097SAKASHI Takahiro int _syscall; /* triggering system call number */ 212cc5e9097SAKASHI Takahiro compat_uint_t _arch; /* AUDIT_ARCH_* of syscall */ 213cc5e9097SAKASHI Takahiro } _sigsys; 214751f409dSDenys Vlasenko } _sifields; 215751f409dSDenys Vlasenko } compat_siginfo_t; 216751f409dSDenys Vlasenko 2173dd681d9SWill Deacon #define COMPAT_OFF_T_MAX 0x7fffffff 2183dd681d9SWill Deacon #define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL 2193dd681d9SWill Deacon 2203dd681d9SWill Deacon /* 2213dd681d9SWill Deacon * A pointer passed in from user mode. This should not 2223dd681d9SWill Deacon * be used for syscall parameters, just declare them 2233dd681d9SWill Deacon * as pointers because the syscall entry code will have 2243dd681d9SWill Deacon * appropriately converted them already. 2253dd681d9SWill Deacon */ 2263dd681d9SWill Deacon 2273dd681d9SWill Deacon static inline void __user *compat_ptr(compat_uptr_t uptr) 2283dd681d9SWill Deacon { 2293dd681d9SWill Deacon return (void __user *)(unsigned long)uptr; 2303dd681d9SWill Deacon } 2313dd681d9SWill Deacon 2323dd681d9SWill Deacon static inline compat_uptr_t ptr_to_compat(void __user *uptr) 2333dd681d9SWill Deacon { 2343dd681d9SWill Deacon return (u32)(unsigned long)uptr; 2353dd681d9SWill Deacon } 2363dd681d9SWill Deacon 237adc235afSArnd Bergmann #define compat_user_stack_pointer() (user_stack_pointer(task_pt_regs(current))) 2389b064fc3SAl Viro 2393dd681d9SWill Deacon static inline void __user *arch_compat_alloc_user_space(long len) 2403dd681d9SWill Deacon { 2419b064fc3SAl Viro return (void __user *)compat_user_stack_pointer() - len; 2423dd681d9SWill Deacon } 2433dd681d9SWill Deacon 2443dd681d9SWill Deacon struct compat_ipc64_perm { 2453dd681d9SWill Deacon compat_key_t key; 2463dd681d9SWill Deacon __compat_uid32_t uid; 2473dd681d9SWill Deacon __compat_gid32_t gid; 2483dd681d9SWill Deacon __compat_uid32_t cuid; 2493dd681d9SWill Deacon __compat_gid32_t cgid; 2503dd681d9SWill Deacon unsigned short mode; 2513dd681d9SWill Deacon unsigned short __pad1; 2523dd681d9SWill Deacon unsigned short seq; 2533dd681d9SWill Deacon unsigned short __pad2; 2543dd681d9SWill Deacon compat_ulong_t unused1; 2553dd681d9SWill Deacon compat_ulong_t unused2; 2563dd681d9SWill Deacon }; 2573dd681d9SWill Deacon 2583dd681d9SWill Deacon struct compat_semid64_ds { 2593dd681d9SWill Deacon struct compat_ipc64_perm sem_perm; 2603dd681d9SWill Deacon compat_time_t sem_otime; 2613dd681d9SWill Deacon compat_ulong_t __unused1; 2623dd681d9SWill Deacon compat_time_t sem_ctime; 2633dd681d9SWill Deacon compat_ulong_t __unused2; 2643dd681d9SWill Deacon compat_ulong_t sem_nsems; 2653dd681d9SWill Deacon compat_ulong_t __unused3; 2663dd681d9SWill Deacon compat_ulong_t __unused4; 2673dd681d9SWill Deacon }; 2683dd681d9SWill Deacon 2693dd681d9SWill Deacon struct compat_msqid64_ds { 2703dd681d9SWill Deacon struct compat_ipc64_perm msg_perm; 2713dd681d9SWill Deacon compat_time_t msg_stime; 2723dd681d9SWill Deacon compat_ulong_t __unused1; 2733dd681d9SWill Deacon compat_time_t msg_rtime; 2743dd681d9SWill Deacon compat_ulong_t __unused2; 2753dd681d9SWill Deacon compat_time_t msg_ctime; 2763dd681d9SWill Deacon compat_ulong_t __unused3; 2773dd681d9SWill Deacon compat_ulong_t msg_cbytes; 2783dd681d9SWill Deacon compat_ulong_t msg_qnum; 2793dd681d9SWill Deacon compat_ulong_t msg_qbytes; 2803dd681d9SWill Deacon compat_pid_t msg_lspid; 2813dd681d9SWill Deacon compat_pid_t msg_lrpid; 2823dd681d9SWill Deacon compat_ulong_t __unused4; 2833dd681d9SWill Deacon compat_ulong_t __unused5; 2843dd681d9SWill Deacon }; 2853dd681d9SWill Deacon 2863dd681d9SWill Deacon struct compat_shmid64_ds { 2873dd681d9SWill Deacon struct compat_ipc64_perm shm_perm; 2883dd681d9SWill Deacon compat_size_t shm_segsz; 2893dd681d9SWill Deacon compat_time_t shm_atime; 2903dd681d9SWill Deacon compat_ulong_t __unused1; 2913dd681d9SWill Deacon compat_time_t shm_dtime; 2923dd681d9SWill Deacon compat_ulong_t __unused2; 2933dd681d9SWill Deacon compat_time_t shm_ctime; 2943dd681d9SWill Deacon compat_ulong_t __unused3; 2953dd681d9SWill Deacon compat_pid_t shm_cpid; 2963dd681d9SWill Deacon compat_pid_t shm_lpid; 2973dd681d9SWill Deacon compat_ulong_t shm_nattch; 2983dd681d9SWill Deacon compat_ulong_t __unused4; 2993dd681d9SWill Deacon compat_ulong_t __unused5; 3003dd681d9SWill Deacon }; 3013dd681d9SWill Deacon 3023dd681d9SWill Deacon static inline int is_compat_task(void) 3033dd681d9SWill Deacon { 3043dd681d9SWill Deacon return test_thread_flag(TIF_32BIT); 3053dd681d9SWill Deacon } 3063dd681d9SWill Deacon 3073dd681d9SWill Deacon static inline int is_compat_thread(struct thread_info *thread) 3083dd681d9SWill Deacon { 3093dd681d9SWill Deacon return test_ti_thread_flag(thread, TIF_32BIT); 3103dd681d9SWill Deacon } 3113dd681d9SWill Deacon 3123dd681d9SWill Deacon #else /* !CONFIG_COMPAT */ 3133dd681d9SWill Deacon 3143dd681d9SWill Deacon static inline int is_compat_thread(struct thread_info *thread) 3153dd681d9SWill Deacon { 3163dd681d9SWill Deacon return 0; 3173dd681d9SWill Deacon } 3183dd681d9SWill Deacon 3193dd681d9SWill Deacon #endif /* CONFIG_COMPAT */ 3203dd681d9SWill Deacon #endif /* __KERNEL__ */ 3213dd681d9SWill Deacon #endif /* __ASM_COMPAT_H */ 322