xref: /openbmc/linux/arch/arm64/include/asm/compat.h (revision 68db0cf1)
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>
2668db0cf1SIngo 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