Commit 751f409db6216ebd134a94f6dcd97779933a5106
Committed by
Linus Torvalds
1 parent
5ab1c309b3
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
compat: move compat_siginfo_t definition to asm/compat.h
This is a preparatory patch for the introduction of NT_SIGINFO elf note. Make the location of compat_siginfo_t uniform across eight architectures which have it. Now it can be pulled in by including asm/compat.h or linux/compat.h. Most of the copies are verbatim. compat_uid[32]_t had to be replaced by __compat_uid[32]_t. compat_uptr_t had to be moved up before compat_siginfo_t in asm/compat.h on a several architectures (tile already had it moved up). compat_sigval_t had to be relocated from linux/compat.h to asm/compat.h. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> Cc: Oleg Nesterov <oleg@redhat.com> Cc: Amerigo Wang <amwang@redhat.com> Cc: "Jonathan M. Foote" <jmfoote@cert.org> Cc: Roland McGrath <roland@hack.frob.com> Cc: Pedro Alves <palves@redhat.com> Cc: Fengguang Wu <fengguang.wu@intel.com> Cc: Stephen Rothwell <sfr@canb.auug.org.au> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 19 changed files with 513 additions and 476 deletions Inline Diff
- arch/arm64/include/asm/compat.h
- arch/arm64/kernel/signal32.c
- arch/mips/include/asm/compat-signal.h
- arch/mips/include/asm/compat.h
- arch/parisc/include/asm/compat.h
- arch/parisc/kernel/signal32.h
- arch/powerpc/include/asm/compat.h
- arch/powerpc/include/asm/siginfo.h
- arch/powerpc/kernel/ppc32.h
- arch/s390/include/asm/compat.h
- arch/s390/kernel/compat_linux.h
- arch/sparc/include/asm/compat.h
- arch/sparc/include/asm/siginfo.h
- arch/sparc/kernel/signal32.c
- arch/tile/include/asm/compat.h
- arch/tile/kernel/compat_signal.c
- arch/x86/include/asm/compat.h
- arch/x86/include/asm/ia32.h
- include/linux/compat.h
arch/arm64/include/asm/compat.h
1 | /* | 1 | /* |
2 | * Copyright (C) 2012 ARM Ltd. | 2 | * Copyright (C) 2012 ARM Ltd. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify | 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 | 5 | * it under the terms of the GNU General Public License version 2 as |
6 | * published by the Free Software Foundation. | 6 | * published by the Free Software Foundation. |
7 | * | 7 | * |
8 | * This program is distributed in the hope that it will be useful, | 8 | * This program is distributed in the hope that it will be useful, |
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
11 | * GNU General Public License for more details. | 11 | * GNU General Public License for more details. |
12 | * | 12 | * |
13 | * You should have received a copy of the GNU General Public License | 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/>. | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
15 | */ | 15 | */ |
16 | #ifndef __ASM_COMPAT_H | 16 | #ifndef __ASM_COMPAT_H |
17 | #define __ASM_COMPAT_H | 17 | #define __ASM_COMPAT_H |
18 | #ifdef __KERNEL__ | 18 | #ifdef __KERNEL__ |
19 | #ifdef CONFIG_COMPAT | 19 | #ifdef CONFIG_COMPAT |
20 | 20 | ||
21 | /* | 21 | /* |
22 | * Architecture specific compatibility types | 22 | * Architecture specific compatibility types |
23 | */ | 23 | */ |
24 | #include <linux/types.h> | 24 | #include <linux/types.h> |
25 | #include <linux/sched.h> | 25 | #include <linux/sched.h> |
26 | 26 | ||
27 | #define COMPAT_USER_HZ 100 | 27 | #define COMPAT_USER_HZ 100 |
28 | #define COMPAT_UTS_MACHINE "armv8l\0\0" | 28 | #define COMPAT_UTS_MACHINE "armv8l\0\0" |
29 | 29 | ||
30 | typedef u32 compat_size_t; | 30 | typedef u32 compat_size_t; |
31 | typedef s32 compat_ssize_t; | 31 | typedef s32 compat_ssize_t; |
32 | typedef s32 compat_time_t; | 32 | typedef s32 compat_time_t; |
33 | typedef s32 compat_clock_t; | 33 | typedef s32 compat_clock_t; |
34 | typedef s32 compat_pid_t; | 34 | typedef s32 compat_pid_t; |
35 | typedef u32 __compat_uid_t; | 35 | typedef u32 __compat_uid_t; |
36 | typedef u32 __compat_gid_t; | 36 | typedef u32 __compat_gid_t; |
37 | typedef u32 __compat_uid32_t; | 37 | typedef u32 __compat_uid32_t; |
38 | typedef u32 __compat_gid32_t; | 38 | typedef u32 __compat_gid32_t; |
39 | typedef u32 compat_mode_t; | 39 | typedef u32 compat_mode_t; |
40 | typedef u32 compat_ino_t; | 40 | typedef u32 compat_ino_t; |
41 | typedef u32 compat_dev_t; | 41 | typedef u32 compat_dev_t; |
42 | typedef s32 compat_off_t; | 42 | typedef s32 compat_off_t; |
43 | typedef s64 compat_loff_t; | 43 | typedef s64 compat_loff_t; |
44 | typedef s16 compat_nlink_t; | 44 | typedef s16 compat_nlink_t; |
45 | typedef u16 compat_ipc_pid_t; | 45 | typedef u16 compat_ipc_pid_t; |
46 | typedef s32 compat_daddr_t; | 46 | typedef s32 compat_daddr_t; |
47 | typedef u32 compat_caddr_t; | 47 | typedef u32 compat_caddr_t; |
48 | typedef __kernel_fsid_t compat_fsid_t; | 48 | typedef __kernel_fsid_t compat_fsid_t; |
49 | typedef s32 compat_key_t; | 49 | typedef s32 compat_key_t; |
50 | typedef s32 compat_timer_t; | 50 | typedef s32 compat_timer_t; |
51 | 51 | ||
52 | typedef s32 compat_int_t; | 52 | typedef s32 compat_int_t; |
53 | typedef s32 compat_long_t; | 53 | typedef s32 compat_long_t; |
54 | typedef s64 compat_s64; | 54 | typedef s64 compat_s64; |
55 | typedef u32 compat_uint_t; | 55 | typedef u32 compat_uint_t; |
56 | typedef u32 compat_ulong_t; | 56 | typedef u32 compat_ulong_t; |
57 | typedef u64 compat_u64; | 57 | typedef u64 compat_u64; |
58 | typedef u32 compat_uptr_t; | ||
58 | 59 | ||
59 | struct compat_timespec { | 60 | struct compat_timespec { |
60 | compat_time_t tv_sec; | 61 | compat_time_t tv_sec; |
61 | s32 tv_nsec; | 62 | s32 tv_nsec; |
62 | }; | 63 | }; |
63 | 64 | ||
64 | struct compat_timeval { | 65 | struct compat_timeval { |
65 | compat_time_t tv_sec; | 66 | compat_time_t tv_sec; |
66 | s32 tv_usec; | 67 | s32 tv_usec; |
67 | }; | 68 | }; |
68 | 69 | ||
69 | struct compat_stat { | 70 | struct compat_stat { |
70 | compat_dev_t st_dev; | 71 | compat_dev_t st_dev; |
71 | compat_ino_t st_ino; | 72 | compat_ino_t st_ino; |
72 | compat_mode_t st_mode; | 73 | compat_mode_t st_mode; |
73 | compat_nlink_t st_nlink; | 74 | compat_nlink_t st_nlink; |
74 | __compat_uid32_t st_uid; | 75 | __compat_uid32_t st_uid; |
75 | __compat_gid32_t st_gid; | 76 | __compat_gid32_t st_gid; |
76 | compat_dev_t st_rdev; | 77 | compat_dev_t st_rdev; |
77 | compat_off_t st_size; | 78 | compat_off_t st_size; |
78 | compat_off_t st_blksize; | 79 | compat_off_t st_blksize; |
79 | compat_off_t st_blocks; | 80 | compat_off_t st_blocks; |
80 | compat_time_t st_atime; | 81 | compat_time_t st_atime; |
81 | u32 st_atime_nsec; | 82 | u32 st_atime_nsec; |
82 | compat_time_t st_mtime; | 83 | compat_time_t st_mtime; |
83 | u32 st_mtime_nsec; | 84 | u32 st_mtime_nsec; |
84 | compat_time_t st_ctime; | 85 | compat_time_t st_ctime; |
85 | u32 st_ctime_nsec; | 86 | u32 st_ctime_nsec; |
86 | u32 __unused4[2]; | 87 | u32 __unused4[2]; |
87 | }; | 88 | }; |
88 | 89 | ||
89 | struct compat_flock { | 90 | struct compat_flock { |
90 | short l_type; | 91 | short l_type; |
91 | short l_whence; | 92 | short l_whence; |
92 | compat_off_t l_start; | 93 | compat_off_t l_start; |
93 | compat_off_t l_len; | 94 | compat_off_t l_len; |
94 | compat_pid_t l_pid; | 95 | compat_pid_t l_pid; |
95 | }; | 96 | }; |
96 | 97 | ||
97 | #define F_GETLK64 12 /* using 'struct flock64' */ | 98 | #define F_GETLK64 12 /* using 'struct flock64' */ |
98 | #define F_SETLK64 13 | 99 | #define F_SETLK64 13 |
99 | #define F_SETLKW64 14 | 100 | #define F_SETLKW64 14 |
100 | 101 | ||
101 | struct compat_flock64 { | 102 | struct compat_flock64 { |
102 | short l_type; | 103 | short l_type; |
103 | short l_whence; | 104 | short l_whence; |
104 | compat_loff_t l_start; | 105 | compat_loff_t l_start; |
105 | compat_loff_t l_len; | 106 | compat_loff_t l_len; |
106 | compat_pid_t l_pid; | 107 | compat_pid_t l_pid; |
107 | }; | 108 | }; |
108 | 109 | ||
109 | struct compat_statfs { | 110 | struct compat_statfs { |
110 | int f_type; | 111 | int f_type; |
111 | int f_bsize; | 112 | int f_bsize; |
112 | int f_blocks; | 113 | int f_blocks; |
113 | int f_bfree; | 114 | int f_bfree; |
114 | int f_bavail; | 115 | int f_bavail; |
115 | int f_files; | 116 | int f_files; |
116 | int f_ffree; | 117 | int f_ffree; |
117 | compat_fsid_t f_fsid; | 118 | compat_fsid_t f_fsid; |
118 | int f_namelen; /* SunOS ignores this field. */ | 119 | int f_namelen; /* SunOS ignores this field. */ |
119 | int f_frsize; | 120 | int f_frsize; |
120 | int f_flags; | 121 | int f_flags; |
121 | int f_spare[4]; | 122 | int f_spare[4]; |
122 | }; | 123 | }; |
123 | 124 | ||
124 | #define COMPAT_RLIM_INFINITY 0xffffffff | 125 | #define COMPAT_RLIM_INFINITY 0xffffffff |
125 | 126 | ||
126 | typedef u32 compat_old_sigset_t; | 127 | typedef u32 compat_old_sigset_t; |
127 | 128 | ||
128 | #define _COMPAT_NSIG 64 | 129 | #define _COMPAT_NSIG 64 |
129 | #define _COMPAT_NSIG_BPW 32 | 130 | #define _COMPAT_NSIG_BPW 32 |
130 | 131 | ||
131 | typedef u32 compat_sigset_word; | 132 | typedef u32 compat_sigset_word; |
132 | 133 | ||
134 | typedef union compat_sigval { | ||
135 | compat_int_t sival_int; | ||
136 | compat_uptr_t sival_ptr; | ||
137 | } compat_sigval_t; | ||
138 | |||
139 | typedef struct compat_siginfo { | ||
140 | int si_signo; | ||
141 | int si_errno; | ||
142 | int si_code; | ||
143 | |||
144 | union { | ||
145 | /* The padding is the same size as AArch64. */ | ||
146 | int _pad[128/sizeof(int) - 3]; | ||
147 | |||
148 | /* kill() */ | ||
149 | struct { | ||
150 | compat_pid_t _pid; /* sender's pid */ | ||
151 | __compat_uid32_t _uid; /* sender's uid */ | ||
152 | } _kill; | ||
153 | |||
154 | /* POSIX.1b timers */ | ||
155 | struct { | ||
156 | compat_timer_t _tid; /* timer id */ | ||
157 | int _overrun; /* overrun count */ | ||
158 | compat_sigval_t _sigval; /* same as below */ | ||
159 | int _sys_private; /* not to be passed to user */ | ||
160 | } _timer; | ||
161 | |||
162 | /* POSIX.1b signals */ | ||
163 | struct { | ||
164 | compat_pid_t _pid; /* sender's pid */ | ||
165 | __compat_uid32_t _uid; /* sender's uid */ | ||
166 | compat_sigval_t _sigval; | ||
167 | } _rt; | ||
168 | |||
169 | /* SIGCHLD */ | ||
170 | struct { | ||
171 | compat_pid_t _pid; /* which child */ | ||
172 | __compat_uid32_t _uid; /* sender's uid */ | ||
173 | int _status; /* exit code */ | ||
174 | compat_clock_t _utime; | ||
175 | compat_clock_t _stime; | ||
176 | } _sigchld; | ||
177 | |||
178 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ | ||
179 | struct { | ||
180 | compat_uptr_t _addr; /* faulting insn/memory ref. */ | ||
181 | short _addr_lsb; /* LSB of the reported address */ | ||
182 | } _sigfault; | ||
183 | |||
184 | /* SIGPOLL */ | ||
185 | struct { | ||
186 | compat_long_t _band; /* POLL_IN, POLL_OUT, POLL_MSG */ | ||
187 | int _fd; | ||
188 | } _sigpoll; | ||
189 | } _sifields; | ||
190 | } compat_siginfo_t; | ||
191 | |||
133 | #define COMPAT_OFF_T_MAX 0x7fffffff | 192 | #define COMPAT_OFF_T_MAX 0x7fffffff |
134 | #define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL | 193 | #define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL |
135 | 194 | ||
136 | /* | 195 | /* |
137 | * A pointer passed in from user mode. This should not | 196 | * A pointer passed in from user mode. This should not |
138 | * be used for syscall parameters, just declare them | 197 | * be used for syscall parameters, just declare them |
139 | * as pointers because the syscall entry code will have | 198 | * as pointers because the syscall entry code will have |
140 | * appropriately converted them already. | 199 | * appropriately converted them already. |
141 | */ | 200 | */ |
142 | typedef u32 compat_uptr_t; | ||
143 | 201 | ||
144 | static inline void __user *compat_ptr(compat_uptr_t uptr) | 202 | static inline void __user *compat_ptr(compat_uptr_t uptr) |
145 | { | 203 | { |
146 | return (void __user *)(unsigned long)uptr; | 204 | return (void __user *)(unsigned long)uptr; |
147 | } | 205 | } |
148 | 206 | ||
149 | static inline compat_uptr_t ptr_to_compat(void __user *uptr) | 207 | static inline compat_uptr_t ptr_to_compat(void __user *uptr) |
150 | { | 208 | { |
151 | return (u32)(unsigned long)uptr; | 209 | return (u32)(unsigned long)uptr; |
152 | } | 210 | } |
153 | 211 | ||
154 | static inline void __user *arch_compat_alloc_user_space(long len) | 212 | static inline void __user *arch_compat_alloc_user_space(long len) |
155 | { | 213 | { |
156 | struct pt_regs *regs = task_pt_regs(current); | 214 | struct pt_regs *regs = task_pt_regs(current); |
157 | return (void __user *)regs->compat_sp - len; | 215 | return (void __user *)regs->compat_sp - len; |
158 | } | 216 | } |
159 | 217 | ||
160 | struct compat_ipc64_perm { | 218 | struct compat_ipc64_perm { |
161 | compat_key_t key; | 219 | compat_key_t key; |
162 | __compat_uid32_t uid; | 220 | __compat_uid32_t uid; |
163 | __compat_gid32_t gid; | 221 | __compat_gid32_t gid; |
164 | __compat_uid32_t cuid; | 222 | __compat_uid32_t cuid; |
165 | __compat_gid32_t cgid; | 223 | __compat_gid32_t cgid; |
166 | unsigned short mode; | 224 | unsigned short mode; |
167 | unsigned short __pad1; | 225 | unsigned short __pad1; |
168 | unsigned short seq; | 226 | unsigned short seq; |
169 | unsigned short __pad2; | 227 | unsigned short __pad2; |
170 | compat_ulong_t unused1; | 228 | compat_ulong_t unused1; |
171 | compat_ulong_t unused2; | 229 | compat_ulong_t unused2; |
172 | }; | 230 | }; |
173 | 231 | ||
174 | struct compat_semid64_ds { | 232 | struct compat_semid64_ds { |
175 | struct compat_ipc64_perm sem_perm; | 233 | struct compat_ipc64_perm sem_perm; |
176 | compat_time_t sem_otime; | 234 | compat_time_t sem_otime; |
177 | compat_ulong_t __unused1; | 235 | compat_ulong_t __unused1; |
178 | compat_time_t sem_ctime; | 236 | compat_time_t sem_ctime; |
179 | compat_ulong_t __unused2; | 237 | compat_ulong_t __unused2; |
180 | compat_ulong_t sem_nsems; | 238 | compat_ulong_t sem_nsems; |
181 | compat_ulong_t __unused3; | 239 | compat_ulong_t __unused3; |
182 | compat_ulong_t __unused4; | 240 | compat_ulong_t __unused4; |
183 | }; | 241 | }; |
184 | 242 | ||
185 | struct compat_msqid64_ds { | 243 | struct compat_msqid64_ds { |
186 | struct compat_ipc64_perm msg_perm; | 244 | struct compat_ipc64_perm msg_perm; |
187 | compat_time_t msg_stime; | 245 | compat_time_t msg_stime; |
188 | compat_ulong_t __unused1; | 246 | compat_ulong_t __unused1; |
189 | compat_time_t msg_rtime; | 247 | compat_time_t msg_rtime; |
190 | compat_ulong_t __unused2; | 248 | compat_ulong_t __unused2; |
191 | compat_time_t msg_ctime; | 249 | compat_time_t msg_ctime; |
192 | compat_ulong_t __unused3; | 250 | compat_ulong_t __unused3; |
193 | compat_ulong_t msg_cbytes; | 251 | compat_ulong_t msg_cbytes; |
194 | compat_ulong_t msg_qnum; | 252 | compat_ulong_t msg_qnum; |
195 | compat_ulong_t msg_qbytes; | 253 | compat_ulong_t msg_qbytes; |
196 | compat_pid_t msg_lspid; | 254 | compat_pid_t msg_lspid; |
197 | compat_pid_t msg_lrpid; | 255 | compat_pid_t msg_lrpid; |
198 | compat_ulong_t __unused4; | 256 | compat_ulong_t __unused4; |
199 | compat_ulong_t __unused5; | 257 | compat_ulong_t __unused5; |
200 | }; | 258 | }; |
201 | 259 | ||
202 | struct compat_shmid64_ds { | 260 | struct compat_shmid64_ds { |
203 | struct compat_ipc64_perm shm_perm; | 261 | struct compat_ipc64_perm shm_perm; |
204 | compat_size_t shm_segsz; | 262 | compat_size_t shm_segsz; |
205 | compat_time_t shm_atime; | 263 | compat_time_t shm_atime; |
206 | compat_ulong_t __unused1; | 264 | compat_ulong_t __unused1; |
207 | compat_time_t shm_dtime; | 265 | compat_time_t shm_dtime; |
208 | compat_ulong_t __unused2; | 266 | compat_ulong_t __unused2; |
209 | compat_time_t shm_ctime; | 267 | compat_time_t shm_ctime; |
210 | compat_ulong_t __unused3; | 268 | compat_ulong_t __unused3; |
211 | compat_pid_t shm_cpid; | 269 | compat_pid_t shm_cpid; |
212 | compat_pid_t shm_lpid; | 270 | compat_pid_t shm_lpid; |
213 | compat_ulong_t shm_nattch; | 271 | compat_ulong_t shm_nattch; |
214 | compat_ulong_t __unused4; | 272 | compat_ulong_t __unused4; |
215 | compat_ulong_t __unused5; | 273 | compat_ulong_t __unused5; |
216 | }; | 274 | }; |
217 | 275 | ||
218 | static inline int is_compat_task(void) | 276 | static inline int is_compat_task(void) |
219 | { | 277 | { |
220 | return test_thread_flag(TIF_32BIT); | 278 | return test_thread_flag(TIF_32BIT); |
221 | } | 279 | } |
222 | 280 | ||
223 | static inline int is_compat_thread(struct thread_info *thread) | 281 | static inline int is_compat_thread(struct thread_info *thread) |
224 | { | 282 | { |
225 | return test_ti_thread_flag(thread, TIF_32BIT); | 283 | return test_ti_thread_flag(thread, TIF_32BIT); |
226 | } | 284 | } |
227 | 285 | ||
228 | #else /* !CONFIG_COMPAT */ | 286 | #else /* !CONFIG_COMPAT */ |
229 | 287 | ||
230 | static inline int is_compat_task(void) | 288 | static inline int is_compat_task(void) |
231 | { | 289 | { |
232 | return 0; | 290 | return 0; |
233 | } | 291 | } |
234 | 292 | ||
235 | static inline int is_compat_thread(struct thread_info *thread) | 293 | static inline int is_compat_thread(struct thread_info *thread) |
236 | { | 294 | { |
237 | return 0; | 295 | return 0; |
238 | } | 296 | } |
239 | 297 | ||
240 | #endif /* CONFIG_COMPAT */ | 298 | #endif /* CONFIG_COMPAT */ |
241 | #endif /* __KERNEL__ */ | 299 | #endif /* __KERNEL__ */ |
242 | #endif /* __ASM_COMPAT_H */ | 300 | #endif /* __ASM_COMPAT_H */ |
arch/arm64/kernel/signal32.c
1 | /* | 1 | /* |
2 | * Based on arch/arm/kernel/signal.c | 2 | * Based on arch/arm/kernel/signal.c |
3 | * | 3 | * |
4 | * Copyright (C) 1995-2009 Russell King | 4 | * Copyright (C) 1995-2009 Russell King |
5 | * Copyright (C) 2012 ARM Ltd. | 5 | * Copyright (C) 2012 ARM Ltd. |
6 | * Modified by Will Deacon <will.deacon@arm.com> | 6 | * Modified by Will Deacon <will.deacon@arm.com> |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
11 | * | 11 | * |
12 | * This program is distributed in the hope that it will be useful, | 12 | * This program is distributed in the hope that it will be useful, |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | * GNU General Public License for more details. | 15 | * GNU General Public License for more details. |
16 | * | 16 | * |
17 | * You should have received a copy of the GNU General Public License | 17 | * You should have received a copy of the GNU General Public License |
18 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 18 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #define __SYSCALL_COMPAT | 21 | #define __SYSCALL_COMPAT |
22 | 22 | ||
23 | #include <linux/compat.h> | 23 | #include <linux/compat.h> |
24 | #include <linux/signal.h> | 24 | #include <linux/signal.h> |
25 | #include <linux/syscalls.h> | 25 | #include <linux/syscalls.h> |
26 | #include <linux/ratelimit.h> | 26 | #include <linux/ratelimit.h> |
27 | 27 | ||
28 | #include <asm/fpsimd.h> | 28 | #include <asm/fpsimd.h> |
29 | #include <asm/signal32.h> | 29 | #include <asm/signal32.h> |
30 | #include <asm/uaccess.h> | 30 | #include <asm/uaccess.h> |
31 | #include <asm/unistd.h> | 31 | #include <asm/unistd.h> |
32 | 32 | ||
33 | typedef struct compat_siginfo { | ||
34 | int si_signo; | ||
35 | int si_errno; | ||
36 | int si_code; | ||
37 | |||
38 | union { | ||
39 | /* The padding is the same size as AArch64. */ | ||
40 | int _pad[SI_PAD_SIZE]; | ||
41 | |||
42 | /* kill() */ | ||
43 | struct { | ||
44 | compat_pid_t _pid; /* sender's pid */ | ||
45 | __compat_uid32_t _uid; /* sender's uid */ | ||
46 | } _kill; | ||
47 | |||
48 | /* POSIX.1b timers */ | ||
49 | struct { | ||
50 | compat_timer_t _tid; /* timer id */ | ||
51 | int _overrun; /* overrun count */ | ||
52 | compat_sigval_t _sigval; /* same as below */ | ||
53 | int _sys_private; /* not to be passed to user */ | ||
54 | } _timer; | ||
55 | |||
56 | /* POSIX.1b signals */ | ||
57 | struct { | ||
58 | compat_pid_t _pid; /* sender's pid */ | ||
59 | __compat_uid32_t _uid; /* sender's uid */ | ||
60 | compat_sigval_t _sigval; | ||
61 | } _rt; | ||
62 | |||
63 | /* SIGCHLD */ | ||
64 | struct { | ||
65 | compat_pid_t _pid; /* which child */ | ||
66 | __compat_uid32_t _uid; /* sender's uid */ | ||
67 | int _status; /* exit code */ | ||
68 | compat_clock_t _utime; | ||
69 | compat_clock_t _stime; | ||
70 | } _sigchld; | ||
71 | |||
72 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ | ||
73 | struct { | ||
74 | compat_uptr_t _addr; /* faulting insn/memory ref. */ | ||
75 | short _addr_lsb; /* LSB of the reported address */ | ||
76 | } _sigfault; | ||
77 | |||
78 | /* SIGPOLL */ | ||
79 | struct { | ||
80 | compat_long_t _band; /* POLL_IN, POLL_OUT, POLL_MSG */ | ||
81 | int _fd; | ||
82 | } _sigpoll; | ||
83 | } _sifields; | ||
84 | } compat_siginfo_t; | ||
85 | |||
86 | struct compat_sigaction { | 33 | struct compat_sigaction { |
87 | compat_uptr_t sa_handler; | 34 | compat_uptr_t sa_handler; |
88 | compat_ulong_t sa_flags; | 35 | compat_ulong_t sa_flags; |
89 | compat_uptr_t sa_restorer; | 36 | compat_uptr_t sa_restorer; |
90 | compat_sigset_t sa_mask; | 37 | compat_sigset_t sa_mask; |
91 | }; | 38 | }; |
92 | 39 | ||
93 | struct compat_old_sigaction { | 40 | struct compat_old_sigaction { |
94 | compat_uptr_t sa_handler; | 41 | compat_uptr_t sa_handler; |
95 | compat_old_sigset_t sa_mask; | 42 | compat_old_sigset_t sa_mask; |
96 | compat_ulong_t sa_flags; | 43 | compat_ulong_t sa_flags; |
97 | compat_uptr_t sa_restorer; | 44 | compat_uptr_t sa_restorer; |
98 | }; | 45 | }; |
99 | 46 | ||
100 | typedef struct compat_sigaltstack { | 47 | typedef struct compat_sigaltstack { |
101 | compat_uptr_t ss_sp; | 48 | compat_uptr_t ss_sp; |
102 | int ss_flags; | 49 | int ss_flags; |
103 | compat_size_t ss_size; | 50 | compat_size_t ss_size; |
104 | } compat_stack_t; | 51 | } compat_stack_t; |
105 | 52 | ||
106 | struct compat_sigcontext { | 53 | struct compat_sigcontext { |
107 | /* We always set these two fields to 0 */ | 54 | /* We always set these two fields to 0 */ |
108 | compat_ulong_t trap_no; | 55 | compat_ulong_t trap_no; |
109 | compat_ulong_t error_code; | 56 | compat_ulong_t error_code; |
110 | 57 | ||
111 | compat_ulong_t oldmask; | 58 | compat_ulong_t oldmask; |
112 | compat_ulong_t arm_r0; | 59 | compat_ulong_t arm_r0; |
113 | compat_ulong_t arm_r1; | 60 | compat_ulong_t arm_r1; |
114 | compat_ulong_t arm_r2; | 61 | compat_ulong_t arm_r2; |
115 | compat_ulong_t arm_r3; | 62 | compat_ulong_t arm_r3; |
116 | compat_ulong_t arm_r4; | 63 | compat_ulong_t arm_r4; |
117 | compat_ulong_t arm_r5; | 64 | compat_ulong_t arm_r5; |
118 | compat_ulong_t arm_r6; | 65 | compat_ulong_t arm_r6; |
119 | compat_ulong_t arm_r7; | 66 | compat_ulong_t arm_r7; |
120 | compat_ulong_t arm_r8; | 67 | compat_ulong_t arm_r8; |
121 | compat_ulong_t arm_r9; | 68 | compat_ulong_t arm_r9; |
122 | compat_ulong_t arm_r10; | 69 | compat_ulong_t arm_r10; |
123 | compat_ulong_t arm_fp; | 70 | compat_ulong_t arm_fp; |
124 | compat_ulong_t arm_ip; | 71 | compat_ulong_t arm_ip; |
125 | compat_ulong_t arm_sp; | 72 | compat_ulong_t arm_sp; |
126 | compat_ulong_t arm_lr; | 73 | compat_ulong_t arm_lr; |
127 | compat_ulong_t arm_pc; | 74 | compat_ulong_t arm_pc; |
128 | compat_ulong_t arm_cpsr; | 75 | compat_ulong_t arm_cpsr; |
129 | compat_ulong_t fault_address; | 76 | compat_ulong_t fault_address; |
130 | }; | 77 | }; |
131 | 78 | ||
132 | struct compat_ucontext { | 79 | struct compat_ucontext { |
133 | compat_ulong_t uc_flags; | 80 | compat_ulong_t uc_flags; |
134 | struct compat_ucontext *uc_link; | 81 | struct compat_ucontext *uc_link; |
135 | compat_stack_t uc_stack; | 82 | compat_stack_t uc_stack; |
136 | struct compat_sigcontext uc_mcontext; | 83 | struct compat_sigcontext uc_mcontext; |
137 | compat_sigset_t uc_sigmask; | 84 | compat_sigset_t uc_sigmask; |
138 | int __unused[32 - (sizeof (compat_sigset_t) / sizeof (int))]; | 85 | int __unused[32 - (sizeof (compat_sigset_t) / sizeof (int))]; |
139 | compat_ulong_t uc_regspace[128] __attribute__((__aligned__(8))); | 86 | compat_ulong_t uc_regspace[128] __attribute__((__aligned__(8))); |
140 | }; | 87 | }; |
141 | 88 | ||
142 | struct compat_vfp_sigframe { | 89 | struct compat_vfp_sigframe { |
143 | compat_ulong_t magic; | 90 | compat_ulong_t magic; |
144 | compat_ulong_t size; | 91 | compat_ulong_t size; |
145 | struct compat_user_vfp { | 92 | struct compat_user_vfp { |
146 | compat_u64 fpregs[32]; | 93 | compat_u64 fpregs[32]; |
147 | compat_ulong_t fpscr; | 94 | compat_ulong_t fpscr; |
148 | } ufp; | 95 | } ufp; |
149 | struct compat_user_vfp_exc { | 96 | struct compat_user_vfp_exc { |
150 | compat_ulong_t fpexc; | 97 | compat_ulong_t fpexc; |
151 | compat_ulong_t fpinst; | 98 | compat_ulong_t fpinst; |
152 | compat_ulong_t fpinst2; | 99 | compat_ulong_t fpinst2; |
153 | } ufp_exc; | 100 | } ufp_exc; |
154 | } __attribute__((__aligned__(8))); | 101 | } __attribute__((__aligned__(8))); |
155 | 102 | ||
156 | #define VFP_MAGIC 0x56465001 | 103 | #define VFP_MAGIC 0x56465001 |
157 | #define VFP_STORAGE_SIZE sizeof(struct compat_vfp_sigframe) | 104 | #define VFP_STORAGE_SIZE sizeof(struct compat_vfp_sigframe) |
158 | 105 | ||
159 | struct compat_aux_sigframe { | 106 | struct compat_aux_sigframe { |
160 | struct compat_vfp_sigframe vfp; | 107 | struct compat_vfp_sigframe vfp; |
161 | 108 | ||
162 | /* Something that isn't a valid magic number for any coprocessor. */ | 109 | /* Something that isn't a valid magic number for any coprocessor. */ |
163 | unsigned long end_magic; | 110 | unsigned long end_magic; |
164 | } __attribute__((__aligned__(8))); | 111 | } __attribute__((__aligned__(8))); |
165 | 112 | ||
166 | struct compat_sigframe { | 113 | struct compat_sigframe { |
167 | struct compat_ucontext uc; | 114 | struct compat_ucontext uc; |
168 | compat_ulong_t retcode[2]; | 115 | compat_ulong_t retcode[2]; |
169 | }; | 116 | }; |
170 | 117 | ||
171 | struct compat_rt_sigframe { | 118 | struct compat_rt_sigframe { |
172 | struct compat_siginfo info; | 119 | struct compat_siginfo info; |
173 | struct compat_sigframe sig; | 120 | struct compat_sigframe sig; |
174 | }; | 121 | }; |
175 | 122 | ||
176 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) | 123 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) |
177 | 124 | ||
178 | /* | 125 | /* |
179 | * For ARM syscalls, the syscall number has to be loaded into r7. | 126 | * For ARM syscalls, the syscall number has to be loaded into r7. |
180 | * We do not support an OABI userspace. | 127 | * We do not support an OABI userspace. |
181 | */ | 128 | */ |
182 | #define MOV_R7_NR_SIGRETURN (0xe3a07000 | __NR_sigreturn) | 129 | #define MOV_R7_NR_SIGRETURN (0xe3a07000 | __NR_sigreturn) |
183 | #define SVC_SYS_SIGRETURN (0xef000000 | __NR_sigreturn) | 130 | #define SVC_SYS_SIGRETURN (0xef000000 | __NR_sigreturn) |
184 | #define MOV_R7_NR_RT_SIGRETURN (0xe3a07000 | __NR_rt_sigreturn) | 131 | #define MOV_R7_NR_RT_SIGRETURN (0xe3a07000 | __NR_rt_sigreturn) |
185 | #define SVC_SYS_RT_SIGRETURN (0xef000000 | __NR_rt_sigreturn) | 132 | #define SVC_SYS_RT_SIGRETURN (0xef000000 | __NR_rt_sigreturn) |
186 | 133 | ||
187 | /* | 134 | /* |
188 | * For Thumb syscalls, we also pass the syscall number via r7. We therefore | 135 | * For Thumb syscalls, we also pass the syscall number via r7. We therefore |
189 | * need two 16-bit instructions. | 136 | * need two 16-bit instructions. |
190 | */ | 137 | */ |
191 | #define SVC_THUMB_SIGRETURN (((0xdf00 | __NR_sigreturn) << 16) | \ | 138 | #define SVC_THUMB_SIGRETURN (((0xdf00 | __NR_sigreturn) << 16) | \ |
192 | 0x2700 | __NR_sigreturn) | 139 | 0x2700 | __NR_sigreturn) |
193 | #define SVC_THUMB_RT_SIGRETURN (((0xdf00 | __NR_rt_sigreturn) << 16) | \ | 140 | #define SVC_THUMB_RT_SIGRETURN (((0xdf00 | __NR_rt_sigreturn) << 16) | \ |
194 | 0x2700 | __NR_rt_sigreturn) | 141 | 0x2700 | __NR_rt_sigreturn) |
195 | 142 | ||
196 | const compat_ulong_t aarch32_sigret_code[6] = { | 143 | const compat_ulong_t aarch32_sigret_code[6] = { |
197 | /* | 144 | /* |
198 | * AArch32 sigreturn code. | 145 | * AArch32 sigreturn code. |
199 | * We don't construct an OABI SWI - instead we just set the imm24 field | 146 | * We don't construct an OABI SWI - instead we just set the imm24 field |
200 | * to the EABI syscall number so that we create a sane disassembly. | 147 | * to the EABI syscall number so that we create a sane disassembly. |
201 | */ | 148 | */ |
202 | MOV_R7_NR_SIGRETURN, SVC_SYS_SIGRETURN, SVC_THUMB_SIGRETURN, | 149 | MOV_R7_NR_SIGRETURN, SVC_SYS_SIGRETURN, SVC_THUMB_SIGRETURN, |
203 | MOV_R7_NR_RT_SIGRETURN, SVC_SYS_RT_SIGRETURN, SVC_THUMB_RT_SIGRETURN, | 150 | MOV_R7_NR_RT_SIGRETURN, SVC_SYS_RT_SIGRETURN, SVC_THUMB_RT_SIGRETURN, |
204 | }; | 151 | }; |
205 | 152 | ||
206 | static inline int put_sigset_t(compat_sigset_t __user *uset, sigset_t *set) | 153 | static inline int put_sigset_t(compat_sigset_t __user *uset, sigset_t *set) |
207 | { | 154 | { |
208 | compat_sigset_t cset; | 155 | compat_sigset_t cset; |
209 | 156 | ||
210 | cset.sig[0] = set->sig[0] & 0xffffffffull; | 157 | cset.sig[0] = set->sig[0] & 0xffffffffull; |
211 | cset.sig[1] = set->sig[0] >> 32; | 158 | cset.sig[1] = set->sig[0] >> 32; |
212 | 159 | ||
213 | return copy_to_user(uset, &cset, sizeof(*uset)); | 160 | return copy_to_user(uset, &cset, sizeof(*uset)); |
214 | } | 161 | } |
215 | 162 | ||
216 | static inline int get_sigset_t(sigset_t *set, | 163 | static inline int get_sigset_t(sigset_t *set, |
217 | const compat_sigset_t __user *uset) | 164 | const compat_sigset_t __user *uset) |
218 | { | 165 | { |
219 | compat_sigset_t s32; | 166 | compat_sigset_t s32; |
220 | 167 | ||
221 | if (copy_from_user(&s32, uset, sizeof(*uset))) | 168 | if (copy_from_user(&s32, uset, sizeof(*uset))) |
222 | return -EFAULT; | 169 | return -EFAULT; |
223 | 170 | ||
224 | set->sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32); | 171 | set->sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32); |
225 | return 0; | 172 | return 0; |
226 | } | 173 | } |
227 | 174 | ||
228 | int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from) | 175 | int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from) |
229 | { | 176 | { |
230 | int err; | 177 | int err; |
231 | 178 | ||
232 | if (!access_ok(VERIFY_WRITE, to, sizeof(*to))) | 179 | if (!access_ok(VERIFY_WRITE, to, sizeof(*to))) |
233 | return -EFAULT; | 180 | return -EFAULT; |
234 | 181 | ||
235 | /* If you change siginfo_t structure, please be sure | 182 | /* If you change siginfo_t structure, please be sure |
236 | * this code is fixed accordingly. | 183 | * this code is fixed accordingly. |
237 | * It should never copy any pad contained in the structure | 184 | * It should never copy any pad contained in the structure |
238 | * to avoid security leaks, but must copy the generic | 185 | * to avoid security leaks, but must copy the generic |
239 | * 3 ints plus the relevant union member. | 186 | * 3 ints plus the relevant union member. |
240 | * This routine must convert siginfo from 64bit to 32bit as well | 187 | * This routine must convert siginfo from 64bit to 32bit as well |
241 | * at the same time. | 188 | * at the same time. |
242 | */ | 189 | */ |
243 | err = __put_user(from->si_signo, &to->si_signo); | 190 | err = __put_user(from->si_signo, &to->si_signo); |
244 | err |= __put_user(from->si_errno, &to->si_errno); | 191 | err |= __put_user(from->si_errno, &to->si_errno); |
245 | err |= __put_user((short)from->si_code, &to->si_code); | 192 | err |= __put_user((short)from->si_code, &to->si_code); |
246 | if (from->si_code < 0) | 193 | if (from->si_code < 0) |
247 | err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, | 194 | err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, |
248 | SI_PAD_SIZE); | 195 | SI_PAD_SIZE); |
249 | else switch (from->si_code & __SI_MASK) { | 196 | else switch (from->si_code & __SI_MASK) { |
250 | case __SI_KILL: | 197 | case __SI_KILL: |
251 | err |= __put_user(from->si_pid, &to->si_pid); | 198 | err |= __put_user(from->si_pid, &to->si_pid); |
252 | err |= __put_user(from->si_uid, &to->si_uid); | 199 | err |= __put_user(from->si_uid, &to->si_uid); |
253 | break; | 200 | break; |
254 | case __SI_TIMER: | 201 | case __SI_TIMER: |
255 | err |= __put_user(from->si_tid, &to->si_tid); | 202 | err |= __put_user(from->si_tid, &to->si_tid); |
256 | err |= __put_user(from->si_overrun, &to->si_overrun); | 203 | err |= __put_user(from->si_overrun, &to->si_overrun); |
257 | err |= __put_user((compat_uptr_t)(unsigned long)from->si_ptr, | 204 | err |= __put_user((compat_uptr_t)(unsigned long)from->si_ptr, |
258 | &to->si_ptr); | 205 | &to->si_ptr); |
259 | break; | 206 | break; |
260 | case __SI_POLL: | 207 | case __SI_POLL: |
261 | err |= __put_user(from->si_band, &to->si_band); | 208 | err |= __put_user(from->si_band, &to->si_band); |
262 | err |= __put_user(from->si_fd, &to->si_fd); | 209 | err |= __put_user(from->si_fd, &to->si_fd); |
263 | break; | 210 | break; |
264 | case __SI_FAULT: | 211 | case __SI_FAULT: |
265 | err |= __put_user((compat_uptr_t)(unsigned long)from->si_addr, | 212 | err |= __put_user((compat_uptr_t)(unsigned long)from->si_addr, |
266 | &to->si_addr); | 213 | &to->si_addr); |
267 | #ifdef BUS_MCEERR_AO | 214 | #ifdef BUS_MCEERR_AO |
268 | /* | 215 | /* |
269 | * Other callers might not initialize the si_lsb field, | 216 | * Other callers might not initialize the si_lsb field, |
270 | * so check explicitely for the right codes here. | 217 | * so check explicitely for the right codes here. |
271 | */ | 218 | */ |
272 | if (from->si_code == BUS_MCEERR_AR || from->si_code == BUS_MCEERR_AO) | 219 | if (from->si_code == BUS_MCEERR_AR || from->si_code == BUS_MCEERR_AO) |
273 | err |= __put_user(from->si_addr_lsb, &to->si_addr_lsb); | 220 | err |= __put_user(from->si_addr_lsb, &to->si_addr_lsb); |
274 | #endif | 221 | #endif |
275 | break; | 222 | break; |
276 | case __SI_CHLD: | 223 | case __SI_CHLD: |
277 | err |= __put_user(from->si_pid, &to->si_pid); | 224 | err |= __put_user(from->si_pid, &to->si_pid); |
278 | err |= __put_user(from->si_uid, &to->si_uid); | 225 | err |= __put_user(from->si_uid, &to->si_uid); |
279 | err |= __put_user(from->si_status, &to->si_status); | 226 | err |= __put_user(from->si_status, &to->si_status); |
280 | err |= __put_user(from->si_utime, &to->si_utime); | 227 | err |= __put_user(from->si_utime, &to->si_utime); |
281 | err |= __put_user(from->si_stime, &to->si_stime); | 228 | err |= __put_user(from->si_stime, &to->si_stime); |
282 | break; | 229 | break; |
283 | case __SI_RT: /* This is not generated by the kernel as of now. */ | 230 | case __SI_RT: /* This is not generated by the kernel as of now. */ |
284 | case __SI_MESGQ: /* But this is */ | 231 | case __SI_MESGQ: /* But this is */ |
285 | err |= __put_user(from->si_pid, &to->si_pid); | 232 | err |= __put_user(from->si_pid, &to->si_pid); |
286 | err |= __put_user(from->si_uid, &to->si_uid); | 233 | err |= __put_user(from->si_uid, &to->si_uid); |
287 | err |= __put_user((compat_uptr_t)(unsigned long)from->si_ptr, &to->si_ptr); | 234 | err |= __put_user((compat_uptr_t)(unsigned long)from->si_ptr, &to->si_ptr); |
288 | break; | 235 | break; |
289 | default: /* this is just in case for now ... */ | 236 | default: /* this is just in case for now ... */ |
290 | err |= __put_user(from->si_pid, &to->si_pid); | 237 | err |= __put_user(from->si_pid, &to->si_pid); |
291 | err |= __put_user(from->si_uid, &to->si_uid); | 238 | err |= __put_user(from->si_uid, &to->si_uid); |
292 | break; | 239 | break; |
293 | } | 240 | } |
294 | return err; | 241 | return err; |
295 | } | 242 | } |
296 | 243 | ||
297 | int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from) | 244 | int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from) |
298 | { | 245 | { |
299 | memset(to, 0, sizeof *to); | 246 | memset(to, 0, sizeof *to); |
300 | 247 | ||
301 | if (copy_from_user(to, from, __ARCH_SI_PREAMBLE_SIZE) || | 248 | if (copy_from_user(to, from, __ARCH_SI_PREAMBLE_SIZE) || |
302 | copy_from_user(to->_sifields._pad, | 249 | copy_from_user(to->_sifields._pad, |
303 | from->_sifields._pad, SI_PAD_SIZE)) | 250 | from->_sifields._pad, SI_PAD_SIZE)) |
304 | return -EFAULT; | 251 | return -EFAULT; |
305 | 252 | ||
306 | return 0; | 253 | return 0; |
307 | } | 254 | } |
308 | 255 | ||
309 | /* | 256 | /* |
310 | * VFP save/restore code. | 257 | * VFP save/restore code. |
311 | */ | 258 | */ |
312 | static int compat_preserve_vfp_context(struct compat_vfp_sigframe __user *frame) | 259 | static int compat_preserve_vfp_context(struct compat_vfp_sigframe __user *frame) |
313 | { | 260 | { |
314 | struct fpsimd_state *fpsimd = ¤t->thread.fpsimd_state; | 261 | struct fpsimd_state *fpsimd = ¤t->thread.fpsimd_state; |
315 | compat_ulong_t magic = VFP_MAGIC; | 262 | compat_ulong_t magic = VFP_MAGIC; |
316 | compat_ulong_t size = VFP_STORAGE_SIZE; | 263 | compat_ulong_t size = VFP_STORAGE_SIZE; |
317 | compat_ulong_t fpscr, fpexc; | 264 | compat_ulong_t fpscr, fpexc; |
318 | int err = 0; | 265 | int err = 0; |
319 | 266 | ||
320 | /* | 267 | /* |
321 | * Save the hardware registers to the fpsimd_state structure. | 268 | * Save the hardware registers to the fpsimd_state structure. |
322 | * Note that this also saves V16-31, which aren't visible | 269 | * Note that this also saves V16-31, which aren't visible |
323 | * in AArch32. | 270 | * in AArch32. |
324 | */ | 271 | */ |
325 | fpsimd_save_state(fpsimd); | 272 | fpsimd_save_state(fpsimd); |
326 | 273 | ||
327 | /* Place structure header on the stack */ | 274 | /* Place structure header on the stack */ |
328 | __put_user_error(magic, &frame->magic, err); | 275 | __put_user_error(magic, &frame->magic, err); |
329 | __put_user_error(size, &frame->size, err); | 276 | __put_user_error(size, &frame->size, err); |
330 | 277 | ||
331 | /* | 278 | /* |
332 | * Now copy the FP registers. Since the registers are packed, | 279 | * Now copy the FP registers. Since the registers are packed, |
333 | * we can copy the prefix we want (V0-V15) as it is. | 280 | * we can copy the prefix we want (V0-V15) as it is. |
334 | * FIXME: Won't work if big endian. | 281 | * FIXME: Won't work if big endian. |
335 | */ | 282 | */ |
336 | err |= __copy_to_user(&frame->ufp.fpregs, fpsimd->vregs, | 283 | err |= __copy_to_user(&frame->ufp.fpregs, fpsimd->vregs, |
337 | sizeof(frame->ufp.fpregs)); | 284 | sizeof(frame->ufp.fpregs)); |
338 | 285 | ||
339 | /* Create an AArch32 fpscr from the fpsr and the fpcr. */ | 286 | /* Create an AArch32 fpscr from the fpsr and the fpcr. */ |
340 | fpscr = (fpsimd->fpsr & VFP_FPSCR_STAT_MASK) | | 287 | fpscr = (fpsimd->fpsr & VFP_FPSCR_STAT_MASK) | |
341 | (fpsimd->fpcr & VFP_FPSCR_CTRL_MASK); | 288 | (fpsimd->fpcr & VFP_FPSCR_CTRL_MASK); |
342 | __put_user_error(fpscr, &frame->ufp.fpscr, err); | 289 | __put_user_error(fpscr, &frame->ufp.fpscr, err); |
343 | 290 | ||
344 | /* | 291 | /* |
345 | * The exception register aren't available so we fake up a | 292 | * The exception register aren't available so we fake up a |
346 | * basic FPEXC and zero everything else. | 293 | * basic FPEXC and zero everything else. |
347 | */ | 294 | */ |
348 | fpexc = (1 << 30); | 295 | fpexc = (1 << 30); |
349 | __put_user_error(fpexc, &frame->ufp_exc.fpexc, err); | 296 | __put_user_error(fpexc, &frame->ufp_exc.fpexc, err); |
350 | __put_user_error(0, &frame->ufp_exc.fpinst, err); | 297 | __put_user_error(0, &frame->ufp_exc.fpinst, err); |
351 | __put_user_error(0, &frame->ufp_exc.fpinst2, err); | 298 | __put_user_error(0, &frame->ufp_exc.fpinst2, err); |
352 | 299 | ||
353 | return err ? -EFAULT : 0; | 300 | return err ? -EFAULT : 0; |
354 | } | 301 | } |
355 | 302 | ||
356 | static int compat_restore_vfp_context(struct compat_vfp_sigframe __user *frame) | 303 | static int compat_restore_vfp_context(struct compat_vfp_sigframe __user *frame) |
357 | { | 304 | { |
358 | struct fpsimd_state fpsimd; | 305 | struct fpsimd_state fpsimd; |
359 | compat_ulong_t magic = VFP_MAGIC; | 306 | compat_ulong_t magic = VFP_MAGIC; |
360 | compat_ulong_t size = VFP_STORAGE_SIZE; | 307 | compat_ulong_t size = VFP_STORAGE_SIZE; |
361 | compat_ulong_t fpscr; | 308 | compat_ulong_t fpscr; |
362 | int err = 0; | 309 | int err = 0; |
363 | 310 | ||
364 | __get_user_error(magic, &frame->magic, err); | 311 | __get_user_error(magic, &frame->magic, err); |
365 | __get_user_error(size, &frame->size, err); | 312 | __get_user_error(size, &frame->size, err); |
366 | 313 | ||
367 | if (err) | 314 | if (err) |
368 | return -EFAULT; | 315 | return -EFAULT; |
369 | if (magic != VFP_MAGIC || size != VFP_STORAGE_SIZE) | 316 | if (magic != VFP_MAGIC || size != VFP_STORAGE_SIZE) |
370 | return -EINVAL; | 317 | return -EINVAL; |
371 | 318 | ||
372 | /* | 319 | /* |
373 | * Copy the FP registers into the start of the fpsimd_state. | 320 | * Copy the FP registers into the start of the fpsimd_state. |
374 | * FIXME: Won't work if big endian. | 321 | * FIXME: Won't work if big endian. |
375 | */ | 322 | */ |
376 | err |= __copy_from_user(fpsimd.vregs, frame->ufp.fpregs, | 323 | err |= __copy_from_user(fpsimd.vregs, frame->ufp.fpregs, |
377 | sizeof(frame->ufp.fpregs)); | 324 | sizeof(frame->ufp.fpregs)); |
378 | 325 | ||
379 | /* Extract the fpsr and the fpcr from the fpscr */ | 326 | /* Extract the fpsr and the fpcr from the fpscr */ |
380 | __get_user_error(fpscr, &frame->ufp.fpscr, err); | 327 | __get_user_error(fpscr, &frame->ufp.fpscr, err); |
381 | fpsimd.fpsr = fpscr & VFP_FPSCR_STAT_MASK; | 328 | fpsimd.fpsr = fpscr & VFP_FPSCR_STAT_MASK; |
382 | fpsimd.fpcr = fpscr & VFP_FPSCR_CTRL_MASK; | 329 | fpsimd.fpcr = fpscr & VFP_FPSCR_CTRL_MASK; |
383 | 330 | ||
384 | /* | 331 | /* |
385 | * We don't need to touch the exception register, so | 332 | * We don't need to touch the exception register, so |
386 | * reload the hardware state. | 333 | * reload the hardware state. |
387 | */ | 334 | */ |
388 | if (!err) { | 335 | if (!err) { |
389 | preempt_disable(); | 336 | preempt_disable(); |
390 | fpsimd_load_state(&fpsimd); | 337 | fpsimd_load_state(&fpsimd); |
391 | preempt_enable(); | 338 | preempt_enable(); |
392 | } | 339 | } |
393 | 340 | ||
394 | return err ? -EFAULT : 0; | 341 | return err ? -EFAULT : 0; |
395 | } | 342 | } |
396 | 343 | ||
397 | /* | 344 | /* |
398 | * atomically swap in the new signal mask, and wait for a signal. | 345 | * atomically swap in the new signal mask, and wait for a signal. |
399 | */ | 346 | */ |
400 | asmlinkage int compat_sys_sigsuspend(int restart, compat_ulong_t oldmask, | 347 | asmlinkage int compat_sys_sigsuspend(int restart, compat_ulong_t oldmask, |
401 | compat_old_sigset_t mask) | 348 | compat_old_sigset_t mask) |
402 | { | 349 | { |
403 | sigset_t blocked; | 350 | sigset_t blocked; |
404 | 351 | ||
405 | siginitset(¤t->blocked, mask); | 352 | siginitset(¤t->blocked, mask); |
406 | return sigsuspend(&blocked); | 353 | return sigsuspend(&blocked); |
407 | } | 354 | } |
408 | 355 | ||
409 | asmlinkage int compat_sys_sigaction(int sig, | 356 | asmlinkage int compat_sys_sigaction(int sig, |
410 | const struct compat_old_sigaction __user *act, | 357 | const struct compat_old_sigaction __user *act, |
411 | struct compat_old_sigaction __user *oact) | 358 | struct compat_old_sigaction __user *oact) |
412 | { | 359 | { |
413 | struct k_sigaction new_ka, old_ka; | 360 | struct k_sigaction new_ka, old_ka; |
414 | int ret; | 361 | int ret; |
415 | compat_old_sigset_t mask; | 362 | compat_old_sigset_t mask; |
416 | compat_uptr_t handler, restorer; | 363 | compat_uptr_t handler, restorer; |
417 | 364 | ||
418 | if (act) { | 365 | if (act) { |
419 | if (!access_ok(VERIFY_READ, act, sizeof(*act)) || | 366 | if (!access_ok(VERIFY_READ, act, sizeof(*act)) || |
420 | __get_user(handler, &act->sa_handler) || | 367 | __get_user(handler, &act->sa_handler) || |
421 | __get_user(restorer, &act->sa_restorer) || | 368 | __get_user(restorer, &act->sa_restorer) || |
422 | __get_user(new_ka.sa.sa_flags, &act->sa_flags) || | 369 | __get_user(new_ka.sa.sa_flags, &act->sa_flags) || |
423 | __get_user(mask, &act->sa_mask)) | 370 | __get_user(mask, &act->sa_mask)) |
424 | return -EFAULT; | 371 | return -EFAULT; |
425 | 372 | ||
426 | new_ka.sa.sa_handler = compat_ptr(handler); | 373 | new_ka.sa.sa_handler = compat_ptr(handler); |
427 | new_ka.sa.sa_restorer = compat_ptr(restorer); | 374 | new_ka.sa.sa_restorer = compat_ptr(restorer); |
428 | siginitset(&new_ka.sa.sa_mask, mask); | 375 | siginitset(&new_ka.sa.sa_mask, mask); |
429 | } | 376 | } |
430 | 377 | ||
431 | ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); | 378 | ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); |
432 | 379 | ||
433 | if (!ret && oact) { | 380 | if (!ret && oact) { |
434 | if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || | 381 | if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || |
435 | __put_user(ptr_to_compat(old_ka.sa.sa_handler), | 382 | __put_user(ptr_to_compat(old_ka.sa.sa_handler), |
436 | &oact->sa_handler) || | 383 | &oact->sa_handler) || |
437 | __put_user(ptr_to_compat(old_ka.sa.sa_restorer), | 384 | __put_user(ptr_to_compat(old_ka.sa.sa_restorer), |
438 | &oact->sa_restorer) || | 385 | &oact->sa_restorer) || |
439 | __put_user(old_ka.sa.sa_flags, &oact->sa_flags) || | 386 | __put_user(old_ka.sa.sa_flags, &oact->sa_flags) || |
440 | __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask)) | 387 | __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask)) |
441 | return -EFAULT; | 388 | return -EFAULT; |
442 | } | 389 | } |
443 | 390 | ||
444 | return ret; | 391 | return ret; |
445 | } | 392 | } |
446 | 393 | ||
447 | asmlinkage int compat_sys_rt_sigaction(int sig, | 394 | asmlinkage int compat_sys_rt_sigaction(int sig, |
448 | const struct compat_sigaction __user *act, | 395 | const struct compat_sigaction __user *act, |
449 | struct compat_sigaction __user *oact, | 396 | struct compat_sigaction __user *oact, |
450 | compat_size_t sigsetsize) | 397 | compat_size_t sigsetsize) |
451 | { | 398 | { |
452 | struct k_sigaction new_ka, old_ka; | 399 | struct k_sigaction new_ka, old_ka; |
453 | int ret; | 400 | int ret; |
454 | 401 | ||
455 | /* XXX: Don't preclude handling different sized sigset_t's. */ | 402 | /* XXX: Don't preclude handling different sized sigset_t's. */ |
456 | if (sigsetsize != sizeof(compat_sigset_t)) | 403 | if (sigsetsize != sizeof(compat_sigset_t)) |
457 | return -EINVAL; | 404 | return -EINVAL; |
458 | 405 | ||
459 | if (act) { | 406 | if (act) { |
460 | compat_uptr_t handler, restorer; | 407 | compat_uptr_t handler, restorer; |
461 | 408 | ||
462 | ret = get_user(handler, &act->sa_handler); | 409 | ret = get_user(handler, &act->sa_handler); |
463 | new_ka.sa.sa_handler = compat_ptr(handler); | 410 | new_ka.sa.sa_handler = compat_ptr(handler); |
464 | ret |= get_user(restorer, &act->sa_restorer); | 411 | ret |= get_user(restorer, &act->sa_restorer); |
465 | new_ka.sa.sa_restorer = compat_ptr(restorer); | 412 | new_ka.sa.sa_restorer = compat_ptr(restorer); |
466 | ret |= get_sigset_t(&new_ka.sa.sa_mask, &act->sa_mask); | 413 | ret |= get_sigset_t(&new_ka.sa.sa_mask, &act->sa_mask); |
467 | ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags); | 414 | ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags); |
468 | if (ret) | 415 | if (ret) |
469 | return -EFAULT; | 416 | return -EFAULT; |
470 | } | 417 | } |
471 | 418 | ||
472 | ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); | 419 | ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); |
473 | if (!ret && oact) { | 420 | if (!ret && oact) { |
474 | ret = put_user(ptr_to_compat(old_ka.sa.sa_handler), &oact->sa_handler); | 421 | ret = put_user(ptr_to_compat(old_ka.sa.sa_handler), &oact->sa_handler); |
475 | ret |= put_sigset_t(&oact->sa_mask, &old_ka.sa.sa_mask); | 422 | ret |= put_sigset_t(&oact->sa_mask, &old_ka.sa.sa_mask); |
476 | ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags); | 423 | ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags); |
477 | } | 424 | } |
478 | return ret; | 425 | return ret; |
479 | } | 426 | } |
480 | 427 | ||
481 | int compat_do_sigaltstack(compat_uptr_t compat_uss, compat_uptr_t compat_uoss, | 428 | int compat_do_sigaltstack(compat_uptr_t compat_uss, compat_uptr_t compat_uoss, |
482 | compat_ulong_t sp) | 429 | compat_ulong_t sp) |
483 | { | 430 | { |
484 | compat_stack_t __user *newstack = compat_ptr(compat_uss); | 431 | compat_stack_t __user *newstack = compat_ptr(compat_uss); |
485 | compat_stack_t __user *oldstack = compat_ptr(compat_uoss); | 432 | compat_stack_t __user *oldstack = compat_ptr(compat_uoss); |
486 | compat_uptr_t ss_sp; | 433 | compat_uptr_t ss_sp; |
487 | int ret; | 434 | int ret; |
488 | mm_segment_t old_fs; | 435 | mm_segment_t old_fs; |
489 | stack_t uss, uoss; | 436 | stack_t uss, uoss; |
490 | 437 | ||
491 | /* Marshall the compat new stack into a stack_t */ | 438 | /* Marshall the compat new stack into a stack_t */ |
492 | if (newstack) { | 439 | if (newstack) { |
493 | if (get_user(ss_sp, &newstack->ss_sp) || | 440 | if (get_user(ss_sp, &newstack->ss_sp) || |
494 | __get_user(uss.ss_flags, &newstack->ss_flags) || | 441 | __get_user(uss.ss_flags, &newstack->ss_flags) || |
495 | __get_user(uss.ss_size, &newstack->ss_size)) | 442 | __get_user(uss.ss_size, &newstack->ss_size)) |
496 | return -EFAULT; | 443 | return -EFAULT; |
497 | uss.ss_sp = compat_ptr(ss_sp); | 444 | uss.ss_sp = compat_ptr(ss_sp); |
498 | } | 445 | } |
499 | 446 | ||
500 | old_fs = get_fs(); | 447 | old_fs = get_fs(); |
501 | set_fs(KERNEL_DS); | 448 | set_fs(KERNEL_DS); |
502 | /* The __user pointer casts are valid because of the set_fs() */ | 449 | /* The __user pointer casts are valid because of the set_fs() */ |
503 | ret = do_sigaltstack( | 450 | ret = do_sigaltstack( |
504 | newstack ? (stack_t __user *) &uss : NULL, | 451 | newstack ? (stack_t __user *) &uss : NULL, |
505 | oldstack ? (stack_t __user *) &uoss : NULL, | 452 | oldstack ? (stack_t __user *) &uoss : NULL, |
506 | (unsigned long)sp); | 453 | (unsigned long)sp); |
507 | set_fs(old_fs); | 454 | set_fs(old_fs); |
508 | 455 | ||
509 | /* Convert the old stack_t into a compat stack. */ | 456 | /* Convert the old stack_t into a compat stack. */ |
510 | if (!ret && oldstack && | 457 | if (!ret && oldstack && |
511 | (put_user(ptr_to_compat(uoss.ss_sp), &oldstack->ss_sp) || | 458 | (put_user(ptr_to_compat(uoss.ss_sp), &oldstack->ss_sp) || |
512 | __put_user(uoss.ss_flags, &oldstack->ss_flags) || | 459 | __put_user(uoss.ss_flags, &oldstack->ss_flags) || |
513 | __put_user(uoss.ss_size, &oldstack->ss_size))) | 460 | __put_user(uoss.ss_size, &oldstack->ss_size))) |
514 | return -EFAULT; | 461 | return -EFAULT; |
515 | return ret; | 462 | return ret; |
516 | } | 463 | } |
517 | 464 | ||
518 | static int compat_restore_sigframe(struct pt_regs *regs, | 465 | static int compat_restore_sigframe(struct pt_regs *regs, |
519 | struct compat_sigframe __user *sf) | 466 | struct compat_sigframe __user *sf) |
520 | { | 467 | { |
521 | int err; | 468 | int err; |
522 | sigset_t set; | 469 | sigset_t set; |
523 | struct compat_aux_sigframe __user *aux; | 470 | struct compat_aux_sigframe __user *aux; |
524 | 471 | ||
525 | err = get_sigset_t(&set, &sf->uc.uc_sigmask); | 472 | err = get_sigset_t(&set, &sf->uc.uc_sigmask); |
526 | if (err == 0) { | 473 | if (err == 0) { |
527 | sigdelsetmask(&set, ~_BLOCKABLE); | 474 | sigdelsetmask(&set, ~_BLOCKABLE); |
528 | set_current_blocked(&set); | 475 | set_current_blocked(&set); |
529 | } | 476 | } |
530 | 477 | ||
531 | __get_user_error(regs->regs[0], &sf->uc.uc_mcontext.arm_r0, err); | 478 | __get_user_error(regs->regs[0], &sf->uc.uc_mcontext.arm_r0, err); |
532 | __get_user_error(regs->regs[1], &sf->uc.uc_mcontext.arm_r1, err); | 479 | __get_user_error(regs->regs[1], &sf->uc.uc_mcontext.arm_r1, err); |
533 | __get_user_error(regs->regs[2], &sf->uc.uc_mcontext.arm_r2, err); | 480 | __get_user_error(regs->regs[2], &sf->uc.uc_mcontext.arm_r2, err); |
534 | __get_user_error(regs->regs[3], &sf->uc.uc_mcontext.arm_r3, err); | 481 | __get_user_error(regs->regs[3], &sf->uc.uc_mcontext.arm_r3, err); |
535 | __get_user_error(regs->regs[4], &sf->uc.uc_mcontext.arm_r4, err); | 482 | __get_user_error(regs->regs[4], &sf->uc.uc_mcontext.arm_r4, err); |
536 | __get_user_error(regs->regs[5], &sf->uc.uc_mcontext.arm_r5, err); | 483 | __get_user_error(regs->regs[5], &sf->uc.uc_mcontext.arm_r5, err); |
537 | __get_user_error(regs->regs[6], &sf->uc.uc_mcontext.arm_r6, err); | 484 | __get_user_error(regs->regs[6], &sf->uc.uc_mcontext.arm_r6, err); |
538 | __get_user_error(regs->regs[7], &sf->uc.uc_mcontext.arm_r7, err); | 485 | __get_user_error(regs->regs[7], &sf->uc.uc_mcontext.arm_r7, err); |
539 | __get_user_error(regs->regs[8], &sf->uc.uc_mcontext.arm_r8, err); | 486 | __get_user_error(regs->regs[8], &sf->uc.uc_mcontext.arm_r8, err); |
540 | __get_user_error(regs->regs[9], &sf->uc.uc_mcontext.arm_r9, err); | 487 | __get_user_error(regs->regs[9], &sf->uc.uc_mcontext.arm_r9, err); |
541 | __get_user_error(regs->regs[10], &sf->uc.uc_mcontext.arm_r10, err); | 488 | __get_user_error(regs->regs[10], &sf->uc.uc_mcontext.arm_r10, err); |
542 | __get_user_error(regs->regs[11], &sf->uc.uc_mcontext.arm_fp, err); | 489 | __get_user_error(regs->regs[11], &sf->uc.uc_mcontext.arm_fp, err); |
543 | __get_user_error(regs->regs[12], &sf->uc.uc_mcontext.arm_ip, err); | 490 | __get_user_error(regs->regs[12], &sf->uc.uc_mcontext.arm_ip, err); |
544 | __get_user_error(regs->compat_sp, &sf->uc.uc_mcontext.arm_sp, err); | 491 | __get_user_error(regs->compat_sp, &sf->uc.uc_mcontext.arm_sp, err); |
545 | __get_user_error(regs->compat_lr, &sf->uc.uc_mcontext.arm_lr, err); | 492 | __get_user_error(regs->compat_lr, &sf->uc.uc_mcontext.arm_lr, err); |
546 | __get_user_error(regs->pc, &sf->uc.uc_mcontext.arm_pc, err); | 493 | __get_user_error(regs->pc, &sf->uc.uc_mcontext.arm_pc, err); |
547 | __get_user_error(regs->pstate, &sf->uc.uc_mcontext.arm_cpsr, err); | 494 | __get_user_error(regs->pstate, &sf->uc.uc_mcontext.arm_cpsr, err); |
548 | 495 | ||
549 | /* | 496 | /* |
550 | * Avoid compat_sys_sigreturn() restarting. | 497 | * Avoid compat_sys_sigreturn() restarting. |
551 | */ | 498 | */ |
552 | regs->syscallno = ~0UL; | 499 | regs->syscallno = ~0UL; |
553 | 500 | ||
554 | err |= !valid_user_regs(®s->user_regs); | 501 | err |= !valid_user_regs(®s->user_regs); |
555 | 502 | ||
556 | aux = (struct compat_aux_sigframe __user *) sf->uc.uc_regspace; | 503 | aux = (struct compat_aux_sigframe __user *) sf->uc.uc_regspace; |
557 | if (err == 0) | 504 | if (err == 0) |
558 | err |= compat_restore_vfp_context(&aux->vfp); | 505 | err |= compat_restore_vfp_context(&aux->vfp); |
559 | 506 | ||
560 | return err; | 507 | return err; |
561 | } | 508 | } |
562 | 509 | ||
563 | asmlinkage int compat_sys_sigreturn(struct pt_regs *regs) | 510 | asmlinkage int compat_sys_sigreturn(struct pt_regs *regs) |
564 | { | 511 | { |
565 | struct compat_sigframe __user *frame; | 512 | struct compat_sigframe __user *frame; |
566 | 513 | ||
567 | /* Always make any pending restarted system calls return -EINTR */ | 514 | /* Always make any pending restarted system calls return -EINTR */ |
568 | current_thread_info()->restart_block.fn = do_no_restart_syscall; | 515 | current_thread_info()->restart_block.fn = do_no_restart_syscall; |
569 | 516 | ||
570 | /* | 517 | /* |
571 | * Since we stacked the signal on a 64-bit boundary, | 518 | * Since we stacked the signal on a 64-bit boundary, |
572 | * then 'sp' should be word aligned here. If it's | 519 | * then 'sp' should be word aligned here. If it's |
573 | * not, then the user is trying to mess with us. | 520 | * not, then the user is trying to mess with us. |
574 | */ | 521 | */ |
575 | if (regs->compat_sp & 7) | 522 | if (regs->compat_sp & 7) |
576 | goto badframe; | 523 | goto badframe; |
577 | 524 | ||
578 | frame = (struct compat_sigframe __user *)regs->compat_sp; | 525 | frame = (struct compat_sigframe __user *)regs->compat_sp; |
579 | 526 | ||
580 | if (!access_ok(VERIFY_READ, frame, sizeof (*frame))) | 527 | if (!access_ok(VERIFY_READ, frame, sizeof (*frame))) |
581 | goto badframe; | 528 | goto badframe; |
582 | 529 | ||
583 | if (compat_restore_sigframe(regs, frame)) | 530 | if (compat_restore_sigframe(regs, frame)) |
584 | goto badframe; | 531 | goto badframe; |
585 | 532 | ||
586 | return regs->regs[0]; | 533 | return regs->regs[0]; |
587 | 534 | ||
588 | badframe: | 535 | badframe: |
589 | if (show_unhandled_signals) | 536 | if (show_unhandled_signals) |
590 | pr_info_ratelimited("%s[%d]: bad frame in %s: pc=%08llx sp=%08llx\n", | 537 | pr_info_ratelimited("%s[%d]: bad frame in %s: pc=%08llx sp=%08llx\n", |
591 | current->comm, task_pid_nr(current), __func__, | 538 | current->comm, task_pid_nr(current), __func__, |
592 | regs->pc, regs->sp); | 539 | regs->pc, regs->sp); |
593 | force_sig(SIGSEGV, current); | 540 | force_sig(SIGSEGV, current); |
594 | return 0; | 541 | return 0; |
595 | } | 542 | } |
596 | 543 | ||
597 | asmlinkage int compat_sys_rt_sigreturn(struct pt_regs *regs) | 544 | asmlinkage int compat_sys_rt_sigreturn(struct pt_regs *regs) |
598 | { | 545 | { |
599 | struct compat_rt_sigframe __user *frame; | 546 | struct compat_rt_sigframe __user *frame; |
600 | 547 | ||
601 | /* Always make any pending restarted system calls return -EINTR */ | 548 | /* Always make any pending restarted system calls return -EINTR */ |
602 | current_thread_info()->restart_block.fn = do_no_restart_syscall; | 549 | current_thread_info()->restart_block.fn = do_no_restart_syscall; |
603 | 550 | ||
604 | /* | 551 | /* |
605 | * Since we stacked the signal on a 64-bit boundary, | 552 | * Since we stacked the signal on a 64-bit boundary, |
606 | * then 'sp' should be word aligned here. If it's | 553 | * then 'sp' should be word aligned here. If it's |
607 | * not, then the user is trying to mess with us. | 554 | * not, then the user is trying to mess with us. |
608 | */ | 555 | */ |
609 | if (regs->compat_sp & 7) | 556 | if (regs->compat_sp & 7) |
610 | goto badframe; | 557 | goto badframe; |
611 | 558 | ||
612 | frame = (struct compat_rt_sigframe __user *)regs->compat_sp; | 559 | frame = (struct compat_rt_sigframe __user *)regs->compat_sp; |
613 | 560 | ||
614 | if (!access_ok(VERIFY_READ, frame, sizeof (*frame))) | 561 | if (!access_ok(VERIFY_READ, frame, sizeof (*frame))) |
615 | goto badframe; | 562 | goto badframe; |
616 | 563 | ||
617 | if (compat_restore_sigframe(regs, &frame->sig)) | 564 | if (compat_restore_sigframe(regs, &frame->sig)) |
618 | goto badframe; | 565 | goto badframe; |
619 | 566 | ||
620 | if (compat_do_sigaltstack(ptr_to_compat(&frame->sig.uc.uc_stack), | 567 | if (compat_do_sigaltstack(ptr_to_compat(&frame->sig.uc.uc_stack), |
621 | ptr_to_compat((void __user *)NULL), | 568 | ptr_to_compat((void __user *)NULL), |
622 | regs->compat_sp) == -EFAULT) | 569 | regs->compat_sp) == -EFAULT) |
623 | goto badframe; | 570 | goto badframe; |
624 | 571 | ||
625 | return regs->regs[0]; | 572 | return regs->regs[0]; |
626 | 573 | ||
627 | badframe: | 574 | badframe: |
628 | if (show_unhandled_signals) | 575 | if (show_unhandled_signals) |
629 | pr_info_ratelimited("%s[%d]: bad frame in %s: pc=%08llx sp=%08llx\n", | 576 | pr_info_ratelimited("%s[%d]: bad frame in %s: pc=%08llx sp=%08llx\n", |
630 | current->comm, task_pid_nr(current), __func__, | 577 | current->comm, task_pid_nr(current), __func__, |
631 | regs->pc, regs->sp); | 578 | regs->pc, regs->sp); |
632 | force_sig(SIGSEGV, current); | 579 | force_sig(SIGSEGV, current); |
633 | return 0; | 580 | return 0; |
634 | } | 581 | } |
635 | 582 | ||
636 | static inline void __user *compat_get_sigframe(struct k_sigaction *ka, | 583 | static inline void __user *compat_get_sigframe(struct k_sigaction *ka, |
637 | struct pt_regs *regs, | 584 | struct pt_regs *regs, |
638 | int framesize) | 585 | int framesize) |
639 | { | 586 | { |
640 | compat_ulong_t sp = regs->compat_sp; | 587 | compat_ulong_t sp = regs->compat_sp; |
641 | void __user *frame; | 588 | void __user *frame; |
642 | 589 | ||
643 | /* | 590 | /* |
644 | * This is the X/Open sanctioned signal stack switching. | 591 | * This is the X/Open sanctioned signal stack switching. |
645 | */ | 592 | */ |
646 | if ((ka->sa.sa_flags & SA_ONSTACK) && !sas_ss_flags(sp)) | 593 | if ((ka->sa.sa_flags & SA_ONSTACK) && !sas_ss_flags(sp)) |
647 | sp = current->sas_ss_sp + current->sas_ss_size; | 594 | sp = current->sas_ss_sp + current->sas_ss_size; |
648 | 595 | ||
649 | /* | 596 | /* |
650 | * ATPCS B01 mandates 8-byte alignment | 597 | * ATPCS B01 mandates 8-byte alignment |
651 | */ | 598 | */ |
652 | frame = compat_ptr((compat_uptr_t)((sp - framesize) & ~7)); | 599 | frame = compat_ptr((compat_uptr_t)((sp - framesize) & ~7)); |
653 | 600 | ||
654 | /* | 601 | /* |
655 | * Check that we can actually write to the signal frame. | 602 | * Check that we can actually write to the signal frame. |
656 | */ | 603 | */ |
657 | if (!access_ok(VERIFY_WRITE, frame, framesize)) | 604 | if (!access_ok(VERIFY_WRITE, frame, framesize)) |
658 | frame = NULL; | 605 | frame = NULL; |
659 | 606 | ||
660 | return frame; | 607 | return frame; |
661 | } | 608 | } |
662 | 609 | ||
663 | static int compat_setup_return(struct pt_regs *regs, struct k_sigaction *ka, | 610 | static int compat_setup_return(struct pt_regs *regs, struct k_sigaction *ka, |
664 | compat_ulong_t __user *rc, void __user *frame, | 611 | compat_ulong_t __user *rc, void __user *frame, |
665 | int usig) | 612 | int usig) |
666 | { | 613 | { |
667 | compat_ulong_t handler = ptr_to_compat(ka->sa.sa_handler); | 614 | compat_ulong_t handler = ptr_to_compat(ka->sa.sa_handler); |
668 | compat_ulong_t retcode; | 615 | compat_ulong_t retcode; |
669 | compat_ulong_t spsr = regs->pstate & ~PSR_f; | 616 | compat_ulong_t spsr = regs->pstate & ~PSR_f; |
670 | int thumb; | 617 | int thumb; |
671 | 618 | ||
672 | /* Check if the handler is written for ARM or Thumb */ | 619 | /* Check if the handler is written for ARM or Thumb */ |
673 | thumb = handler & 1; | 620 | thumb = handler & 1; |
674 | 621 | ||
675 | if (thumb) { | 622 | if (thumb) { |
676 | spsr |= COMPAT_PSR_T_BIT; | 623 | spsr |= COMPAT_PSR_T_BIT; |
677 | spsr &= ~COMPAT_PSR_IT_MASK; | 624 | spsr &= ~COMPAT_PSR_IT_MASK; |
678 | } else { | 625 | } else { |
679 | spsr &= ~COMPAT_PSR_T_BIT; | 626 | spsr &= ~COMPAT_PSR_T_BIT; |
680 | } | 627 | } |
681 | 628 | ||
682 | if (ka->sa.sa_flags & SA_RESTORER) { | 629 | if (ka->sa.sa_flags & SA_RESTORER) { |
683 | retcode = ptr_to_compat(ka->sa.sa_restorer); | 630 | retcode = ptr_to_compat(ka->sa.sa_restorer); |
684 | } else { | 631 | } else { |
685 | /* Set up sigreturn pointer */ | 632 | /* Set up sigreturn pointer */ |
686 | unsigned int idx = thumb << 1; | 633 | unsigned int idx = thumb << 1; |
687 | 634 | ||
688 | if (ka->sa.sa_flags & SA_SIGINFO) | 635 | if (ka->sa.sa_flags & SA_SIGINFO) |
689 | idx += 3; | 636 | idx += 3; |
690 | 637 | ||
691 | retcode = AARCH32_VECTORS_BASE + | 638 | retcode = AARCH32_VECTORS_BASE + |
692 | AARCH32_KERN_SIGRET_CODE_OFFSET + | 639 | AARCH32_KERN_SIGRET_CODE_OFFSET + |
693 | (idx << 2) + thumb; | 640 | (idx << 2) + thumb; |
694 | } | 641 | } |
695 | 642 | ||
696 | regs->regs[0] = usig; | 643 | regs->regs[0] = usig; |
697 | regs->compat_sp = ptr_to_compat(frame); | 644 | regs->compat_sp = ptr_to_compat(frame); |
698 | regs->compat_lr = retcode; | 645 | regs->compat_lr = retcode; |
699 | regs->pc = handler; | 646 | regs->pc = handler; |
700 | regs->pstate = spsr; | 647 | regs->pstate = spsr; |
701 | 648 | ||
702 | return 0; | 649 | return 0; |
703 | } | 650 | } |
704 | 651 | ||
705 | static int compat_setup_sigframe(struct compat_sigframe __user *sf, | 652 | static int compat_setup_sigframe(struct compat_sigframe __user *sf, |
706 | struct pt_regs *regs, sigset_t *set) | 653 | struct pt_regs *regs, sigset_t *set) |
707 | { | 654 | { |
708 | struct compat_aux_sigframe __user *aux; | 655 | struct compat_aux_sigframe __user *aux; |
709 | int err = 0; | 656 | int err = 0; |
710 | 657 | ||
711 | __put_user_error(regs->regs[0], &sf->uc.uc_mcontext.arm_r0, err); | 658 | __put_user_error(regs->regs[0], &sf->uc.uc_mcontext.arm_r0, err); |
712 | __put_user_error(regs->regs[1], &sf->uc.uc_mcontext.arm_r1, err); | 659 | __put_user_error(regs->regs[1], &sf->uc.uc_mcontext.arm_r1, err); |
713 | __put_user_error(regs->regs[2], &sf->uc.uc_mcontext.arm_r2, err); | 660 | __put_user_error(regs->regs[2], &sf->uc.uc_mcontext.arm_r2, err); |
714 | __put_user_error(regs->regs[3], &sf->uc.uc_mcontext.arm_r3, err); | 661 | __put_user_error(regs->regs[3], &sf->uc.uc_mcontext.arm_r3, err); |
715 | __put_user_error(regs->regs[4], &sf->uc.uc_mcontext.arm_r4, err); | 662 | __put_user_error(regs->regs[4], &sf->uc.uc_mcontext.arm_r4, err); |
716 | __put_user_error(regs->regs[5], &sf->uc.uc_mcontext.arm_r5, err); | 663 | __put_user_error(regs->regs[5], &sf->uc.uc_mcontext.arm_r5, err); |
717 | __put_user_error(regs->regs[6], &sf->uc.uc_mcontext.arm_r6, err); | 664 | __put_user_error(regs->regs[6], &sf->uc.uc_mcontext.arm_r6, err); |
718 | __put_user_error(regs->regs[7], &sf->uc.uc_mcontext.arm_r7, err); | 665 | __put_user_error(regs->regs[7], &sf->uc.uc_mcontext.arm_r7, err); |
719 | __put_user_error(regs->regs[8], &sf->uc.uc_mcontext.arm_r8, err); | 666 | __put_user_error(regs->regs[8], &sf->uc.uc_mcontext.arm_r8, err); |
720 | __put_user_error(regs->regs[9], &sf->uc.uc_mcontext.arm_r9, err); | 667 | __put_user_error(regs->regs[9], &sf->uc.uc_mcontext.arm_r9, err); |
721 | __put_user_error(regs->regs[10], &sf->uc.uc_mcontext.arm_r10, err); | 668 | __put_user_error(regs->regs[10], &sf->uc.uc_mcontext.arm_r10, err); |
722 | __put_user_error(regs->regs[11], &sf->uc.uc_mcontext.arm_fp, err); | 669 | __put_user_error(regs->regs[11], &sf->uc.uc_mcontext.arm_fp, err); |
723 | __put_user_error(regs->regs[12], &sf->uc.uc_mcontext.arm_ip, err); | 670 | __put_user_error(regs->regs[12], &sf->uc.uc_mcontext.arm_ip, err); |
724 | __put_user_error(regs->compat_sp, &sf->uc.uc_mcontext.arm_sp, err); | 671 | __put_user_error(regs->compat_sp, &sf->uc.uc_mcontext.arm_sp, err); |
725 | __put_user_error(regs->compat_lr, &sf->uc.uc_mcontext.arm_lr, err); | 672 | __put_user_error(regs->compat_lr, &sf->uc.uc_mcontext.arm_lr, err); |
726 | __put_user_error(regs->pc, &sf->uc.uc_mcontext.arm_pc, err); | 673 | __put_user_error(regs->pc, &sf->uc.uc_mcontext.arm_pc, err); |
727 | __put_user_error(regs->pstate, &sf->uc.uc_mcontext.arm_cpsr, err); | 674 | __put_user_error(regs->pstate, &sf->uc.uc_mcontext.arm_cpsr, err); |
728 | 675 | ||
729 | __put_user_error((compat_ulong_t)0, &sf->uc.uc_mcontext.trap_no, err); | 676 | __put_user_error((compat_ulong_t)0, &sf->uc.uc_mcontext.trap_no, err); |
730 | __put_user_error((compat_ulong_t)0, &sf->uc.uc_mcontext.error_code, err); | 677 | __put_user_error((compat_ulong_t)0, &sf->uc.uc_mcontext.error_code, err); |
731 | __put_user_error(current->thread.fault_address, &sf->uc.uc_mcontext.fault_address, err); | 678 | __put_user_error(current->thread.fault_address, &sf->uc.uc_mcontext.fault_address, err); |
732 | __put_user_error(set->sig[0], &sf->uc.uc_mcontext.oldmask, err); | 679 | __put_user_error(set->sig[0], &sf->uc.uc_mcontext.oldmask, err); |
733 | 680 | ||
734 | err |= put_sigset_t(&sf->uc.uc_sigmask, set); | 681 | err |= put_sigset_t(&sf->uc.uc_sigmask, set); |
735 | 682 | ||
736 | aux = (struct compat_aux_sigframe __user *) sf->uc.uc_regspace; | 683 | aux = (struct compat_aux_sigframe __user *) sf->uc.uc_regspace; |
737 | 684 | ||
738 | if (err == 0) | 685 | if (err == 0) |
739 | err |= compat_preserve_vfp_context(&aux->vfp); | 686 | err |= compat_preserve_vfp_context(&aux->vfp); |
740 | __put_user_error(0, &aux->end_magic, err); | 687 | __put_user_error(0, &aux->end_magic, err); |
741 | 688 | ||
742 | return err; | 689 | return err; |
743 | } | 690 | } |
744 | 691 | ||
745 | /* | 692 | /* |
746 | * 32-bit signal handling routines called from signal.c | 693 | * 32-bit signal handling routines called from signal.c |
747 | */ | 694 | */ |
748 | int compat_setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info, | 695 | int compat_setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info, |
749 | sigset_t *set, struct pt_regs *regs) | 696 | sigset_t *set, struct pt_regs *regs) |
750 | { | 697 | { |
751 | struct compat_rt_sigframe __user *frame; | 698 | struct compat_rt_sigframe __user *frame; |
752 | compat_stack_t stack; | 699 | compat_stack_t stack; |
753 | int err = 0; | 700 | int err = 0; |
754 | 701 | ||
755 | frame = compat_get_sigframe(ka, regs, sizeof(*frame)); | 702 | frame = compat_get_sigframe(ka, regs, sizeof(*frame)); |
756 | 703 | ||
757 | if (!frame) | 704 | if (!frame) |
758 | return 1; | 705 | return 1; |
759 | 706 | ||
760 | err |= copy_siginfo_to_user32(&frame->info, info); | 707 | err |= copy_siginfo_to_user32(&frame->info, info); |
761 | 708 | ||
762 | __put_user_error(0, &frame->sig.uc.uc_flags, err); | 709 | __put_user_error(0, &frame->sig.uc.uc_flags, err); |
763 | __put_user_error(NULL, &frame->sig.uc.uc_link, err); | 710 | __put_user_error(NULL, &frame->sig.uc.uc_link, err); |
764 | 711 | ||
765 | memset(&stack, 0, sizeof(stack)); | 712 | memset(&stack, 0, sizeof(stack)); |
766 | stack.ss_sp = (compat_uptr_t)current->sas_ss_sp; | 713 | stack.ss_sp = (compat_uptr_t)current->sas_ss_sp; |
767 | stack.ss_flags = sas_ss_flags(regs->compat_sp); | 714 | stack.ss_flags = sas_ss_flags(regs->compat_sp); |
768 | stack.ss_size = current->sas_ss_size; | 715 | stack.ss_size = current->sas_ss_size; |
769 | err |= __copy_to_user(&frame->sig.uc.uc_stack, &stack, sizeof(stack)); | 716 | err |= __copy_to_user(&frame->sig.uc.uc_stack, &stack, sizeof(stack)); |
770 | 717 | ||
771 | err |= compat_setup_sigframe(&frame->sig, regs, set); | 718 | err |= compat_setup_sigframe(&frame->sig, regs, set); |
772 | if (err == 0) | 719 | if (err == 0) |
773 | err = compat_setup_return(regs, ka, frame->sig.retcode, frame, | 720 | err = compat_setup_return(regs, ka, frame->sig.retcode, frame, |
774 | usig); | 721 | usig); |
775 | 722 | ||
776 | if (err == 0) { | 723 | if (err == 0) { |
777 | regs->regs[1] = (compat_ulong_t)(unsigned long)&frame->info; | 724 | regs->regs[1] = (compat_ulong_t)(unsigned long)&frame->info; |
778 | regs->regs[2] = (compat_ulong_t)(unsigned long)&frame->sig.uc; | 725 | regs->regs[2] = (compat_ulong_t)(unsigned long)&frame->sig.uc; |
779 | } | 726 | } |
780 | 727 | ||
781 | return err; | 728 | return err; |
782 | } | 729 | } |
783 | 730 | ||
784 | int compat_setup_frame(int usig, struct k_sigaction *ka, sigset_t *set, | 731 | int compat_setup_frame(int usig, struct k_sigaction *ka, sigset_t *set, |
785 | struct pt_regs *regs) | 732 | struct pt_regs *regs) |
786 | { | 733 | { |
787 | struct compat_sigframe __user *frame; | 734 | struct compat_sigframe __user *frame; |
788 | int err = 0; | 735 | int err = 0; |
789 | 736 | ||
790 | frame = compat_get_sigframe(ka, regs, sizeof(*frame)); | 737 | frame = compat_get_sigframe(ka, regs, sizeof(*frame)); |
791 | 738 | ||
792 | if (!frame) | 739 | if (!frame) |
793 | return 1; | 740 | return 1; |
794 | 741 | ||
795 | __put_user_error(0x5ac3c35a, &frame->uc.uc_flags, err); | 742 | __put_user_error(0x5ac3c35a, &frame->uc.uc_flags, err); |
796 | 743 | ||
797 | err |= compat_setup_sigframe(frame, regs, set); | 744 | err |= compat_setup_sigframe(frame, regs, set); |
798 | if (err == 0) | 745 | if (err == 0) |
799 | err = compat_setup_return(regs, ka, frame->retcode, frame, usig); | 746 | err = compat_setup_return(regs, ka, frame->retcode, frame, usig); |
800 | 747 | ||
801 | return err; | 748 | return err; |
802 | } | 749 | } |
803 | 750 | ||
804 | /* | 751 | /* |
805 | * RT signals don't have generic compat wrappers. | 752 | * RT signals don't have generic compat wrappers. |
806 | * See arch/powerpc/kernel/signal_32.c | 753 | * See arch/powerpc/kernel/signal_32.c |
807 | */ | 754 | */ |
808 | asmlinkage int compat_sys_rt_sigprocmask(int how, compat_sigset_t __user *set, | 755 | asmlinkage int compat_sys_rt_sigprocmask(int how, compat_sigset_t __user *set, |
809 | compat_sigset_t __user *oset, | 756 | compat_sigset_t __user *oset, |
810 | compat_size_t sigsetsize) | 757 | compat_size_t sigsetsize) |
811 | { | 758 | { |
812 | sigset_t s; | 759 | sigset_t s; |
813 | sigset_t __user *up; | 760 | sigset_t __user *up; |
814 | int ret; | 761 | int ret; |
815 | mm_segment_t old_fs = get_fs(); | 762 | mm_segment_t old_fs = get_fs(); |
816 | 763 | ||
817 | if (set) { | 764 | if (set) { |
818 | if (get_sigset_t(&s, set)) | 765 | if (get_sigset_t(&s, set)) |
819 | return -EFAULT; | 766 | return -EFAULT; |
820 | } | 767 | } |
821 | 768 | ||
822 | set_fs(KERNEL_DS); | 769 | set_fs(KERNEL_DS); |
823 | /* This is valid because of the set_fs() */ | 770 | /* This is valid because of the set_fs() */ |
824 | up = (sigset_t __user *) &s; | 771 | up = (sigset_t __user *) &s; |
825 | ret = sys_rt_sigprocmask(how, set ? up : NULL, oset ? up : NULL, | 772 | ret = sys_rt_sigprocmask(how, set ? up : NULL, oset ? up : NULL, |
826 | sigsetsize); | 773 | sigsetsize); |
827 | set_fs(old_fs); | 774 | set_fs(old_fs); |
828 | if (ret) | 775 | if (ret) |
829 | return ret; | 776 | return ret; |
830 | if (oset) { | 777 | if (oset) { |
831 | if (put_sigset_t(oset, &s)) | 778 | if (put_sigset_t(oset, &s)) |
832 | return -EFAULT; | 779 | return -EFAULT; |
833 | } | 780 | } |
834 | return 0; | 781 | return 0; |
835 | } | 782 | } |
836 | 783 | ||
837 | asmlinkage int compat_sys_rt_sigpending(compat_sigset_t __user *set, | 784 | asmlinkage int compat_sys_rt_sigpending(compat_sigset_t __user *set, |
838 | compat_size_t sigsetsize) | 785 | compat_size_t sigsetsize) |
839 | { | 786 | { |
840 | sigset_t s; | 787 | sigset_t s; |
841 | int ret; | 788 | int ret; |
842 | mm_segment_t old_fs = get_fs(); | 789 | mm_segment_t old_fs = get_fs(); |
843 | 790 | ||
844 | set_fs(KERNEL_DS); | 791 | set_fs(KERNEL_DS); |
845 | /* The __user pointer cast is valid because of the set_fs() */ | 792 | /* The __user pointer cast is valid because of the set_fs() */ |
846 | ret = sys_rt_sigpending((sigset_t __user *) &s, sigsetsize); | 793 | ret = sys_rt_sigpending((sigset_t __user *) &s, sigsetsize); |
847 | set_fs(old_fs); | 794 | set_fs(old_fs); |
848 | if (!ret) { | 795 | if (!ret) { |
849 | if (put_sigset_t(set, &s)) | 796 | if (put_sigset_t(set, &s)) |
850 | return -EFAULT; | 797 | return -EFAULT; |
851 | } | 798 | } |
852 | return ret; | 799 | return ret; |
853 | } | 800 | } |
854 | 801 | ||
855 | asmlinkage int compat_sys_rt_sigqueueinfo(int pid, int sig, | 802 | asmlinkage int compat_sys_rt_sigqueueinfo(int pid, int sig, |
856 | compat_siginfo_t __user *uinfo) | 803 | compat_siginfo_t __user *uinfo) |
857 | { | 804 | { |
858 | siginfo_t info; | 805 | siginfo_t info; |
859 | int ret; | 806 | int ret; |
860 | mm_segment_t old_fs = get_fs(); | 807 | mm_segment_t old_fs = get_fs(); |
861 | 808 | ||
862 | ret = copy_siginfo_from_user32(&info, uinfo); | 809 | ret = copy_siginfo_from_user32(&info, uinfo); |
863 | if (unlikely(ret)) | 810 | if (unlikely(ret)) |
864 | return ret; | 811 | return ret; |
865 | 812 | ||
866 | set_fs (KERNEL_DS); | 813 | set_fs (KERNEL_DS); |
867 | /* The __user pointer cast is valid because of the set_fs() */ | 814 | /* The __user pointer cast is valid because of the set_fs() */ |
868 | ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *) &info); | 815 | ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *) &info); |
869 | set_fs (old_fs); | 816 | set_fs (old_fs); |
870 | return ret; | 817 | return ret; |
871 | } | 818 | } |
872 | 819 | ||
873 | void compat_setup_restart_syscall(struct pt_regs *regs) | 820 | void compat_setup_restart_syscall(struct pt_regs *regs) |
874 | { | 821 | { |
875 | regs->regs[7] = __NR_restart_syscall; | 822 | regs->regs[7] = __NR_restart_syscall; |
876 | } | 823 | } |
877 | 824 |
arch/mips/include/asm/compat-signal.h
1 | #ifndef __ASM_COMPAT_SIGNAL_H | 1 | #ifndef __ASM_COMPAT_SIGNAL_H |
2 | #define __ASM_COMPAT_SIGNAL_H | 2 | #define __ASM_COMPAT_SIGNAL_H |
3 | 3 | ||
4 | #include <linux/bug.h> | 4 | #include <linux/bug.h> |
5 | #include <linux/compat.h> | 5 | #include <linux/compat.h> |
6 | #include <linux/compiler.h> | 6 | #include <linux/compiler.h> |
7 | 7 | ||
8 | #include <asm/signal.h> | 8 | #include <asm/signal.h> |
9 | #include <asm/siginfo.h> | 9 | #include <asm/siginfo.h> |
10 | 10 | ||
11 | #include <asm/uaccess.h> | 11 | #include <asm/uaccess.h> |
12 | 12 | ||
13 | #define SI_PAD_SIZE32 ((SI_MAX_SIZE/sizeof(int)) - 3) | ||
14 | |||
15 | typedef struct compat_siginfo { | ||
16 | int si_signo; | ||
17 | int si_code; | ||
18 | int si_errno; | ||
19 | |||
20 | union { | ||
21 | int _pad[SI_PAD_SIZE32]; | ||
22 | |||
23 | /* kill() */ | ||
24 | struct { | ||
25 | compat_pid_t _pid; /* sender's pid */ | ||
26 | compat_uid_t _uid; /* sender's uid */ | ||
27 | } _kill; | ||
28 | |||
29 | /* SIGCHLD */ | ||
30 | struct { | ||
31 | compat_pid_t _pid; /* which child */ | ||
32 | compat_uid_t _uid; /* sender's uid */ | ||
33 | int _status; /* exit code */ | ||
34 | compat_clock_t _utime; | ||
35 | compat_clock_t _stime; | ||
36 | } _sigchld; | ||
37 | |||
38 | /* IRIX SIGCHLD */ | ||
39 | struct { | ||
40 | compat_pid_t _pid; /* which child */ | ||
41 | compat_clock_t _utime; | ||
42 | int _status; /* exit code */ | ||
43 | compat_clock_t _stime; | ||
44 | } _irix_sigchld; | ||
45 | |||
46 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ | ||
47 | struct { | ||
48 | s32 _addr; /* faulting insn/memory ref. */ | ||
49 | } _sigfault; | ||
50 | |||
51 | /* SIGPOLL, SIGXFSZ (To do ...) */ | ||
52 | struct { | ||
53 | int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ | ||
54 | int _fd; | ||
55 | } _sigpoll; | ||
56 | |||
57 | /* POSIX.1b timers */ | ||
58 | struct { | ||
59 | timer_t _tid; /* timer id */ | ||
60 | int _overrun; /* overrun count */ | ||
61 | compat_sigval_t _sigval;/* same as below */ | ||
62 | int _sys_private; /* not to be passed to user */ | ||
63 | } _timer; | ||
64 | |||
65 | /* POSIX.1b signals */ | ||
66 | struct { | ||
67 | compat_pid_t _pid; /* sender's pid */ | ||
68 | compat_uid_t _uid; /* sender's uid */ | ||
69 | compat_sigval_t _sigval; | ||
70 | } _rt; | ||
71 | |||
72 | } _sifields; | ||
73 | } compat_siginfo_t; | ||
74 | |||
75 | static inline int __copy_conv_sigset_to_user(compat_sigset_t __user *d, | 13 | static inline int __copy_conv_sigset_to_user(compat_sigset_t __user *d, |
76 | const sigset_t *s) | 14 | const sigset_t *s) |
77 | { | 15 | { |
78 | int err; | 16 | int err; |
79 | 17 | ||
80 | BUG_ON(sizeof(*d) != sizeof(*s)); | 18 | BUG_ON(sizeof(*d) != sizeof(*s)); |
81 | BUG_ON(_NSIG_WORDS != 2); | 19 | BUG_ON(_NSIG_WORDS != 2); |
82 | 20 | ||
83 | err = __put_user(s->sig[0], &d->sig[0]); | 21 | err = __put_user(s->sig[0], &d->sig[0]); |
84 | err |= __put_user(s->sig[0] >> 32, &d->sig[1]); | 22 | err |= __put_user(s->sig[0] >> 32, &d->sig[1]); |
85 | err |= __put_user(s->sig[1], &d->sig[2]); | 23 | err |= __put_user(s->sig[1], &d->sig[2]); |
86 | err |= __put_user(s->sig[1] >> 32, &d->sig[3]); | 24 | err |= __put_user(s->sig[1] >> 32, &d->sig[3]); |
87 | 25 | ||
88 | return err; | 26 | return err; |
89 | } | 27 | } |
90 | 28 | ||
91 | static inline int __copy_conv_sigset_from_user(sigset_t *d, | 29 | static inline int __copy_conv_sigset_from_user(sigset_t *d, |
92 | const compat_sigset_t __user *s) | 30 | const compat_sigset_t __user *s) |
93 | { | 31 | { |
94 | int err; | 32 | int err; |
95 | union sigset_u { | 33 | union sigset_u { |
96 | sigset_t s; | 34 | sigset_t s; |
97 | compat_sigset_t c; | 35 | compat_sigset_t c; |
98 | } *u = (union sigset_u *) d; | 36 | } *u = (union sigset_u *) d; |
99 | 37 | ||
100 | BUG_ON(sizeof(*d) != sizeof(*s)); | 38 | BUG_ON(sizeof(*d) != sizeof(*s)); |
101 | BUG_ON(_NSIG_WORDS != 2); | 39 | BUG_ON(_NSIG_WORDS != 2); |
102 | 40 | ||
103 | #ifdef CONFIG_CPU_BIG_ENDIAN | 41 | #ifdef CONFIG_CPU_BIG_ENDIAN |
104 | err = __get_user(u->c.sig[1], &s->sig[0]); | 42 | err = __get_user(u->c.sig[1], &s->sig[0]); |
105 | err |= __get_user(u->c.sig[0], &s->sig[1]); | 43 | err |= __get_user(u->c.sig[0], &s->sig[1]); |
106 | err |= __get_user(u->c.sig[3], &s->sig[2]); | 44 | err |= __get_user(u->c.sig[3], &s->sig[2]); |
107 | err |= __get_user(u->c.sig[2], &s->sig[3]); | 45 | err |= __get_user(u->c.sig[2], &s->sig[3]); |
108 | #endif | 46 | #endif |
109 | #ifdef CONFIG_CPU_LITTLE_ENDIAN | 47 | #ifdef CONFIG_CPU_LITTLE_ENDIAN |
110 | err = __get_user(u->c.sig[0], &s->sig[0]); | 48 | err = __get_user(u->c.sig[0], &s->sig[0]); |
111 | err |= __get_user(u->c.sig[1], &s->sig[1]); | 49 | err |= __get_user(u->c.sig[1], &s->sig[1]); |
112 | err |= __get_user(u->c.sig[2], &s->sig[2]); | 50 | err |= __get_user(u->c.sig[2], &s->sig[2]); |
113 | err |= __get_user(u->c.sig[3], &s->sig[3]); | 51 | err |= __get_user(u->c.sig[3], &s->sig[3]); |
114 | #endif | 52 | #endif |
115 | 53 | ||
116 | return err; | 54 | return err; |
117 | } | 55 | } |
118 | 56 | ||
119 | #endif /* __ASM_COMPAT_SIGNAL_H */ | 57 | #endif /* __ASM_COMPAT_SIGNAL_H */ |
120 | 58 |
arch/mips/include/asm/compat.h
1 | #ifndef _ASM_COMPAT_H | 1 | #ifndef _ASM_COMPAT_H |
2 | #define _ASM_COMPAT_H | 2 | #define _ASM_COMPAT_H |
3 | /* | 3 | /* |
4 | * Architecture specific compatibility types | 4 | * Architecture specific compatibility types |
5 | */ | 5 | */ |
6 | #include <linux/thread_info.h> | 6 | #include <linux/thread_info.h> |
7 | #include <linux/types.h> | 7 | #include <linux/types.h> |
8 | #include <asm/page.h> | 8 | #include <asm/page.h> |
9 | #include <asm/ptrace.h> | 9 | #include <asm/ptrace.h> |
10 | 10 | ||
11 | #define COMPAT_USER_HZ 100 | 11 | #define COMPAT_USER_HZ 100 |
12 | #define COMPAT_UTS_MACHINE "mips\0\0\0" | 12 | #define COMPAT_UTS_MACHINE "mips\0\0\0" |
13 | 13 | ||
14 | typedef u32 compat_size_t; | 14 | typedef u32 compat_size_t; |
15 | typedef s32 compat_ssize_t; | 15 | typedef s32 compat_ssize_t; |
16 | typedef s32 compat_time_t; | 16 | typedef s32 compat_time_t; |
17 | typedef s32 compat_clock_t; | 17 | typedef s32 compat_clock_t; |
18 | typedef s32 compat_suseconds_t; | 18 | typedef s32 compat_suseconds_t; |
19 | 19 | ||
20 | typedef s32 compat_pid_t; | 20 | typedef s32 compat_pid_t; |
21 | typedef s32 __compat_uid_t; | 21 | typedef s32 __compat_uid_t; |
22 | typedef s32 __compat_gid_t; | 22 | typedef s32 __compat_gid_t; |
23 | typedef __compat_uid_t __compat_uid32_t; | 23 | typedef __compat_uid_t __compat_uid32_t; |
24 | typedef __compat_gid_t __compat_gid32_t; | 24 | typedef __compat_gid_t __compat_gid32_t; |
25 | typedef u32 compat_mode_t; | 25 | typedef u32 compat_mode_t; |
26 | typedef u32 compat_ino_t; | 26 | typedef u32 compat_ino_t; |
27 | typedef u32 compat_dev_t; | 27 | typedef u32 compat_dev_t; |
28 | typedef s32 compat_off_t; | 28 | typedef s32 compat_off_t; |
29 | typedef s64 compat_loff_t; | 29 | typedef s64 compat_loff_t; |
30 | typedef u32 compat_nlink_t; | 30 | typedef u32 compat_nlink_t; |
31 | typedef s32 compat_ipc_pid_t; | 31 | typedef s32 compat_ipc_pid_t; |
32 | typedef s32 compat_daddr_t; | 32 | typedef s32 compat_daddr_t; |
33 | typedef s32 compat_caddr_t; | 33 | typedef s32 compat_caddr_t; |
34 | typedef struct { | 34 | typedef struct { |
35 | s32 val[2]; | 35 | s32 val[2]; |
36 | } compat_fsid_t; | 36 | } compat_fsid_t; |
37 | typedef s32 compat_timer_t; | 37 | typedef s32 compat_timer_t; |
38 | typedef s32 compat_key_t; | 38 | typedef s32 compat_key_t; |
39 | 39 | ||
40 | typedef s32 compat_int_t; | 40 | typedef s32 compat_int_t; |
41 | typedef s32 compat_long_t; | 41 | typedef s32 compat_long_t; |
42 | typedef s64 compat_s64; | 42 | typedef s64 compat_s64; |
43 | typedef u32 compat_uint_t; | 43 | typedef u32 compat_uint_t; |
44 | typedef u32 compat_ulong_t; | 44 | typedef u32 compat_ulong_t; |
45 | typedef u64 compat_u64; | 45 | typedef u64 compat_u64; |
46 | typedef u32 compat_uptr_t; | ||
46 | 47 | ||
47 | struct compat_timespec { | 48 | struct compat_timespec { |
48 | compat_time_t tv_sec; | 49 | compat_time_t tv_sec; |
49 | s32 tv_nsec; | 50 | s32 tv_nsec; |
50 | }; | 51 | }; |
51 | 52 | ||
52 | struct compat_timeval { | 53 | struct compat_timeval { |
53 | compat_time_t tv_sec; | 54 | compat_time_t tv_sec; |
54 | s32 tv_usec; | 55 | s32 tv_usec; |
55 | }; | 56 | }; |
56 | 57 | ||
57 | struct compat_stat { | 58 | struct compat_stat { |
58 | compat_dev_t st_dev; | 59 | compat_dev_t st_dev; |
59 | s32 st_pad1[3]; | 60 | s32 st_pad1[3]; |
60 | compat_ino_t st_ino; | 61 | compat_ino_t st_ino; |
61 | compat_mode_t st_mode; | 62 | compat_mode_t st_mode; |
62 | compat_nlink_t st_nlink; | 63 | compat_nlink_t st_nlink; |
63 | __compat_uid_t st_uid; | 64 | __compat_uid_t st_uid; |
64 | __compat_gid_t st_gid; | 65 | __compat_gid_t st_gid; |
65 | compat_dev_t st_rdev; | 66 | compat_dev_t st_rdev; |
66 | s32 st_pad2[2]; | 67 | s32 st_pad2[2]; |
67 | compat_off_t st_size; | 68 | compat_off_t st_size; |
68 | s32 st_pad3; | 69 | s32 st_pad3; |
69 | compat_time_t st_atime; | 70 | compat_time_t st_atime; |
70 | s32 st_atime_nsec; | 71 | s32 st_atime_nsec; |
71 | compat_time_t st_mtime; | 72 | compat_time_t st_mtime; |
72 | s32 st_mtime_nsec; | 73 | s32 st_mtime_nsec; |
73 | compat_time_t st_ctime; | 74 | compat_time_t st_ctime; |
74 | s32 st_ctime_nsec; | 75 | s32 st_ctime_nsec; |
75 | s32 st_blksize; | 76 | s32 st_blksize; |
76 | s32 st_blocks; | 77 | s32 st_blocks; |
77 | s32 st_pad4[14]; | 78 | s32 st_pad4[14]; |
78 | }; | 79 | }; |
79 | 80 | ||
80 | struct compat_flock { | 81 | struct compat_flock { |
81 | short l_type; | 82 | short l_type; |
82 | short l_whence; | 83 | short l_whence; |
83 | compat_off_t l_start; | 84 | compat_off_t l_start; |
84 | compat_off_t l_len; | 85 | compat_off_t l_len; |
85 | s32 l_sysid; | 86 | s32 l_sysid; |
86 | compat_pid_t l_pid; | 87 | compat_pid_t l_pid; |
87 | short __unused; | 88 | short __unused; |
88 | s32 pad[4]; | 89 | s32 pad[4]; |
89 | }; | 90 | }; |
90 | 91 | ||
91 | #define F_GETLK64 33 | 92 | #define F_GETLK64 33 |
92 | #define F_SETLK64 34 | 93 | #define F_SETLK64 34 |
93 | #define F_SETLKW64 35 | 94 | #define F_SETLKW64 35 |
94 | 95 | ||
95 | struct compat_flock64 { | 96 | struct compat_flock64 { |
96 | short l_type; | 97 | short l_type; |
97 | short l_whence; | 98 | short l_whence; |
98 | compat_loff_t l_start; | 99 | compat_loff_t l_start; |
99 | compat_loff_t l_len; | 100 | compat_loff_t l_len; |
100 | compat_pid_t l_pid; | 101 | compat_pid_t l_pid; |
101 | }; | 102 | }; |
102 | 103 | ||
103 | struct compat_statfs { | 104 | struct compat_statfs { |
104 | int f_type; | 105 | int f_type; |
105 | int f_bsize; | 106 | int f_bsize; |
106 | int f_frsize; | 107 | int f_frsize; |
107 | int f_blocks; | 108 | int f_blocks; |
108 | int f_bfree; | 109 | int f_bfree; |
109 | int f_files; | 110 | int f_files; |
110 | int f_ffree; | 111 | int f_ffree; |
111 | int f_bavail; | 112 | int f_bavail; |
112 | compat_fsid_t f_fsid; | 113 | compat_fsid_t f_fsid; |
113 | int f_namelen; | 114 | int f_namelen; |
114 | int f_flags; | 115 | int f_flags; |
115 | int f_spare[5]; | 116 | int f_spare[5]; |
116 | }; | 117 | }; |
117 | 118 | ||
118 | #define COMPAT_RLIM_INFINITY 0x7fffffffUL | 119 | #define COMPAT_RLIM_INFINITY 0x7fffffffUL |
119 | 120 | ||
120 | typedef u32 compat_old_sigset_t; /* at least 32 bits */ | 121 | typedef u32 compat_old_sigset_t; /* at least 32 bits */ |
121 | 122 | ||
122 | #define _COMPAT_NSIG 128 /* Don't ask !$@#% ... */ | 123 | #define _COMPAT_NSIG 128 /* Don't ask !$@#% ... */ |
123 | #define _COMPAT_NSIG_BPW 32 | 124 | #define _COMPAT_NSIG_BPW 32 |
124 | 125 | ||
125 | typedef u32 compat_sigset_word; | 126 | typedef u32 compat_sigset_word; |
126 | 127 | ||
128 | typedef union compat_sigval { | ||
129 | compat_int_t sival_int; | ||
130 | compat_uptr_t sival_ptr; | ||
131 | } compat_sigval_t; | ||
132 | |||
133 | #define SI_PAD_SIZE32 (128/sizeof(int) - 3) | ||
134 | |||
135 | typedef struct compat_siginfo { | ||
136 | int si_signo; | ||
137 | int si_code; | ||
138 | int si_errno; | ||
139 | |||
140 | union { | ||
141 | int _pad[SI_PAD_SIZE32]; | ||
142 | |||
143 | /* kill() */ | ||
144 | struct { | ||
145 | compat_pid_t _pid; /* sender's pid */ | ||
146 | __compat_uid_t _uid; /* sender's uid */ | ||
147 | } _kill; | ||
148 | |||
149 | /* SIGCHLD */ | ||
150 | struct { | ||
151 | compat_pid_t _pid; /* which child */ | ||
152 | __compat_uid_t _uid; /* sender's uid */ | ||
153 | int _status; /* exit code */ | ||
154 | compat_clock_t _utime; | ||
155 | compat_clock_t _stime; | ||
156 | } _sigchld; | ||
157 | |||
158 | /* IRIX SIGCHLD */ | ||
159 | struct { | ||
160 | compat_pid_t _pid; /* which child */ | ||
161 | compat_clock_t _utime; | ||
162 | int _status; /* exit code */ | ||
163 | compat_clock_t _stime; | ||
164 | } _irix_sigchld; | ||
165 | |||
166 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ | ||
167 | struct { | ||
168 | s32 _addr; /* faulting insn/memory ref. */ | ||
169 | } _sigfault; | ||
170 | |||
171 | /* SIGPOLL, SIGXFSZ (To do ...) */ | ||
172 | struct { | ||
173 | int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ | ||
174 | int _fd; | ||
175 | } _sigpoll; | ||
176 | |||
177 | /* POSIX.1b timers */ | ||
178 | struct { | ||
179 | timer_t _tid; /* timer id */ | ||
180 | int _overrun; /* overrun count */ | ||
181 | compat_sigval_t _sigval;/* same as below */ | ||
182 | int _sys_private; /* not to be passed to user */ | ||
183 | } _timer; | ||
184 | |||
185 | /* POSIX.1b signals */ | ||
186 | struct { | ||
187 | compat_pid_t _pid; /* sender's pid */ | ||
188 | __compat_uid_t _uid; /* sender's uid */ | ||
189 | compat_sigval_t _sigval; | ||
190 | } _rt; | ||
191 | |||
192 | } _sifields; | ||
193 | } compat_siginfo_t; | ||
194 | |||
127 | #define COMPAT_OFF_T_MAX 0x7fffffff | 195 | #define COMPAT_OFF_T_MAX 0x7fffffff |
128 | #define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL | 196 | #define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL |
129 | 197 | ||
130 | /* | 198 | /* |
131 | * A pointer passed in from user mode. This should not | 199 | * A pointer passed in from user mode. This should not |
132 | * be used for syscall parameters, just declare them | 200 | * be used for syscall parameters, just declare them |
133 | * as pointers because the syscall entry code will have | 201 | * as pointers because the syscall entry code will have |
134 | * appropriately converted them already. | 202 | * appropriately converted them already. |
135 | */ | 203 | */ |
136 | typedef u32 compat_uptr_t; | ||
137 | 204 | ||
138 | static inline void __user *compat_ptr(compat_uptr_t uptr) | 205 | static inline void __user *compat_ptr(compat_uptr_t uptr) |
139 | { | 206 | { |
140 | /* cast to a __user pointer via "unsigned long" makes sparse happy */ | 207 | /* cast to a __user pointer via "unsigned long" makes sparse happy */ |
141 | return (void __user *)(unsigned long)(long)uptr; | 208 | return (void __user *)(unsigned long)(long)uptr; |
142 | } | 209 | } |
143 | 210 | ||
144 | static inline compat_uptr_t ptr_to_compat(void __user *uptr) | 211 | static inline compat_uptr_t ptr_to_compat(void __user *uptr) |
145 | { | 212 | { |
146 | return (u32)(unsigned long)uptr; | 213 | return (u32)(unsigned long)uptr; |
147 | } | 214 | } |
148 | 215 | ||
149 | static inline void __user *arch_compat_alloc_user_space(long len) | 216 | static inline void __user *arch_compat_alloc_user_space(long len) |
150 | { | 217 | { |
151 | struct pt_regs *regs = (struct pt_regs *) | 218 | struct pt_regs *regs = (struct pt_regs *) |
152 | ((unsigned long) current_thread_info() + THREAD_SIZE - 32) - 1; | 219 | ((unsigned long) current_thread_info() + THREAD_SIZE - 32) - 1; |
153 | 220 | ||
154 | return (void __user *) (regs->regs[29] - len); | 221 | return (void __user *) (regs->regs[29] - len); |
155 | } | 222 | } |
156 | 223 | ||
157 | struct compat_ipc64_perm { | 224 | struct compat_ipc64_perm { |
158 | compat_key_t key; | 225 | compat_key_t key; |
159 | __compat_uid32_t uid; | 226 | __compat_uid32_t uid; |
160 | __compat_gid32_t gid; | 227 | __compat_gid32_t gid; |
161 | __compat_uid32_t cuid; | 228 | __compat_uid32_t cuid; |
162 | __compat_gid32_t cgid; | 229 | __compat_gid32_t cgid; |
163 | compat_mode_t mode; | 230 | compat_mode_t mode; |
164 | unsigned short seq; | 231 | unsigned short seq; |
165 | unsigned short __pad2; | 232 | unsigned short __pad2; |
166 | compat_ulong_t __unused1; | 233 | compat_ulong_t __unused1; |
167 | compat_ulong_t __unused2; | 234 | compat_ulong_t __unused2; |
168 | }; | 235 | }; |
169 | 236 | ||
170 | struct compat_semid64_ds { | 237 | struct compat_semid64_ds { |
171 | struct compat_ipc64_perm sem_perm; | 238 | struct compat_ipc64_perm sem_perm; |
172 | compat_time_t sem_otime; | 239 | compat_time_t sem_otime; |
173 | compat_time_t sem_ctime; | 240 | compat_time_t sem_ctime; |
174 | compat_ulong_t sem_nsems; | 241 | compat_ulong_t sem_nsems; |
175 | compat_ulong_t __unused1; | 242 | compat_ulong_t __unused1; |
176 | compat_ulong_t __unused2; | 243 | compat_ulong_t __unused2; |
177 | }; | 244 | }; |
178 | 245 | ||
179 | struct compat_msqid64_ds { | 246 | struct compat_msqid64_ds { |
180 | struct compat_ipc64_perm msg_perm; | 247 | struct compat_ipc64_perm msg_perm; |
181 | #ifndef CONFIG_CPU_LITTLE_ENDIAN | 248 | #ifndef CONFIG_CPU_LITTLE_ENDIAN |
182 | compat_ulong_t __unused1; | 249 | compat_ulong_t __unused1; |
183 | #endif | 250 | #endif |
184 | compat_time_t msg_stime; | 251 | compat_time_t msg_stime; |
185 | #ifdef CONFIG_CPU_LITTLE_ENDIAN | 252 | #ifdef CONFIG_CPU_LITTLE_ENDIAN |
186 | compat_ulong_t __unused1; | 253 | compat_ulong_t __unused1; |
187 | #endif | 254 | #endif |
188 | #ifndef CONFIG_CPU_LITTLE_ENDIAN | 255 | #ifndef CONFIG_CPU_LITTLE_ENDIAN |
189 | compat_ulong_t __unused2; | 256 | compat_ulong_t __unused2; |
190 | #endif | 257 | #endif |
191 | compat_time_t msg_rtime; | 258 | compat_time_t msg_rtime; |
192 | #ifdef CONFIG_CPU_LITTLE_ENDIAN | 259 | #ifdef CONFIG_CPU_LITTLE_ENDIAN |
193 | compat_ulong_t __unused2; | 260 | compat_ulong_t __unused2; |
194 | #endif | 261 | #endif |
195 | #ifndef CONFIG_CPU_LITTLE_ENDIAN | 262 | #ifndef CONFIG_CPU_LITTLE_ENDIAN |
196 | compat_ulong_t __unused3; | 263 | compat_ulong_t __unused3; |
197 | #endif | 264 | #endif |
198 | compat_time_t msg_ctime; | 265 | compat_time_t msg_ctime; |
199 | #ifdef CONFIG_CPU_LITTLE_ENDIAN | 266 | #ifdef CONFIG_CPU_LITTLE_ENDIAN |
200 | compat_ulong_t __unused3; | 267 | compat_ulong_t __unused3; |
201 | #endif | 268 | #endif |
202 | compat_ulong_t msg_cbytes; | 269 | compat_ulong_t msg_cbytes; |
203 | compat_ulong_t msg_qnum; | 270 | compat_ulong_t msg_qnum; |
204 | compat_ulong_t msg_qbytes; | 271 | compat_ulong_t msg_qbytes; |
205 | compat_pid_t msg_lspid; | 272 | compat_pid_t msg_lspid; |
206 | compat_pid_t msg_lrpid; | 273 | compat_pid_t msg_lrpid; |
207 | compat_ulong_t __unused4; | 274 | compat_ulong_t __unused4; |
208 | compat_ulong_t __unused5; | 275 | compat_ulong_t __unused5; |
209 | }; | 276 | }; |
210 | 277 | ||
211 | struct compat_shmid64_ds { | 278 | struct compat_shmid64_ds { |
212 | struct compat_ipc64_perm shm_perm; | 279 | struct compat_ipc64_perm shm_perm; |
213 | compat_size_t shm_segsz; | 280 | compat_size_t shm_segsz; |
214 | compat_time_t shm_atime; | 281 | compat_time_t shm_atime; |
215 | compat_time_t shm_dtime; | 282 | compat_time_t shm_dtime; |
216 | compat_time_t shm_ctime; | 283 | compat_time_t shm_ctime; |
217 | compat_pid_t shm_cpid; | 284 | compat_pid_t shm_cpid; |
218 | compat_pid_t shm_lpid; | 285 | compat_pid_t shm_lpid; |
219 | compat_ulong_t shm_nattch; | 286 | compat_ulong_t shm_nattch; |
220 | compat_ulong_t __unused1; | 287 | compat_ulong_t __unused1; |
221 | compat_ulong_t __unused2; | 288 | compat_ulong_t __unused2; |
222 | }; | 289 | }; |
223 | 290 | ||
224 | static inline int is_compat_task(void) | 291 | static inline int is_compat_task(void) |
225 | { | 292 | { |
226 | return test_thread_flag(TIF_32BIT); | 293 | return test_thread_flag(TIF_32BIT); |
227 | } | 294 | } |
228 | 295 | ||
229 | #endif /* _ASM_COMPAT_H */ | 296 | #endif /* _ASM_COMPAT_H */ |
arch/parisc/include/asm/compat.h
1 | #ifndef _ASM_PARISC_COMPAT_H | 1 | #ifndef _ASM_PARISC_COMPAT_H |
2 | #define _ASM_PARISC_COMPAT_H | 2 | #define _ASM_PARISC_COMPAT_H |
3 | /* | 3 | /* |
4 | * Architecture specific compatibility types | 4 | * Architecture specific compatibility types |
5 | */ | 5 | */ |
6 | #include <linux/types.h> | 6 | #include <linux/types.h> |
7 | #include <linux/sched.h> | 7 | #include <linux/sched.h> |
8 | #include <linux/thread_info.h> | 8 | #include <linux/thread_info.h> |
9 | 9 | ||
10 | #define COMPAT_USER_HZ 100 | 10 | #define COMPAT_USER_HZ 100 |
11 | #define COMPAT_UTS_MACHINE "parisc\0\0" | 11 | #define COMPAT_UTS_MACHINE "parisc\0\0" |
12 | 12 | ||
13 | typedef u32 compat_size_t; | 13 | typedef u32 compat_size_t; |
14 | typedef s32 compat_ssize_t; | 14 | typedef s32 compat_ssize_t; |
15 | typedef s32 compat_time_t; | 15 | typedef s32 compat_time_t; |
16 | typedef s32 compat_clock_t; | 16 | typedef s32 compat_clock_t; |
17 | typedef s32 compat_pid_t; | 17 | typedef s32 compat_pid_t; |
18 | typedef u32 __compat_uid_t; | 18 | typedef u32 __compat_uid_t; |
19 | typedef u32 __compat_gid_t; | 19 | typedef u32 __compat_gid_t; |
20 | typedef u32 __compat_uid32_t; | 20 | typedef u32 __compat_uid32_t; |
21 | typedef u32 __compat_gid32_t; | 21 | typedef u32 __compat_gid32_t; |
22 | typedef u16 compat_mode_t; | 22 | typedef u16 compat_mode_t; |
23 | typedef u32 compat_ino_t; | 23 | typedef u32 compat_ino_t; |
24 | typedef u32 compat_dev_t; | 24 | typedef u32 compat_dev_t; |
25 | typedef s32 compat_off_t; | 25 | typedef s32 compat_off_t; |
26 | typedef s64 compat_loff_t; | 26 | typedef s64 compat_loff_t; |
27 | typedef u16 compat_nlink_t; | 27 | typedef u16 compat_nlink_t; |
28 | typedef u16 compat_ipc_pid_t; | 28 | typedef u16 compat_ipc_pid_t; |
29 | typedef s32 compat_daddr_t; | 29 | typedef s32 compat_daddr_t; |
30 | typedef u32 compat_caddr_t; | 30 | typedef u32 compat_caddr_t; |
31 | typedef s32 compat_timer_t; | 31 | typedef s32 compat_timer_t; |
32 | 32 | ||
33 | typedef s32 compat_int_t; | 33 | typedef s32 compat_int_t; |
34 | typedef s32 compat_long_t; | 34 | typedef s32 compat_long_t; |
35 | typedef s64 compat_s64; | 35 | typedef s64 compat_s64; |
36 | typedef u32 compat_uint_t; | 36 | typedef u32 compat_uint_t; |
37 | typedef u32 compat_ulong_t; | 37 | typedef u32 compat_ulong_t; |
38 | typedef u64 compat_u64; | 38 | typedef u64 compat_u64; |
39 | typedef u32 compat_uptr_t; | ||
39 | 40 | ||
40 | struct compat_timespec { | 41 | struct compat_timespec { |
41 | compat_time_t tv_sec; | 42 | compat_time_t tv_sec; |
42 | s32 tv_nsec; | 43 | s32 tv_nsec; |
43 | }; | 44 | }; |
44 | 45 | ||
45 | struct compat_timeval { | 46 | struct compat_timeval { |
46 | compat_time_t tv_sec; | 47 | compat_time_t tv_sec; |
47 | s32 tv_usec; | 48 | s32 tv_usec; |
48 | }; | 49 | }; |
49 | 50 | ||
50 | struct compat_stat { | 51 | struct compat_stat { |
51 | compat_dev_t st_dev; /* dev_t is 32 bits on parisc */ | 52 | compat_dev_t st_dev; /* dev_t is 32 bits on parisc */ |
52 | compat_ino_t st_ino; /* 32 bits */ | 53 | compat_ino_t st_ino; /* 32 bits */ |
53 | compat_mode_t st_mode; /* 16 bits */ | 54 | compat_mode_t st_mode; /* 16 bits */ |
54 | compat_nlink_t st_nlink; /* 16 bits */ | 55 | compat_nlink_t st_nlink; /* 16 bits */ |
55 | u16 st_reserved1; /* old st_uid */ | 56 | u16 st_reserved1; /* old st_uid */ |
56 | u16 st_reserved2; /* old st_gid */ | 57 | u16 st_reserved2; /* old st_gid */ |
57 | compat_dev_t st_rdev; | 58 | compat_dev_t st_rdev; |
58 | compat_off_t st_size; | 59 | compat_off_t st_size; |
59 | compat_time_t st_atime; | 60 | compat_time_t st_atime; |
60 | u32 st_atime_nsec; | 61 | u32 st_atime_nsec; |
61 | compat_time_t st_mtime; | 62 | compat_time_t st_mtime; |
62 | u32 st_mtime_nsec; | 63 | u32 st_mtime_nsec; |
63 | compat_time_t st_ctime; | 64 | compat_time_t st_ctime; |
64 | u32 st_ctime_nsec; | 65 | u32 st_ctime_nsec; |
65 | s32 st_blksize; | 66 | s32 st_blksize; |
66 | s32 st_blocks; | 67 | s32 st_blocks; |
67 | u32 __unused1; /* ACL stuff */ | 68 | u32 __unused1; /* ACL stuff */ |
68 | compat_dev_t __unused2; /* network */ | 69 | compat_dev_t __unused2; /* network */ |
69 | compat_ino_t __unused3; /* network */ | 70 | compat_ino_t __unused3; /* network */ |
70 | u32 __unused4; /* cnodes */ | 71 | u32 __unused4; /* cnodes */ |
71 | u16 __unused5; /* netsite */ | 72 | u16 __unused5; /* netsite */ |
72 | short st_fstype; | 73 | short st_fstype; |
73 | compat_dev_t st_realdev; | 74 | compat_dev_t st_realdev; |
74 | u16 st_basemode; | 75 | u16 st_basemode; |
75 | u16 st_spareshort; | 76 | u16 st_spareshort; |
76 | __compat_uid32_t st_uid; | 77 | __compat_uid32_t st_uid; |
77 | __compat_gid32_t st_gid; | 78 | __compat_gid32_t st_gid; |
78 | u32 st_spare4[3]; | 79 | u32 st_spare4[3]; |
79 | }; | 80 | }; |
80 | 81 | ||
81 | struct compat_flock { | 82 | struct compat_flock { |
82 | short l_type; | 83 | short l_type; |
83 | short l_whence; | 84 | short l_whence; |
84 | compat_off_t l_start; | 85 | compat_off_t l_start; |
85 | compat_off_t l_len; | 86 | compat_off_t l_len; |
86 | compat_pid_t l_pid; | 87 | compat_pid_t l_pid; |
87 | }; | 88 | }; |
88 | 89 | ||
89 | struct compat_flock64 { | 90 | struct compat_flock64 { |
90 | short l_type; | 91 | short l_type; |
91 | short l_whence; | 92 | short l_whence; |
92 | compat_loff_t l_start; | 93 | compat_loff_t l_start; |
93 | compat_loff_t l_len; | 94 | compat_loff_t l_len; |
94 | compat_pid_t l_pid; | 95 | compat_pid_t l_pid; |
95 | }; | 96 | }; |
96 | 97 | ||
97 | struct compat_statfs { | 98 | struct compat_statfs { |
98 | s32 f_type; | 99 | s32 f_type; |
99 | s32 f_bsize; | 100 | s32 f_bsize; |
100 | s32 f_blocks; | 101 | s32 f_blocks; |
101 | s32 f_bfree; | 102 | s32 f_bfree; |
102 | s32 f_bavail; | 103 | s32 f_bavail; |
103 | s32 f_files; | 104 | s32 f_files; |
104 | s32 f_ffree; | 105 | s32 f_ffree; |
105 | __kernel_fsid_t f_fsid; | 106 | __kernel_fsid_t f_fsid; |
106 | s32 f_namelen; | 107 | s32 f_namelen; |
107 | s32 f_frsize; | 108 | s32 f_frsize; |
108 | s32 f_flags; | 109 | s32 f_flags; |
109 | s32 f_spare[4]; | 110 | s32 f_spare[4]; |
110 | }; | 111 | }; |
111 | 112 | ||
112 | struct compat_sigcontext { | 113 | struct compat_sigcontext { |
113 | compat_int_t sc_flags; | 114 | compat_int_t sc_flags; |
114 | compat_int_t sc_gr[32]; /* PSW in sc_gr[0] */ | 115 | compat_int_t sc_gr[32]; /* PSW in sc_gr[0] */ |
115 | u64 sc_fr[32]; | 116 | u64 sc_fr[32]; |
116 | compat_int_t sc_iasq[2]; | 117 | compat_int_t sc_iasq[2]; |
117 | compat_int_t sc_iaoq[2]; | 118 | compat_int_t sc_iaoq[2]; |
118 | compat_int_t sc_sar; /* cr11 */ | 119 | compat_int_t sc_sar; /* cr11 */ |
119 | }; | 120 | }; |
120 | 121 | ||
121 | #define COMPAT_RLIM_INFINITY 0xffffffff | 122 | #define COMPAT_RLIM_INFINITY 0xffffffff |
122 | 123 | ||
123 | typedef u32 compat_old_sigset_t; /* at least 32 bits */ | 124 | typedef u32 compat_old_sigset_t; /* at least 32 bits */ |
124 | 125 | ||
125 | #define _COMPAT_NSIG 64 | 126 | #define _COMPAT_NSIG 64 |
126 | #define _COMPAT_NSIG_BPW 32 | 127 | #define _COMPAT_NSIG_BPW 32 |
127 | 128 | ||
128 | typedef u32 compat_sigset_word; | 129 | typedef u32 compat_sigset_word; |
129 | 130 | ||
131 | typedef union compat_sigval { | ||
132 | compat_int_t sival_int; | ||
133 | compat_uptr_t sival_ptr; | ||
134 | } compat_sigval_t; | ||
135 | |||
136 | typedef struct compat_siginfo { | ||
137 | int si_signo; | ||
138 | int si_errno; | ||
139 | int si_code; | ||
140 | |||
141 | union { | ||
142 | int _pad[128/sizeof(int) - 3]; | ||
143 | |||
144 | /* kill() */ | ||
145 | struct { | ||
146 | unsigned int _pid; /* sender's pid */ | ||
147 | unsigned int _uid; /* sender's uid */ | ||
148 | } _kill; | ||
149 | |||
150 | /* POSIX.1b timers */ | ||
151 | struct { | ||
152 | compat_timer_t _tid; /* timer id */ | ||
153 | int _overrun; /* overrun count */ | ||
154 | char _pad[sizeof(unsigned int) - sizeof(int)]; | ||
155 | compat_sigval_t _sigval; /* same as below */ | ||
156 | int _sys_private; /* not to be passed to user */ | ||
157 | } _timer; | ||
158 | |||
159 | /* POSIX.1b signals */ | ||
160 | struct { | ||
161 | unsigned int _pid; /* sender's pid */ | ||
162 | unsigned int _uid; /* sender's uid */ | ||
163 | compat_sigval_t _sigval; | ||
164 | } _rt; | ||
165 | |||
166 | /* SIGCHLD */ | ||
167 | struct { | ||
168 | unsigned int _pid; /* which child */ | ||
169 | unsigned int _uid; /* sender's uid */ | ||
170 | int _status; /* exit code */ | ||
171 | compat_clock_t _utime; | ||
172 | compat_clock_t _stime; | ||
173 | } _sigchld; | ||
174 | |||
175 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ | ||
176 | struct { | ||
177 | unsigned int _addr; /* faulting insn/memory ref. */ | ||
178 | } _sigfault; | ||
179 | |||
180 | /* SIGPOLL */ | ||
181 | struct { | ||
182 | int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ | ||
183 | int _fd; | ||
184 | } _sigpoll; | ||
185 | } _sifields; | ||
186 | } compat_siginfo_t; | ||
187 | |||
130 | #define COMPAT_OFF_T_MAX 0x7fffffff | 188 | #define COMPAT_OFF_T_MAX 0x7fffffff |
131 | #define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL | 189 | #define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL |
132 | 190 | ||
133 | /* | 191 | /* |
134 | * A pointer passed in from user mode. This should not | 192 | * A pointer passed in from user mode. This should not |
135 | * be used for syscall parameters, just declare them | 193 | * be used for syscall parameters, just declare them |
136 | * as pointers because the syscall entry code will have | 194 | * as pointers because the syscall entry code will have |
137 | * appropriately converted them already. | 195 | * appropriately converted them already. |
138 | */ | 196 | */ |
139 | typedef u32 compat_uptr_t; | ||
140 | 197 | ||
141 | static inline void __user *compat_ptr(compat_uptr_t uptr) | 198 | static inline void __user *compat_ptr(compat_uptr_t uptr) |
142 | { | 199 | { |
143 | return (void __user *)(unsigned long)uptr; | 200 | return (void __user *)(unsigned long)uptr; |
144 | } | 201 | } |
145 | 202 | ||
146 | static inline compat_uptr_t ptr_to_compat(void __user *uptr) | 203 | static inline compat_uptr_t ptr_to_compat(void __user *uptr) |
147 | { | 204 | { |
148 | return (u32)(unsigned long)uptr; | 205 | return (u32)(unsigned long)uptr; |
149 | } | 206 | } |
150 | 207 | ||
151 | static __inline__ void __user *arch_compat_alloc_user_space(long len) | 208 | static __inline__ void __user *arch_compat_alloc_user_space(long len) |
152 | { | 209 | { |
153 | struct pt_regs *regs = ¤t->thread.regs; | 210 | struct pt_regs *regs = ¤t->thread.regs; |
154 | return (void __user *)regs->gr[30]; | 211 | return (void __user *)regs->gr[30]; |
155 | } | 212 | } |
156 | 213 | ||
157 | static inline int __is_compat_task(struct task_struct *t) | 214 | static inline int __is_compat_task(struct task_struct *t) |
158 | { | 215 | { |
159 | return test_ti_thread_flag(task_thread_info(t), TIF_32BIT); | 216 | return test_ti_thread_flag(task_thread_info(t), TIF_32BIT); |
160 | } | 217 | } |
161 | 218 | ||
162 | static inline int is_compat_task(void) | 219 | static inline int is_compat_task(void) |
163 | { | 220 | { |
164 | return __is_compat_task(current); | 221 | return __is_compat_task(current); |
165 | } | 222 | } |
166 | 223 | ||
167 | #endif /* _ASM_PARISC_COMPAT_H */ | 224 | #endif /* _ASM_PARISC_COMPAT_H */ |
arch/parisc/kernel/signal32.h
1 | /* | 1 | /* |
2 | * Copyright (C) 2001 Matthew Wilcox <willy at parisc-linux.org> | 2 | * Copyright (C) 2001 Matthew Wilcox <willy at parisc-linux.org> |
3 | * Copyright (C) 2003 Carlos O'Donell <carlos at parisc-linux.org> | 3 | * Copyright (C) 2003 Carlos O'Donell <carlos at parisc-linux.org> |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify | 5 | * This program is free software; you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License as published by | 6 | * it under the terms of the GNU General Public License as published by |
7 | * the Free Software Foundation; either version 2 of the License, or | 7 | * the Free Software Foundation; either version 2 of the License, or |
8 | * (at your option) any later version. | 8 | * (at your option) any later version. |
9 | * | 9 | * |
10 | * This program is distributed in the hope that it will be useful, | 10 | * This program is distributed in the hope that it will be useful, |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | * GNU General Public License for more details. | 13 | * GNU General Public License for more details. |
14 | * | 14 | * |
15 | * You should have received a copy of the GNU General Public License | 15 | * You should have received a copy of the GNU General Public License |
16 | * along with this program; if not, write to the Free Software | 16 | * along with this program; if not, write to the Free Software |
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
18 | */ | 18 | */ |
19 | #ifndef _PARISC64_KERNEL_SIGNAL32_H | 19 | #ifndef _PARISC64_KERNEL_SIGNAL32_H |
20 | #define _PARISC64_KERNEL_SIGNAL32_H | 20 | #define _PARISC64_KERNEL_SIGNAL32_H |
21 | 21 | ||
22 | #include <linux/compat.h> | 22 | #include <linux/compat.h> |
23 | 23 | ||
24 | typedef compat_uptr_t compat_sighandler_t; | 24 | typedef compat_uptr_t compat_sighandler_t; |
25 | 25 | ||
26 | typedef struct compat_sigaltstack { | 26 | typedef struct compat_sigaltstack { |
27 | compat_uptr_t ss_sp; | 27 | compat_uptr_t ss_sp; |
28 | compat_int_t ss_flags; | 28 | compat_int_t ss_flags; |
29 | compat_size_t ss_size; | 29 | compat_size_t ss_size; |
30 | } compat_stack_t; | 30 | } compat_stack_t; |
31 | 31 | ||
32 | /* Most things should be clean enough to redefine this at will, if care | 32 | /* Most things should be clean enough to redefine this at will, if care |
33 | is taken to make libc match. */ | 33 | is taken to make libc match. */ |
34 | 34 | ||
35 | struct compat_sigaction { | 35 | struct compat_sigaction { |
36 | compat_sighandler_t sa_handler; | 36 | compat_sighandler_t sa_handler; |
37 | compat_uint_t sa_flags; | 37 | compat_uint_t sa_flags; |
38 | compat_sigset_t sa_mask; /* mask last for extensibility */ | 38 | compat_sigset_t sa_mask; /* mask last for extensibility */ |
39 | }; | 39 | }; |
40 | 40 | ||
41 | /* 32-bit ucontext as seen from an 64-bit kernel */ | 41 | /* 32-bit ucontext as seen from an 64-bit kernel */ |
42 | struct compat_ucontext { | 42 | struct compat_ucontext { |
43 | compat_uint_t uc_flags; | 43 | compat_uint_t uc_flags; |
44 | compat_uptr_t uc_link; | 44 | compat_uptr_t uc_link; |
45 | compat_stack_t uc_stack; /* struct compat_sigaltstack (12 bytes)*/ | 45 | compat_stack_t uc_stack; /* struct compat_sigaltstack (12 bytes)*/ |
46 | /* FIXME: Pad out to get uc_mcontext to start at an 8-byte aligned boundary */ | 46 | /* FIXME: Pad out to get uc_mcontext to start at an 8-byte aligned boundary */ |
47 | compat_uint_t pad[1]; | 47 | compat_uint_t pad[1]; |
48 | struct compat_sigcontext uc_mcontext; | 48 | struct compat_sigcontext uc_mcontext; |
49 | compat_sigset_t uc_sigmask; /* mask last for extensibility */ | 49 | compat_sigset_t uc_sigmask; /* mask last for extensibility */ |
50 | }; | 50 | }; |
51 | 51 | ||
52 | /* ELF32 signal handling */ | 52 | /* ELF32 signal handling */ |
53 | 53 | ||
54 | struct k_sigaction32 { | 54 | struct k_sigaction32 { |
55 | struct compat_sigaction sa; | 55 | struct compat_sigaction sa; |
56 | }; | 56 | }; |
57 | 57 | ||
58 | typedef struct compat_siginfo { | ||
59 | int si_signo; | ||
60 | int si_errno; | ||
61 | int si_code; | ||
62 | |||
63 | union { | ||
64 | int _pad[((128/sizeof(int)) - 3)]; | ||
65 | |||
66 | /* kill() */ | ||
67 | struct { | ||
68 | unsigned int _pid; /* sender's pid */ | ||
69 | unsigned int _uid; /* sender's uid */ | ||
70 | } _kill; | ||
71 | |||
72 | /* POSIX.1b timers */ | ||
73 | struct { | ||
74 | compat_timer_t _tid; /* timer id */ | ||
75 | int _overrun; /* overrun count */ | ||
76 | char _pad[sizeof(unsigned int) - sizeof(int)]; | ||
77 | compat_sigval_t _sigval; /* same as below */ | ||
78 | int _sys_private; /* not to be passed to user */ | ||
79 | } _timer; | ||
80 | |||
81 | /* POSIX.1b signals */ | ||
82 | struct { | ||
83 | unsigned int _pid; /* sender's pid */ | ||
84 | unsigned int _uid; /* sender's uid */ | ||
85 | compat_sigval_t _sigval; | ||
86 | } _rt; | ||
87 | |||
88 | /* SIGCHLD */ | ||
89 | struct { | ||
90 | unsigned int _pid; /* which child */ | ||
91 | unsigned int _uid; /* sender's uid */ | ||
92 | int _status; /* exit code */ | ||
93 | compat_clock_t _utime; | ||
94 | compat_clock_t _stime; | ||
95 | } _sigchld; | ||
96 | |||
97 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ | ||
98 | struct { | ||
99 | unsigned int _addr; /* faulting insn/memory ref. */ | ||
100 | } _sigfault; | ||
101 | |||
102 | /* SIGPOLL */ | ||
103 | struct { | ||
104 | int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ | ||
105 | int _fd; | ||
106 | } _sigpoll; | ||
107 | } _sifields; | ||
108 | } compat_siginfo_t; | ||
109 | |||
110 | int copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from); | 58 | int copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from); |
111 | int copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from); | 59 | int copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from); |
112 | 60 | ||
113 | /* In a deft move of uber-hackery, we decide to carry the top half of all | 61 | /* In a deft move of uber-hackery, we decide to carry the top half of all |
114 | * 64-bit registers in a non-portable, non-ABI, hidden structure. | 62 | * 64-bit registers in a non-portable, non-ABI, hidden structure. |
115 | * Userspace can read the hidden structure if it *wants* but is never | 63 | * Userspace can read the hidden structure if it *wants* but is never |
116 | * guaranteed to be in the same place. In fact the uc_sigmask from the | 64 | * guaranteed to be in the same place. In fact the uc_sigmask from the |
117 | * ucontext_t structure may push the hidden register file downards | 65 | * ucontext_t structure may push the hidden register file downards |
118 | */ | 66 | */ |
119 | struct compat_regfile { | 67 | struct compat_regfile { |
120 | /* Upper half of all the 64-bit registers that were truncated | 68 | /* Upper half of all the 64-bit registers that were truncated |
121 | on a copy to a 32-bit userspace */ | 69 | on a copy to a 32-bit userspace */ |
122 | compat_int_t rf_gr[32]; | 70 | compat_int_t rf_gr[32]; |
123 | compat_int_t rf_iasq[2]; | 71 | compat_int_t rf_iasq[2]; |
124 | compat_int_t rf_iaoq[2]; | 72 | compat_int_t rf_iaoq[2]; |
125 | compat_int_t rf_sar; | 73 | compat_int_t rf_sar; |
126 | }; | 74 | }; |
127 | 75 | ||
128 | #define COMPAT_SIGRETURN_TRAMP 4 | 76 | #define COMPAT_SIGRETURN_TRAMP 4 |
129 | #define COMPAT_SIGRESTARTBLOCK_TRAMP 5 | 77 | #define COMPAT_SIGRESTARTBLOCK_TRAMP 5 |
130 | #define COMPAT_TRAMP_SIZE (COMPAT_SIGRETURN_TRAMP + \ | 78 | #define COMPAT_TRAMP_SIZE (COMPAT_SIGRETURN_TRAMP + \ |
131 | COMPAT_SIGRESTARTBLOCK_TRAMP) | 79 | COMPAT_SIGRESTARTBLOCK_TRAMP) |
132 | 80 | ||
133 | struct compat_rt_sigframe { | 81 | struct compat_rt_sigframe { |
134 | /* XXX: Must match trampoline size in arch/parisc/kernel/signal.c | 82 | /* XXX: Must match trampoline size in arch/parisc/kernel/signal.c |
135 | Secondary to that it must protect the ERESTART_RESTARTBLOCK | 83 | Secondary to that it must protect the ERESTART_RESTARTBLOCK |
136 | trampoline we left on the stack (we were bad and didn't | 84 | trampoline we left on the stack (we were bad and didn't |
137 | change sp so we could run really fast.) */ | 85 | change sp so we could run really fast.) */ |
138 | compat_uint_t tramp[COMPAT_TRAMP_SIZE]; | 86 | compat_uint_t tramp[COMPAT_TRAMP_SIZE]; |
139 | compat_siginfo_t info; | 87 | compat_siginfo_t info; |
140 | struct compat_ucontext uc; | 88 | struct compat_ucontext uc; |
141 | /* Hidden location of truncated registers, *must* be last. */ | 89 | /* Hidden location of truncated registers, *must* be last. */ |
142 | struct compat_regfile regs; | 90 | struct compat_regfile regs; |
143 | }; | 91 | }; |
144 | 92 | ||
145 | /* | 93 | /* |
146 | * The 32-bit ABI wants at least 48 bytes for a function call frame: | 94 | * The 32-bit ABI wants at least 48 bytes for a function call frame: |
147 | * 16 bytes for arg0-arg3, and 32 bytes for magic (the only part of | 95 | * 16 bytes for arg0-arg3, and 32 bytes for magic (the only part of |
148 | * which Linux/parisc uses is sp-20 for the saved return pointer...) | 96 | * which Linux/parisc uses is sp-20 for the saved return pointer...) |
149 | * Then, the stack pointer must be rounded to a cache line (64 bytes). | 97 | * Then, the stack pointer must be rounded to a cache line (64 bytes). |
150 | */ | 98 | */ |
151 | #define SIGFRAME32 64 | 99 | #define SIGFRAME32 64 |
152 | #define FUNCTIONCALLFRAME32 48 | 100 | #define FUNCTIONCALLFRAME32 48 |
153 | #define PARISC_RT_SIGFRAME_SIZE32 (((sizeof(struct compat_rt_sigframe) + FUNCTIONCALLFRAME32) + SIGFRAME32) & -SIGFRAME32) | 101 | #define PARISC_RT_SIGFRAME_SIZE32 (((sizeof(struct compat_rt_sigframe) + FUNCTIONCALLFRAME32) + SIGFRAME32) & -SIGFRAME32) |
154 | 102 | ||
155 | void sigset_32to64(sigset_t *s64, compat_sigset_t *s32); | 103 | void sigset_32to64(sigset_t *s64, compat_sigset_t *s32); |
156 | void sigset_64to32(compat_sigset_t *s32, sigset_t *s64); | 104 | void sigset_64to32(compat_sigset_t *s32, sigset_t *s64); |
157 | int do_sigaltstack32 (const compat_stack_t __user *uss32, | 105 | int do_sigaltstack32 (const compat_stack_t __user *uss32, |
158 | compat_stack_t __user *uoss32, unsigned long sp); | 106 | compat_stack_t __user *uoss32, unsigned long sp); |
159 | long restore_sigcontext32(struct compat_sigcontext __user *sc, | 107 | long restore_sigcontext32(struct compat_sigcontext __user *sc, |
160 | struct compat_regfile __user *rf, | 108 | struct compat_regfile __user *rf, |
161 | struct pt_regs *regs); | 109 | struct pt_regs *regs); |
162 | long setup_sigcontext32(struct compat_sigcontext __user *sc, | 110 | long setup_sigcontext32(struct compat_sigcontext __user *sc, |
163 | struct compat_regfile __user *rf, | 111 | struct compat_regfile __user *rf, |
164 | struct pt_regs *regs, int in_syscall); | 112 | struct pt_regs *regs, int in_syscall); |
165 | 113 | ||
166 | #endif | 114 | #endif |
167 | 115 |
arch/powerpc/include/asm/compat.h
1 | #ifndef _ASM_POWERPC_COMPAT_H | 1 | #ifndef _ASM_POWERPC_COMPAT_H |
2 | #define _ASM_POWERPC_COMPAT_H | 2 | #define _ASM_POWERPC_COMPAT_H |
3 | #ifdef __KERNEL__ | 3 | #ifdef __KERNEL__ |
4 | /* | 4 | /* |
5 | * Architecture specific compatibility types | 5 | * Architecture specific compatibility types |
6 | */ | 6 | */ |
7 | #include <linux/types.h> | 7 | #include <linux/types.h> |
8 | #include <linux/sched.h> | 8 | #include <linux/sched.h> |
9 | 9 | ||
10 | #define COMPAT_USER_HZ 100 | 10 | #define COMPAT_USER_HZ 100 |
11 | #define COMPAT_UTS_MACHINE "ppc\0\0" | 11 | #define COMPAT_UTS_MACHINE "ppc\0\0" |
12 | 12 | ||
13 | typedef u32 compat_size_t; | 13 | typedef u32 compat_size_t; |
14 | typedef s32 compat_ssize_t; | 14 | typedef s32 compat_ssize_t; |
15 | typedef s32 compat_time_t; | 15 | typedef s32 compat_time_t; |
16 | typedef s32 compat_clock_t; | 16 | typedef s32 compat_clock_t; |
17 | typedef s32 compat_pid_t; | 17 | typedef s32 compat_pid_t; |
18 | typedef u32 __compat_uid_t; | 18 | typedef u32 __compat_uid_t; |
19 | typedef u32 __compat_gid_t; | 19 | typedef u32 __compat_gid_t; |
20 | typedef u32 __compat_uid32_t; | 20 | typedef u32 __compat_uid32_t; |
21 | typedef u32 __compat_gid32_t; | 21 | typedef u32 __compat_gid32_t; |
22 | typedef u32 compat_mode_t; | 22 | typedef u32 compat_mode_t; |
23 | typedef u32 compat_ino_t; | 23 | typedef u32 compat_ino_t; |
24 | typedef u32 compat_dev_t; | 24 | typedef u32 compat_dev_t; |
25 | typedef s32 compat_off_t; | 25 | typedef s32 compat_off_t; |
26 | typedef s64 compat_loff_t; | 26 | typedef s64 compat_loff_t; |
27 | typedef s16 compat_nlink_t; | 27 | typedef s16 compat_nlink_t; |
28 | typedef u16 compat_ipc_pid_t; | 28 | typedef u16 compat_ipc_pid_t; |
29 | typedef s32 compat_daddr_t; | 29 | typedef s32 compat_daddr_t; |
30 | typedef u32 compat_caddr_t; | 30 | typedef u32 compat_caddr_t; |
31 | typedef __kernel_fsid_t compat_fsid_t; | 31 | typedef __kernel_fsid_t compat_fsid_t; |
32 | typedef s32 compat_key_t; | 32 | typedef s32 compat_key_t; |
33 | typedef s32 compat_timer_t; | 33 | typedef s32 compat_timer_t; |
34 | 34 | ||
35 | typedef s32 compat_int_t; | 35 | typedef s32 compat_int_t; |
36 | typedef s32 compat_long_t; | 36 | typedef s32 compat_long_t; |
37 | typedef s64 compat_s64; | 37 | typedef s64 compat_s64; |
38 | typedef u32 compat_uint_t; | 38 | typedef u32 compat_uint_t; |
39 | typedef u32 compat_ulong_t; | 39 | typedef u32 compat_ulong_t; |
40 | typedef u64 compat_u64; | 40 | typedef u64 compat_u64; |
41 | typedef u32 compat_uptr_t; | ||
41 | 42 | ||
42 | struct compat_timespec { | 43 | struct compat_timespec { |
43 | compat_time_t tv_sec; | 44 | compat_time_t tv_sec; |
44 | s32 tv_nsec; | 45 | s32 tv_nsec; |
45 | }; | 46 | }; |
46 | 47 | ||
47 | struct compat_timeval { | 48 | struct compat_timeval { |
48 | compat_time_t tv_sec; | 49 | compat_time_t tv_sec; |
49 | s32 tv_usec; | 50 | s32 tv_usec; |
50 | }; | 51 | }; |
51 | 52 | ||
52 | struct compat_stat { | 53 | struct compat_stat { |
53 | compat_dev_t st_dev; | 54 | compat_dev_t st_dev; |
54 | compat_ino_t st_ino; | 55 | compat_ino_t st_ino; |
55 | compat_mode_t st_mode; | 56 | compat_mode_t st_mode; |
56 | compat_nlink_t st_nlink; | 57 | compat_nlink_t st_nlink; |
57 | __compat_uid32_t st_uid; | 58 | __compat_uid32_t st_uid; |
58 | __compat_gid32_t st_gid; | 59 | __compat_gid32_t st_gid; |
59 | compat_dev_t st_rdev; | 60 | compat_dev_t st_rdev; |
60 | compat_off_t st_size; | 61 | compat_off_t st_size; |
61 | compat_off_t st_blksize; | 62 | compat_off_t st_blksize; |
62 | compat_off_t st_blocks; | 63 | compat_off_t st_blocks; |
63 | compat_time_t st_atime; | 64 | compat_time_t st_atime; |
64 | u32 st_atime_nsec; | 65 | u32 st_atime_nsec; |
65 | compat_time_t st_mtime; | 66 | compat_time_t st_mtime; |
66 | u32 st_mtime_nsec; | 67 | u32 st_mtime_nsec; |
67 | compat_time_t st_ctime; | 68 | compat_time_t st_ctime; |
68 | u32 st_ctime_nsec; | 69 | u32 st_ctime_nsec; |
69 | u32 __unused4[2]; | 70 | u32 __unused4[2]; |
70 | }; | 71 | }; |
71 | 72 | ||
72 | struct compat_flock { | 73 | struct compat_flock { |
73 | short l_type; | 74 | short l_type; |
74 | short l_whence; | 75 | short l_whence; |
75 | compat_off_t l_start; | 76 | compat_off_t l_start; |
76 | compat_off_t l_len; | 77 | compat_off_t l_len; |
77 | compat_pid_t l_pid; | 78 | compat_pid_t l_pid; |
78 | }; | 79 | }; |
79 | 80 | ||
80 | #define F_GETLK64 12 /* using 'struct flock64' */ | 81 | #define F_GETLK64 12 /* using 'struct flock64' */ |
81 | #define F_SETLK64 13 | 82 | #define F_SETLK64 13 |
82 | #define F_SETLKW64 14 | 83 | #define F_SETLKW64 14 |
83 | 84 | ||
84 | struct compat_flock64 { | 85 | struct compat_flock64 { |
85 | short l_type; | 86 | short l_type; |
86 | short l_whence; | 87 | short l_whence; |
87 | compat_loff_t l_start; | 88 | compat_loff_t l_start; |
88 | compat_loff_t l_len; | 89 | compat_loff_t l_len; |
89 | compat_pid_t l_pid; | 90 | compat_pid_t l_pid; |
90 | }; | 91 | }; |
91 | 92 | ||
92 | struct compat_statfs { | 93 | struct compat_statfs { |
93 | int f_type; | 94 | int f_type; |
94 | int f_bsize; | 95 | int f_bsize; |
95 | int f_blocks; | 96 | int f_blocks; |
96 | int f_bfree; | 97 | int f_bfree; |
97 | int f_bavail; | 98 | int f_bavail; |
98 | int f_files; | 99 | int f_files; |
99 | int f_ffree; | 100 | int f_ffree; |
100 | compat_fsid_t f_fsid; | 101 | compat_fsid_t f_fsid; |
101 | int f_namelen; /* SunOS ignores this field. */ | 102 | int f_namelen; /* SunOS ignores this field. */ |
102 | int f_frsize; | 103 | int f_frsize; |
103 | int f_flags; | 104 | int f_flags; |
104 | int f_spare[4]; | 105 | int f_spare[4]; |
105 | }; | 106 | }; |
106 | 107 | ||
107 | #define COMPAT_RLIM_OLD_INFINITY 0x7fffffff | 108 | #define COMPAT_RLIM_OLD_INFINITY 0x7fffffff |
108 | #define COMPAT_RLIM_INFINITY 0xffffffff | 109 | #define COMPAT_RLIM_INFINITY 0xffffffff |
109 | 110 | ||
110 | typedef u32 compat_old_sigset_t; | 111 | typedef u32 compat_old_sigset_t; |
111 | 112 | ||
112 | #define _COMPAT_NSIG 64 | 113 | #define _COMPAT_NSIG 64 |
113 | #define _COMPAT_NSIG_BPW 32 | 114 | #define _COMPAT_NSIG_BPW 32 |
114 | 115 | ||
115 | typedef u32 compat_sigset_word; | 116 | typedef u32 compat_sigset_word; |
116 | 117 | ||
118 | typedef union compat_sigval { | ||
119 | compat_int_t sival_int; | ||
120 | compat_uptr_t sival_ptr; | ||
121 | } compat_sigval_t; | ||
122 | |||
123 | #define SI_PAD_SIZE32 (128/sizeof(int) - 3) | ||
124 | |||
125 | typedef struct compat_siginfo { | ||
126 | int si_signo; | ||
127 | int si_errno; | ||
128 | int si_code; | ||
129 | |||
130 | union { | ||
131 | int _pad[SI_PAD_SIZE32]; | ||
132 | |||
133 | /* kill() */ | ||
134 | struct { | ||
135 | compat_pid_t _pid; /* sender's pid */ | ||
136 | __compat_uid_t _uid; /* sender's uid */ | ||
137 | } _kill; | ||
138 | |||
139 | /* POSIX.1b timers */ | ||
140 | struct { | ||
141 | compat_timer_t _tid; /* timer id */ | ||
142 | int _overrun; /* overrun count */ | ||
143 | compat_sigval_t _sigval; /* same as below */ | ||
144 | int _sys_private; /* not to be passed to user */ | ||
145 | } _timer; | ||
146 | |||
147 | /* POSIX.1b signals */ | ||
148 | struct { | ||
149 | compat_pid_t _pid; /* sender's pid */ | ||
150 | __compat_uid_t _uid; /* sender's uid */ | ||
151 | compat_sigval_t _sigval; | ||
152 | } _rt; | ||
153 | |||
154 | /* SIGCHLD */ | ||
155 | struct { | ||
156 | compat_pid_t _pid; /* which child */ | ||
157 | __compat_uid_t _uid; /* sender's uid */ | ||
158 | int _status; /* exit code */ | ||
159 | compat_clock_t _utime; | ||
160 | compat_clock_t _stime; | ||
161 | } _sigchld; | ||
162 | |||
163 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGEMT */ | ||
164 | struct { | ||
165 | unsigned int _addr; /* faulting insn/memory ref. */ | ||
166 | } _sigfault; | ||
167 | |||
168 | /* SIGPOLL */ | ||
169 | struct { | ||
170 | int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ | ||
171 | int _fd; | ||
172 | } _sigpoll; | ||
173 | } _sifields; | ||
174 | } compat_siginfo_t; | ||
175 | |||
117 | #define COMPAT_OFF_T_MAX 0x7fffffff | 176 | #define COMPAT_OFF_T_MAX 0x7fffffff |
118 | #define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL | 177 | #define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL |
119 | 178 | ||
120 | /* | 179 | /* |
121 | * A pointer passed in from user mode. This should not | 180 | * A pointer passed in from user mode. This should not |
122 | * be used for syscall parameters, just declare them | 181 | * be used for syscall parameters, just declare them |
123 | * as pointers because the syscall entry code will have | 182 | * as pointers because the syscall entry code will have |
124 | * appropriately converted them already. | 183 | * appropriately converted them already. |
125 | */ | 184 | */ |
126 | typedef u32 compat_uptr_t; | ||
127 | 185 | ||
128 | static inline void __user *compat_ptr(compat_uptr_t uptr) | 186 | static inline void __user *compat_ptr(compat_uptr_t uptr) |
129 | { | 187 | { |
130 | return (void __user *)(unsigned long)uptr; | 188 | return (void __user *)(unsigned long)uptr; |
131 | } | 189 | } |
132 | 190 | ||
133 | static inline compat_uptr_t ptr_to_compat(void __user *uptr) | 191 | static inline compat_uptr_t ptr_to_compat(void __user *uptr) |
134 | { | 192 | { |
135 | return (u32)(unsigned long)uptr; | 193 | return (u32)(unsigned long)uptr; |
136 | } | 194 | } |
137 | 195 | ||
138 | static inline void __user *arch_compat_alloc_user_space(long len) | 196 | static inline void __user *arch_compat_alloc_user_space(long len) |
139 | { | 197 | { |
140 | struct pt_regs *regs = current->thread.regs; | 198 | struct pt_regs *regs = current->thread.regs; |
141 | unsigned long usp = regs->gpr[1]; | 199 | unsigned long usp = regs->gpr[1]; |
142 | 200 | ||
143 | /* | 201 | /* |
144 | * We can't access below the stack pointer in the 32bit ABI and | 202 | * We can't access below the stack pointer in the 32bit ABI and |
145 | * can access 288 bytes in the 64bit ABI | 203 | * can access 288 bytes in the 64bit ABI |
146 | */ | 204 | */ |
147 | if (!is_32bit_task()) | 205 | if (!is_32bit_task()) |
148 | usp -= 288; | 206 | usp -= 288; |
149 | 207 | ||
150 | return (void __user *) (usp - len); | 208 | return (void __user *) (usp - len); |
151 | } | 209 | } |
152 | 210 | ||
153 | /* | 211 | /* |
154 | * ipc64_perm is actually 32/64bit clean but since the compat layer refers to | 212 | * ipc64_perm is actually 32/64bit clean but since the compat layer refers to |
155 | * it we may as well define it. | 213 | * it we may as well define it. |
156 | */ | 214 | */ |
157 | struct compat_ipc64_perm { | 215 | struct compat_ipc64_perm { |
158 | compat_key_t key; | 216 | compat_key_t key; |
159 | __compat_uid_t uid; | 217 | __compat_uid_t uid; |
160 | __compat_gid_t gid; | 218 | __compat_gid_t gid; |
161 | __compat_uid_t cuid; | 219 | __compat_uid_t cuid; |
162 | __compat_gid_t cgid; | 220 | __compat_gid_t cgid; |
163 | compat_mode_t mode; | 221 | compat_mode_t mode; |
164 | unsigned int seq; | 222 | unsigned int seq; |
165 | unsigned int __pad2; | 223 | unsigned int __pad2; |
166 | unsigned long __unused1; /* yes they really are 64bit pads */ | 224 | unsigned long __unused1; /* yes they really are 64bit pads */ |
167 | unsigned long __unused2; | 225 | unsigned long __unused2; |
168 | }; | 226 | }; |
169 | 227 | ||
170 | struct compat_semid64_ds { | 228 | struct compat_semid64_ds { |
171 | struct compat_ipc64_perm sem_perm; | 229 | struct compat_ipc64_perm sem_perm; |
172 | unsigned int __unused1; | 230 | unsigned int __unused1; |
173 | compat_time_t sem_otime; | 231 | compat_time_t sem_otime; |
174 | unsigned int __unused2; | 232 | unsigned int __unused2; |
175 | compat_time_t sem_ctime; | 233 | compat_time_t sem_ctime; |
176 | compat_ulong_t sem_nsems; | 234 | compat_ulong_t sem_nsems; |
177 | compat_ulong_t __unused3; | 235 | compat_ulong_t __unused3; |
178 | compat_ulong_t __unused4; | 236 | compat_ulong_t __unused4; |
179 | }; | 237 | }; |
180 | 238 | ||
181 | struct compat_msqid64_ds { | 239 | struct compat_msqid64_ds { |
182 | struct compat_ipc64_perm msg_perm; | 240 | struct compat_ipc64_perm msg_perm; |
183 | unsigned int __unused1; | 241 | unsigned int __unused1; |
184 | compat_time_t msg_stime; | 242 | compat_time_t msg_stime; |
185 | unsigned int __unused2; | 243 | unsigned int __unused2; |
186 | compat_time_t msg_rtime; | 244 | compat_time_t msg_rtime; |
187 | unsigned int __unused3; | 245 | unsigned int __unused3; |
188 | compat_time_t msg_ctime; | 246 | compat_time_t msg_ctime; |
189 | compat_ulong_t msg_cbytes; | 247 | compat_ulong_t msg_cbytes; |
190 | compat_ulong_t msg_qnum; | 248 | compat_ulong_t msg_qnum; |
191 | compat_ulong_t msg_qbytes; | 249 | compat_ulong_t msg_qbytes; |
192 | compat_pid_t msg_lspid; | 250 | compat_pid_t msg_lspid; |
193 | compat_pid_t msg_lrpid; | 251 | compat_pid_t msg_lrpid; |
194 | compat_ulong_t __unused4; | 252 | compat_ulong_t __unused4; |
195 | compat_ulong_t __unused5; | 253 | compat_ulong_t __unused5; |
196 | }; | 254 | }; |
197 | 255 | ||
198 | struct compat_shmid64_ds { | 256 | struct compat_shmid64_ds { |
199 | struct compat_ipc64_perm shm_perm; | 257 | struct compat_ipc64_perm shm_perm; |
200 | unsigned int __unused1; | 258 | unsigned int __unused1; |
201 | compat_time_t shm_atime; | 259 | compat_time_t shm_atime; |
202 | unsigned int __unused2; | 260 | unsigned int __unused2; |
203 | compat_time_t shm_dtime; | 261 | compat_time_t shm_dtime; |
204 | unsigned int __unused3; | 262 | unsigned int __unused3; |
205 | compat_time_t shm_ctime; | 263 | compat_time_t shm_ctime; |
206 | unsigned int __unused4; | 264 | unsigned int __unused4; |
207 | compat_size_t shm_segsz; | 265 | compat_size_t shm_segsz; |
208 | compat_pid_t shm_cpid; | 266 | compat_pid_t shm_cpid; |
209 | compat_pid_t shm_lpid; | 267 | compat_pid_t shm_lpid; |
210 | compat_ulong_t shm_nattch; | 268 | compat_ulong_t shm_nattch; |
211 | compat_ulong_t __unused5; | 269 | compat_ulong_t __unused5; |
212 | compat_ulong_t __unused6; | 270 | compat_ulong_t __unused6; |
213 | }; | 271 | }; |
214 | 272 | ||
215 | static inline int is_compat_task(void) | 273 | static inline int is_compat_task(void) |
216 | { | 274 | { |
217 | return is_32bit_task(); | 275 | return is_32bit_task(); |
218 | } | 276 | } |
219 | 277 | ||
220 | #endif /* __KERNEL__ */ | 278 | #endif /* __KERNEL__ */ |
221 | #endif /* _ASM_POWERPC_COMPAT_H */ | 279 | #endif /* _ASM_POWERPC_COMPAT_H */ |
arch/powerpc/include/asm/siginfo.h
1 | #ifndef _ASM_POWERPC_SIGINFO_H | 1 | #ifndef _ASM_POWERPC_SIGINFO_H |
2 | #define _ASM_POWERPC_SIGINFO_H | 2 | #define _ASM_POWERPC_SIGINFO_H |
3 | 3 | ||
4 | /* | 4 | /* |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
6 | * modify it under the terms of the GNU General Public License | 6 | * modify it under the terms of the GNU General Public License |
7 | * as published by the Free Software Foundation; either version | 7 | * as published by the Free Software Foundation; either version |
8 | * 2 of the License, or (at your option) any later version. | 8 | * 2 of the License, or (at your option) any later version. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #ifdef __powerpc64__ | 11 | #ifdef __powerpc64__ |
12 | # define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int)) | 12 | # define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int)) |
13 | # define SI_PAD_SIZE32 ((SI_MAX_SIZE/sizeof(int)) - 3) | ||
14 | #endif | 13 | #endif |
15 | 14 | ||
16 | #include <asm-generic/siginfo.h> | 15 | #include <asm-generic/siginfo.h> |
17 | 16 | ||
18 | #undef NSIGTRAP | 17 | #undef NSIGTRAP |
19 | #define NSIGTRAP 4 | 18 | #define NSIGTRAP 4 |
20 | 19 | ||
21 | #endif /* _ASM_POWERPC_SIGINFO_H */ | 20 | #endif /* _ASM_POWERPC_SIGINFO_H */ |
22 | 21 |
arch/powerpc/kernel/ppc32.h
1 | #ifndef _PPC64_PPC32_H | 1 | #ifndef _PPC64_PPC32_H |
2 | #define _PPC64_PPC32_H | 2 | #define _PPC64_PPC32_H |
3 | 3 | ||
4 | #include <linux/compat.h> | 4 | #include <linux/compat.h> |
5 | #include <asm/siginfo.h> | 5 | #include <asm/siginfo.h> |
6 | #include <asm/signal.h> | 6 | #include <asm/signal.h> |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Data types and macros for providing 32b PowerPC support. | 9 | * Data types and macros for providing 32b PowerPC support. |
10 | * | 10 | * |
11 | * This program is free software; you can redistribute it and/or | 11 | * This program is free software; you can redistribute it and/or |
12 | * modify it under the terms of the GNU General Public License | 12 | * modify it under the terms of the GNU General Public License |
13 | * as published by the Free Software Foundation; either version | 13 | * as published by the Free Software Foundation; either version |
14 | * 2 of the License, or (at your option) any later version. | 14 | * 2 of the License, or (at your option) any later version. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | /* These are here to support 32-bit syscalls on a 64-bit kernel. */ | 17 | /* These are here to support 32-bit syscalls on a 64-bit kernel. */ |
18 | 18 | ||
19 | typedef struct compat_siginfo { | ||
20 | int si_signo; | ||
21 | int si_errno; | ||
22 | int si_code; | ||
23 | |||
24 | union { | ||
25 | int _pad[SI_PAD_SIZE32]; | ||
26 | |||
27 | /* kill() */ | ||
28 | struct { | ||
29 | compat_pid_t _pid; /* sender's pid */ | ||
30 | compat_uid_t _uid; /* sender's uid */ | ||
31 | } _kill; | ||
32 | |||
33 | /* POSIX.1b timers */ | ||
34 | struct { | ||
35 | compat_timer_t _tid; /* timer id */ | ||
36 | int _overrun; /* overrun count */ | ||
37 | compat_sigval_t _sigval; /* same as below */ | ||
38 | int _sys_private; /* not to be passed to user */ | ||
39 | } _timer; | ||
40 | |||
41 | /* POSIX.1b signals */ | ||
42 | struct { | ||
43 | compat_pid_t _pid; /* sender's pid */ | ||
44 | compat_uid_t _uid; /* sender's uid */ | ||
45 | compat_sigval_t _sigval; | ||
46 | } _rt; | ||
47 | |||
48 | /* SIGCHLD */ | ||
49 | struct { | ||
50 | compat_pid_t _pid; /* which child */ | ||
51 | compat_uid_t _uid; /* sender's uid */ | ||
52 | int _status; /* exit code */ | ||
53 | compat_clock_t _utime; | ||
54 | compat_clock_t _stime; | ||
55 | } _sigchld; | ||
56 | |||
57 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGEMT */ | ||
58 | struct { | ||
59 | unsigned int _addr; /* faulting insn/memory ref. */ | ||
60 | } _sigfault; | ||
61 | |||
62 | /* SIGPOLL */ | ||
63 | struct { | ||
64 | int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ | ||
65 | int _fd; | ||
66 | } _sigpoll; | ||
67 | } _sifields; | ||
68 | } compat_siginfo_t; | ||
69 | |||
70 | #define __old_sigaction32 old_sigaction32 | 19 | #define __old_sigaction32 old_sigaction32 |
71 | 20 | ||
72 | struct __old_sigaction32 { | 21 | struct __old_sigaction32 { |
73 | compat_uptr_t sa_handler; | 22 | compat_uptr_t sa_handler; |
74 | compat_old_sigset_t sa_mask; | 23 | compat_old_sigset_t sa_mask; |
75 | unsigned int sa_flags; | 24 | unsigned int sa_flags; |
76 | compat_uptr_t sa_restorer; /* not used by Linux/SPARC yet */ | 25 | compat_uptr_t sa_restorer; /* not used by Linux/SPARC yet */ |
77 | }; | 26 | }; |
78 | 27 | ||
79 | 28 | ||
80 | 29 | ||
81 | struct sigaction32 { | 30 | struct sigaction32 { |
82 | compat_uptr_t sa_handler; /* Really a pointer, but need to deal with 32 bits */ | 31 | compat_uptr_t sa_handler; /* Really a pointer, but need to deal with 32 bits */ |
83 | unsigned int sa_flags; | 32 | unsigned int sa_flags; |
84 | compat_uptr_t sa_restorer; /* Another 32 bit pointer */ | 33 | compat_uptr_t sa_restorer; /* Another 32 bit pointer */ |
85 | compat_sigset_t sa_mask; /* A 32 bit mask */ | 34 | compat_sigset_t sa_mask; /* A 32 bit mask */ |
86 | }; | 35 | }; |
87 | 36 | ||
88 | typedef struct sigaltstack_32 { | 37 | typedef struct sigaltstack_32 { |
89 | unsigned int ss_sp; | 38 | unsigned int ss_sp; |
90 | int ss_flags; | 39 | int ss_flags; |
91 | compat_size_t ss_size; | 40 | compat_size_t ss_size; |
92 | } stack_32_t; | 41 | } stack_32_t; |
93 | 42 | ||
94 | struct pt_regs32 { | 43 | struct pt_regs32 { |
95 | unsigned int gpr[32]; | 44 | unsigned int gpr[32]; |
96 | unsigned int nip; | 45 | unsigned int nip; |
97 | unsigned int msr; | 46 | unsigned int msr; |
98 | unsigned int orig_gpr3; /* Used for restarting system calls */ | 47 | unsigned int orig_gpr3; /* Used for restarting system calls */ |
99 | unsigned int ctr; | 48 | unsigned int ctr; |
100 | unsigned int link; | 49 | unsigned int link; |
101 | unsigned int xer; | 50 | unsigned int xer; |
102 | unsigned int ccr; | 51 | unsigned int ccr; |
103 | unsigned int mq; /* 601 only (not used at present) */ | 52 | unsigned int mq; /* 601 only (not used at present) */ |
104 | unsigned int trap; /* Reason for being here */ | 53 | unsigned int trap; /* Reason for being here */ |
105 | unsigned int dar; /* Fault registers */ | 54 | unsigned int dar; /* Fault registers */ |
106 | unsigned int dsisr; | 55 | unsigned int dsisr; |
107 | unsigned int result; /* Result of a system call */ | 56 | unsigned int result; /* Result of a system call */ |
108 | }; | 57 | }; |
109 | 58 | ||
110 | struct sigcontext32 { | 59 | struct sigcontext32 { |
111 | unsigned int _unused[4]; | 60 | unsigned int _unused[4]; |
112 | int signal; | 61 | int signal; |
113 | compat_uptr_t handler; | 62 | compat_uptr_t handler; |
114 | unsigned int oldmask; | 63 | unsigned int oldmask; |
115 | compat_uptr_t regs; /* 4 byte pointer to the pt_regs32 structure. */ | 64 | compat_uptr_t regs; /* 4 byte pointer to the pt_regs32 structure. */ |
116 | }; | 65 | }; |
117 | 66 | ||
118 | struct mcontext32 { | 67 | struct mcontext32 { |
119 | elf_gregset_t32 mc_gregs; | 68 | elf_gregset_t32 mc_gregs; |
120 | elf_fpregset_t mc_fregs; | 69 | elf_fpregset_t mc_fregs; |
121 | unsigned int mc_pad[2]; | 70 | unsigned int mc_pad[2]; |
122 | elf_vrregset_t32 mc_vregs __attribute__((__aligned__(16))); | 71 | elf_vrregset_t32 mc_vregs __attribute__((__aligned__(16))); |
123 | elf_vsrreghalf_t32 mc_vsregs __attribute__((__aligned__(16))); | 72 | elf_vsrreghalf_t32 mc_vsregs __attribute__((__aligned__(16))); |
124 | }; | 73 | }; |
125 | 74 | ||
126 | struct ucontext32 { | 75 | struct ucontext32 { |
127 | unsigned int uc_flags; | 76 | unsigned int uc_flags; |
128 | unsigned int uc_link; | 77 | unsigned int uc_link; |
129 | stack_32_t uc_stack; | 78 | stack_32_t uc_stack; |
130 | int uc_pad[7]; | 79 | int uc_pad[7]; |
131 | compat_uptr_t uc_regs; /* points to uc_mcontext field */ | 80 | compat_uptr_t uc_regs; /* points to uc_mcontext field */ |
132 | compat_sigset_t uc_sigmask; /* mask last for extensibility */ | 81 | compat_sigset_t uc_sigmask; /* mask last for extensibility */ |
133 | /* glibc has 1024-bit signal masks, ours are 64-bit */ | 82 | /* glibc has 1024-bit signal masks, ours are 64-bit */ |
134 | int uc_maskext[30]; | 83 | int uc_maskext[30]; |
135 | int uc_pad2[3]; | 84 | int uc_pad2[3]; |
136 | struct mcontext32 uc_mcontext; | 85 | struct mcontext32 uc_mcontext; |
137 | }; | 86 | }; |
138 | 87 | ||
139 | #endif /* _PPC64_PPC32_H */ | 88 | #endif /* _PPC64_PPC32_H */ |
140 | 89 |
arch/s390/include/asm/compat.h
1 | #ifndef _ASM_S390X_COMPAT_H | 1 | #ifndef _ASM_S390X_COMPAT_H |
2 | #define _ASM_S390X_COMPAT_H | 2 | #define _ASM_S390X_COMPAT_H |
3 | /* | 3 | /* |
4 | * Architecture specific compatibility types | 4 | * Architecture specific compatibility types |
5 | */ | 5 | */ |
6 | #include <linux/types.h> | 6 | #include <linux/types.h> |
7 | #include <linux/sched.h> | 7 | #include <linux/sched.h> |
8 | #include <linux/thread_info.h> | 8 | #include <linux/thread_info.h> |
9 | 9 | ||
10 | #define PSW32_MASK_PER 0x40000000UL | 10 | #define PSW32_MASK_PER 0x40000000UL |
11 | #define PSW32_MASK_DAT 0x04000000UL | 11 | #define PSW32_MASK_DAT 0x04000000UL |
12 | #define PSW32_MASK_IO 0x02000000UL | 12 | #define PSW32_MASK_IO 0x02000000UL |
13 | #define PSW32_MASK_EXT 0x01000000UL | 13 | #define PSW32_MASK_EXT 0x01000000UL |
14 | #define PSW32_MASK_KEY 0x00F00000UL | 14 | #define PSW32_MASK_KEY 0x00F00000UL |
15 | #define PSW32_MASK_BASE 0x00080000UL /* Always one */ | 15 | #define PSW32_MASK_BASE 0x00080000UL /* Always one */ |
16 | #define PSW32_MASK_MCHECK 0x00040000UL | 16 | #define PSW32_MASK_MCHECK 0x00040000UL |
17 | #define PSW32_MASK_WAIT 0x00020000UL | 17 | #define PSW32_MASK_WAIT 0x00020000UL |
18 | #define PSW32_MASK_PSTATE 0x00010000UL | 18 | #define PSW32_MASK_PSTATE 0x00010000UL |
19 | #define PSW32_MASK_ASC 0x0000C000UL | 19 | #define PSW32_MASK_ASC 0x0000C000UL |
20 | #define PSW32_MASK_CC 0x00003000UL | 20 | #define PSW32_MASK_CC 0x00003000UL |
21 | #define PSW32_MASK_PM 0x00000f00UL | 21 | #define PSW32_MASK_PM 0x00000f00UL |
22 | 22 | ||
23 | #define PSW32_MASK_USER 0x00003F00UL | 23 | #define PSW32_MASK_USER 0x00003F00UL |
24 | 24 | ||
25 | #define PSW32_ADDR_AMODE 0x80000000UL | 25 | #define PSW32_ADDR_AMODE 0x80000000UL |
26 | #define PSW32_ADDR_INSN 0x7FFFFFFFUL | 26 | #define PSW32_ADDR_INSN 0x7FFFFFFFUL |
27 | 27 | ||
28 | #define PSW32_DEFAULT_KEY (((u32) PAGE_DEFAULT_ACC) << 20) | 28 | #define PSW32_DEFAULT_KEY (((u32) PAGE_DEFAULT_ACC) << 20) |
29 | 29 | ||
30 | #define PSW32_ASC_PRIMARY 0x00000000UL | 30 | #define PSW32_ASC_PRIMARY 0x00000000UL |
31 | #define PSW32_ASC_ACCREG 0x00004000UL | 31 | #define PSW32_ASC_ACCREG 0x00004000UL |
32 | #define PSW32_ASC_SECONDARY 0x00008000UL | 32 | #define PSW32_ASC_SECONDARY 0x00008000UL |
33 | #define PSW32_ASC_HOME 0x0000C000UL | 33 | #define PSW32_ASC_HOME 0x0000C000UL |
34 | 34 | ||
35 | extern u32 psw32_user_bits; | 35 | extern u32 psw32_user_bits; |
36 | 36 | ||
37 | #define COMPAT_USER_HZ 100 | 37 | #define COMPAT_USER_HZ 100 |
38 | #define COMPAT_UTS_MACHINE "s390\0\0\0\0" | 38 | #define COMPAT_UTS_MACHINE "s390\0\0\0\0" |
39 | 39 | ||
40 | typedef u32 compat_size_t; | 40 | typedef u32 compat_size_t; |
41 | typedef s32 compat_ssize_t; | 41 | typedef s32 compat_ssize_t; |
42 | typedef s32 compat_time_t; | 42 | typedef s32 compat_time_t; |
43 | typedef s32 compat_clock_t; | 43 | typedef s32 compat_clock_t; |
44 | typedef s32 compat_pid_t; | 44 | typedef s32 compat_pid_t; |
45 | typedef u16 __compat_uid_t; | 45 | typedef u16 __compat_uid_t; |
46 | typedef u16 __compat_gid_t; | 46 | typedef u16 __compat_gid_t; |
47 | typedef u32 __compat_uid32_t; | 47 | typedef u32 __compat_uid32_t; |
48 | typedef u32 __compat_gid32_t; | 48 | typedef u32 __compat_gid32_t; |
49 | typedef u16 compat_mode_t; | 49 | typedef u16 compat_mode_t; |
50 | typedef u32 compat_ino_t; | 50 | typedef u32 compat_ino_t; |
51 | typedef u16 compat_dev_t; | 51 | typedef u16 compat_dev_t; |
52 | typedef s32 compat_off_t; | 52 | typedef s32 compat_off_t; |
53 | typedef s64 compat_loff_t; | 53 | typedef s64 compat_loff_t; |
54 | typedef u16 compat_nlink_t; | 54 | typedef u16 compat_nlink_t; |
55 | typedef u16 compat_ipc_pid_t; | 55 | typedef u16 compat_ipc_pid_t; |
56 | typedef s32 compat_daddr_t; | 56 | typedef s32 compat_daddr_t; |
57 | typedef u32 compat_caddr_t; | 57 | typedef u32 compat_caddr_t; |
58 | typedef __kernel_fsid_t compat_fsid_t; | 58 | typedef __kernel_fsid_t compat_fsid_t; |
59 | typedef s32 compat_key_t; | 59 | typedef s32 compat_key_t; |
60 | typedef s32 compat_timer_t; | 60 | typedef s32 compat_timer_t; |
61 | 61 | ||
62 | typedef s32 compat_int_t; | 62 | typedef s32 compat_int_t; |
63 | typedef s32 compat_long_t; | 63 | typedef s32 compat_long_t; |
64 | typedef s64 compat_s64; | 64 | typedef s64 compat_s64; |
65 | typedef u32 compat_uint_t; | 65 | typedef u32 compat_uint_t; |
66 | typedef u32 compat_ulong_t; | 66 | typedef u32 compat_ulong_t; |
67 | typedef u64 compat_u64; | 67 | typedef u64 compat_u64; |
68 | typedef u32 compat_uptr_t; | ||
68 | 69 | ||
69 | struct compat_timespec { | 70 | struct compat_timespec { |
70 | compat_time_t tv_sec; | 71 | compat_time_t tv_sec; |
71 | s32 tv_nsec; | 72 | s32 tv_nsec; |
72 | }; | 73 | }; |
73 | 74 | ||
74 | struct compat_timeval { | 75 | struct compat_timeval { |
75 | compat_time_t tv_sec; | 76 | compat_time_t tv_sec; |
76 | s32 tv_usec; | 77 | s32 tv_usec; |
77 | }; | 78 | }; |
78 | 79 | ||
79 | struct compat_stat { | 80 | struct compat_stat { |
80 | compat_dev_t st_dev; | 81 | compat_dev_t st_dev; |
81 | u16 __pad1; | 82 | u16 __pad1; |
82 | compat_ino_t st_ino; | 83 | compat_ino_t st_ino; |
83 | compat_mode_t st_mode; | 84 | compat_mode_t st_mode; |
84 | compat_nlink_t st_nlink; | 85 | compat_nlink_t st_nlink; |
85 | __compat_uid_t st_uid; | 86 | __compat_uid_t st_uid; |
86 | __compat_gid_t st_gid; | 87 | __compat_gid_t st_gid; |
87 | compat_dev_t st_rdev; | 88 | compat_dev_t st_rdev; |
88 | u16 __pad2; | 89 | u16 __pad2; |
89 | u32 st_size; | 90 | u32 st_size; |
90 | u32 st_blksize; | 91 | u32 st_blksize; |
91 | u32 st_blocks; | 92 | u32 st_blocks; |
92 | u32 st_atime; | 93 | u32 st_atime; |
93 | u32 st_atime_nsec; | 94 | u32 st_atime_nsec; |
94 | u32 st_mtime; | 95 | u32 st_mtime; |
95 | u32 st_mtime_nsec; | 96 | u32 st_mtime_nsec; |
96 | u32 st_ctime; | 97 | u32 st_ctime; |
97 | u32 st_ctime_nsec; | 98 | u32 st_ctime_nsec; |
98 | u32 __unused4; | 99 | u32 __unused4; |
99 | u32 __unused5; | 100 | u32 __unused5; |
100 | }; | 101 | }; |
101 | 102 | ||
102 | struct compat_flock { | 103 | struct compat_flock { |
103 | short l_type; | 104 | short l_type; |
104 | short l_whence; | 105 | short l_whence; |
105 | compat_off_t l_start; | 106 | compat_off_t l_start; |
106 | compat_off_t l_len; | 107 | compat_off_t l_len; |
107 | compat_pid_t l_pid; | 108 | compat_pid_t l_pid; |
108 | }; | 109 | }; |
109 | 110 | ||
110 | #define F_GETLK64 12 | 111 | #define F_GETLK64 12 |
111 | #define F_SETLK64 13 | 112 | #define F_SETLK64 13 |
112 | #define F_SETLKW64 14 | 113 | #define F_SETLKW64 14 |
113 | 114 | ||
114 | struct compat_flock64 { | 115 | struct compat_flock64 { |
115 | short l_type; | 116 | short l_type; |
116 | short l_whence; | 117 | short l_whence; |
117 | compat_loff_t l_start; | 118 | compat_loff_t l_start; |
118 | compat_loff_t l_len; | 119 | compat_loff_t l_len; |
119 | compat_pid_t l_pid; | 120 | compat_pid_t l_pid; |
120 | }; | 121 | }; |
121 | 122 | ||
122 | struct compat_statfs { | 123 | struct compat_statfs { |
123 | s32 f_type; | 124 | s32 f_type; |
124 | s32 f_bsize; | 125 | s32 f_bsize; |
125 | s32 f_blocks; | 126 | s32 f_blocks; |
126 | s32 f_bfree; | 127 | s32 f_bfree; |
127 | s32 f_bavail; | 128 | s32 f_bavail; |
128 | s32 f_files; | 129 | s32 f_files; |
129 | s32 f_ffree; | 130 | s32 f_ffree; |
130 | compat_fsid_t f_fsid; | 131 | compat_fsid_t f_fsid; |
131 | s32 f_namelen; | 132 | s32 f_namelen; |
132 | s32 f_frsize; | 133 | s32 f_frsize; |
133 | s32 f_flags; | 134 | s32 f_flags; |
134 | s32 f_spare[5]; | 135 | s32 f_spare[5]; |
135 | }; | 136 | }; |
136 | 137 | ||
137 | #define COMPAT_RLIM_OLD_INFINITY 0x7fffffff | 138 | #define COMPAT_RLIM_OLD_INFINITY 0x7fffffff |
138 | #define COMPAT_RLIM_INFINITY 0xffffffff | 139 | #define COMPAT_RLIM_INFINITY 0xffffffff |
139 | 140 | ||
140 | typedef u32 compat_old_sigset_t; /* at least 32 bits */ | 141 | typedef u32 compat_old_sigset_t; /* at least 32 bits */ |
141 | 142 | ||
142 | #define _COMPAT_NSIG 64 | 143 | #define _COMPAT_NSIG 64 |
143 | #define _COMPAT_NSIG_BPW 32 | 144 | #define _COMPAT_NSIG_BPW 32 |
144 | 145 | ||
145 | typedef u32 compat_sigset_word; | 146 | typedef u32 compat_sigset_word; |
146 | 147 | ||
148 | typedef union compat_sigval { | ||
149 | compat_int_t sival_int; | ||
150 | compat_uptr_t sival_ptr; | ||
151 | } compat_sigval_t; | ||
152 | |||
153 | typedef struct compat_siginfo { | ||
154 | int si_signo; | ||
155 | int si_errno; | ||
156 | int si_code; | ||
157 | |||
158 | union { | ||
159 | int _pad[128/sizeof(int) - 3]; | ||
160 | |||
161 | /* kill() */ | ||
162 | struct { | ||
163 | pid_t _pid; /* sender's pid */ | ||
164 | uid_t _uid; /* sender's uid */ | ||
165 | } _kill; | ||
166 | |||
167 | /* POSIX.1b timers */ | ||
168 | struct { | ||
169 | compat_timer_t _tid; /* timer id */ | ||
170 | int _overrun; /* overrun count */ | ||
171 | compat_sigval_t _sigval; /* same as below */ | ||
172 | int _sys_private; /* not to be passed to user */ | ||
173 | } _timer; | ||
174 | |||
175 | /* POSIX.1b signals */ | ||
176 | struct { | ||
177 | pid_t _pid; /* sender's pid */ | ||
178 | uid_t _uid; /* sender's uid */ | ||
179 | compat_sigval_t _sigval; | ||
180 | } _rt; | ||
181 | |||
182 | /* SIGCHLD */ | ||
183 | struct { | ||
184 | pid_t _pid; /* which child */ | ||
185 | uid_t _uid; /* sender's uid */ | ||
186 | int _status;/* exit code */ | ||
187 | compat_clock_t _utime; | ||
188 | compat_clock_t _stime; | ||
189 | } _sigchld; | ||
190 | |||
191 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ | ||
192 | struct { | ||
193 | __u32 _addr; /* faulting insn/memory ref. - pointer */ | ||
194 | } _sigfault; | ||
195 | |||
196 | /* SIGPOLL */ | ||
197 | struct { | ||
198 | int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ | ||
199 | int _fd; | ||
200 | } _sigpoll; | ||
201 | } _sifields; | ||
202 | } compat_siginfo_t; | ||
203 | |||
204 | /* | ||
205 | * How these fields are to be accessed. | ||
206 | */ | ||
207 | #define si_pid _sifields._kill._pid | ||
208 | #define si_uid _sifields._kill._uid | ||
209 | #define si_status _sifields._sigchld._status | ||
210 | #define si_utime _sifields._sigchld._utime | ||
211 | #define si_stime _sifields._sigchld._stime | ||
212 | #define si_value _sifields._rt._sigval | ||
213 | #define si_int _sifields._rt._sigval.sival_int | ||
214 | #define si_ptr _sifields._rt._sigval.sival_ptr | ||
215 | #define si_addr _sifields._sigfault._addr | ||
216 | #define si_band _sifields._sigpoll._band | ||
217 | #define si_fd _sifields._sigpoll._fd | ||
218 | #define si_tid _sifields._timer._tid | ||
219 | #define si_overrun _sifields._timer._overrun | ||
220 | |||
147 | #define COMPAT_OFF_T_MAX 0x7fffffff | 221 | #define COMPAT_OFF_T_MAX 0x7fffffff |
148 | #define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL | 222 | #define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL |
149 | 223 | ||
150 | /* | 224 | /* |
151 | * A pointer passed in from user mode. This should not | 225 | * A pointer passed in from user mode. This should not |
152 | * be used for syscall parameters, just declare them | 226 | * be used for syscall parameters, just declare them |
153 | * as pointers because the syscall entry code will have | 227 | * as pointers because the syscall entry code will have |
154 | * appropriately converted them already. | 228 | * appropriately converted them already. |
155 | */ | 229 | */ |
156 | typedef u32 compat_uptr_t; | ||
157 | 230 | ||
158 | static inline void __user *compat_ptr(compat_uptr_t uptr) | 231 | static inline void __user *compat_ptr(compat_uptr_t uptr) |
159 | { | 232 | { |
160 | return (void __user *)(unsigned long)(uptr & 0x7fffffffUL); | 233 | return (void __user *)(unsigned long)(uptr & 0x7fffffffUL); |
161 | } | 234 | } |
162 | 235 | ||
163 | static inline compat_uptr_t ptr_to_compat(void __user *uptr) | 236 | static inline compat_uptr_t ptr_to_compat(void __user *uptr) |
164 | { | 237 | { |
165 | return (u32)(unsigned long)uptr; | 238 | return (u32)(unsigned long)uptr; |
166 | } | 239 | } |
167 | 240 | ||
168 | #ifdef CONFIG_COMPAT | 241 | #ifdef CONFIG_COMPAT |
169 | 242 | ||
170 | static inline int is_compat_task(void) | 243 | static inline int is_compat_task(void) |
171 | { | 244 | { |
172 | return is_32bit_task(); | 245 | return is_32bit_task(); |
173 | } | 246 | } |
174 | 247 | ||
175 | #endif | 248 | #endif |
176 | 249 | ||
177 | static inline void __user *arch_compat_alloc_user_space(long len) | 250 | static inline void __user *arch_compat_alloc_user_space(long len) |
178 | { | 251 | { |
179 | unsigned long stack; | 252 | unsigned long stack; |
180 | 253 | ||
181 | stack = KSTK_ESP(current); | 254 | stack = KSTK_ESP(current); |
182 | if (is_compat_task()) | 255 | if (is_compat_task()) |
183 | stack &= 0x7fffffffUL; | 256 | stack &= 0x7fffffffUL; |
184 | return (void __user *) (stack - len); | 257 | return (void __user *) (stack - len); |
185 | } | 258 | } |
186 | 259 | ||
187 | struct compat_ipc64_perm { | 260 | struct compat_ipc64_perm { |
188 | compat_key_t key; | 261 | compat_key_t key; |
189 | __compat_uid32_t uid; | 262 | __compat_uid32_t uid; |
190 | __compat_gid32_t gid; | 263 | __compat_gid32_t gid; |
191 | __compat_uid32_t cuid; | 264 | __compat_uid32_t cuid; |
192 | __compat_gid32_t cgid; | 265 | __compat_gid32_t cgid; |
193 | compat_mode_t mode; | 266 | compat_mode_t mode; |
194 | unsigned short __pad1; | 267 | unsigned short __pad1; |
195 | unsigned short seq; | 268 | unsigned short seq; |
196 | unsigned short __pad2; | 269 | unsigned short __pad2; |
197 | unsigned int __unused1; | 270 | unsigned int __unused1; |
198 | unsigned int __unused2; | 271 | unsigned int __unused2; |
199 | }; | 272 | }; |
200 | 273 | ||
201 | struct compat_semid64_ds { | 274 | struct compat_semid64_ds { |
202 | struct compat_ipc64_perm sem_perm; | 275 | struct compat_ipc64_perm sem_perm; |
203 | compat_time_t sem_otime; | 276 | compat_time_t sem_otime; |
204 | compat_ulong_t __pad1; | 277 | compat_ulong_t __pad1; |
205 | compat_time_t sem_ctime; | 278 | compat_time_t sem_ctime; |
206 | compat_ulong_t __pad2; | 279 | compat_ulong_t __pad2; |
207 | compat_ulong_t sem_nsems; | 280 | compat_ulong_t sem_nsems; |
208 | compat_ulong_t __unused1; | 281 | compat_ulong_t __unused1; |
209 | compat_ulong_t __unused2; | 282 | compat_ulong_t __unused2; |
210 | }; | 283 | }; |
211 | 284 | ||
212 | struct compat_msqid64_ds { | 285 | struct compat_msqid64_ds { |
213 | struct compat_ipc64_perm msg_perm; | 286 | struct compat_ipc64_perm msg_perm; |
214 | compat_time_t msg_stime; | 287 | compat_time_t msg_stime; |
215 | compat_ulong_t __pad1; | 288 | compat_ulong_t __pad1; |
216 | compat_time_t msg_rtime; | 289 | compat_time_t msg_rtime; |
217 | compat_ulong_t __pad2; | 290 | compat_ulong_t __pad2; |
218 | compat_time_t msg_ctime; | 291 | compat_time_t msg_ctime; |
219 | compat_ulong_t __pad3; | 292 | compat_ulong_t __pad3; |
220 | compat_ulong_t msg_cbytes; | 293 | compat_ulong_t msg_cbytes; |
221 | compat_ulong_t msg_qnum; | 294 | compat_ulong_t msg_qnum; |
222 | compat_ulong_t msg_qbytes; | 295 | compat_ulong_t msg_qbytes; |
223 | compat_pid_t msg_lspid; | 296 | compat_pid_t msg_lspid; |
224 | compat_pid_t msg_lrpid; | 297 | compat_pid_t msg_lrpid; |
225 | compat_ulong_t __unused1; | 298 | compat_ulong_t __unused1; |
226 | compat_ulong_t __unused2; | 299 | compat_ulong_t __unused2; |
227 | }; | 300 | }; |
228 | 301 | ||
229 | struct compat_shmid64_ds { | 302 | struct compat_shmid64_ds { |
230 | struct compat_ipc64_perm shm_perm; | 303 | struct compat_ipc64_perm shm_perm; |
231 | compat_size_t shm_segsz; | 304 | compat_size_t shm_segsz; |
232 | compat_time_t shm_atime; | 305 | compat_time_t shm_atime; |
233 | compat_ulong_t __pad1; | 306 | compat_ulong_t __pad1; |
234 | compat_time_t shm_dtime; | 307 | compat_time_t shm_dtime; |
235 | compat_ulong_t __pad2; | 308 | compat_ulong_t __pad2; |
236 | compat_time_t shm_ctime; | 309 | compat_time_t shm_ctime; |
237 | compat_ulong_t __pad3; | 310 | compat_ulong_t __pad3; |
238 | compat_pid_t shm_cpid; | 311 | compat_pid_t shm_cpid; |
239 | compat_pid_t shm_lpid; | 312 | compat_pid_t shm_lpid; |
240 | compat_ulong_t shm_nattch; | 313 | compat_ulong_t shm_nattch; |
241 | compat_ulong_t __unused1; | 314 | compat_ulong_t __unused1; |
242 | compat_ulong_t __unused2; | 315 | compat_ulong_t __unused2; |
243 | }; | 316 | }; |
244 | #endif /* _ASM_S390X_COMPAT_H */ | 317 | #endif /* _ASM_S390X_COMPAT_H */ |
arch/s390/kernel/compat_linux.h
1 | #ifndef _ASM_S390X_S390_H | 1 | #ifndef _ASM_S390X_S390_H |
2 | #define _ASM_S390X_S390_H | 2 | #define _ASM_S390X_S390_H |
3 | 3 | ||
4 | #include <linux/compat.h> | 4 | #include <linux/compat.h> |
5 | #include <linux/socket.h> | 5 | #include <linux/socket.h> |
6 | #include <linux/syscalls.h> | 6 | #include <linux/syscalls.h> |
7 | 7 | ||
8 | /* Macro that masks the high order bit of an 32 bit pointer and converts it*/ | 8 | /* Macro that masks the high order bit of an 32 bit pointer and converts it*/ |
9 | /* to a 64 bit pointer */ | 9 | /* to a 64 bit pointer */ |
10 | #define A(__x) ((unsigned long)((__x) & 0x7FFFFFFFUL)) | 10 | #define A(__x) ((unsigned long)((__x) & 0x7FFFFFFFUL)) |
11 | #define AA(__x) \ | 11 | #define AA(__x) \ |
12 | ((unsigned long)(__x)) | 12 | ((unsigned long)(__x)) |
13 | 13 | ||
14 | /* Now 32bit compatibility types */ | 14 | /* Now 32bit compatibility types */ |
15 | struct ipc_kludge_32 { | 15 | struct ipc_kludge_32 { |
16 | __u32 msgp; /* pointer */ | 16 | __u32 msgp; /* pointer */ |
17 | __s32 msgtyp; | 17 | __s32 msgtyp; |
18 | }; | 18 | }; |
19 | 19 | ||
20 | struct old_sigaction32 { | 20 | struct old_sigaction32 { |
21 | __u32 sa_handler; /* Really a pointer, but need to deal with 32 bits */ | 21 | __u32 sa_handler; /* Really a pointer, but need to deal with 32 bits */ |
22 | compat_old_sigset_t sa_mask; /* A 32 bit mask */ | 22 | compat_old_sigset_t sa_mask; /* A 32 bit mask */ |
23 | __u32 sa_flags; | 23 | __u32 sa_flags; |
24 | __u32 sa_restorer; /* Another 32 bit pointer */ | 24 | __u32 sa_restorer; /* Another 32 bit pointer */ |
25 | }; | 25 | }; |
26 | |||
27 | typedef struct compat_siginfo { | ||
28 | int si_signo; | ||
29 | int si_errno; | ||
30 | int si_code; | ||
31 | |||
32 | union { | ||
33 | int _pad[((128/sizeof(int)) - 3)]; | ||
34 | |||
35 | /* kill() */ | ||
36 | struct { | ||
37 | pid_t _pid; /* sender's pid */ | ||
38 | uid_t _uid; /* sender's uid */ | ||
39 | } _kill; | ||
40 | |||
41 | /* POSIX.1b timers */ | ||
42 | struct { | ||
43 | compat_timer_t _tid; /* timer id */ | ||
44 | int _overrun; /* overrun count */ | ||
45 | compat_sigval_t _sigval; /* same as below */ | ||
46 | int _sys_private; /* not to be passed to user */ | ||
47 | } _timer; | ||
48 | |||
49 | /* POSIX.1b signals */ | ||
50 | struct { | ||
51 | pid_t _pid; /* sender's pid */ | ||
52 | uid_t _uid; /* sender's uid */ | ||
53 | compat_sigval_t _sigval; | ||
54 | } _rt; | ||
55 | |||
56 | /* SIGCHLD */ | ||
57 | struct { | ||
58 | pid_t _pid; /* which child */ | ||
59 | uid_t _uid; /* sender's uid */ | ||
60 | int _status;/* exit code */ | ||
61 | compat_clock_t _utime; | ||
62 | compat_clock_t _stime; | ||
63 | } _sigchld; | ||
64 | |||
65 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ | ||
66 | struct { | ||
67 | __u32 _addr; /* faulting insn/memory ref. - pointer */ | ||
68 | } _sigfault; | ||
69 | |||
70 | /* SIGPOLL */ | ||
71 | struct { | ||
72 | int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ | ||
73 | int _fd; | ||
74 | } _sigpoll; | ||
75 | } _sifields; | ||
76 | } compat_siginfo_t; | ||
77 | |||
78 | /* | ||
79 | * How these fields are to be accessed. | ||
80 | */ | ||
81 | #define si_pid _sifields._kill._pid | ||
82 | #define si_uid _sifields._kill._uid | ||
83 | #define si_status _sifields._sigchld._status | ||
84 | #define si_utime _sifields._sigchld._utime | ||
85 | #define si_stime _sifields._sigchld._stime | ||
86 | #define si_value _sifields._rt._sigval | ||
87 | #define si_int _sifields._rt._sigval.sival_int | ||
88 | #define si_ptr _sifields._rt._sigval.sival_ptr | ||
89 | #define si_addr _sifields._sigfault._addr | ||
90 | #define si_band _sifields._sigpoll._band | ||
91 | #define si_fd _sifields._sigpoll._fd | ||
92 | #define si_tid _sifields._timer._tid | ||
93 | #define si_overrun _sifields._timer._overrun | ||
94 | 26 | ||
95 | /* asm/sigcontext.h */ | 27 | /* asm/sigcontext.h */ |
96 | typedef union | 28 | typedef union |
97 | { | 29 | { |
98 | __u64 d; | 30 | __u64 d; |
99 | __u32 f; | 31 | __u32 f; |
100 | } freg_t32; | 32 | } freg_t32; |
101 | 33 | ||
102 | typedef struct | 34 | typedef struct |
103 | { | 35 | { |
104 | unsigned int fpc; | 36 | unsigned int fpc; |
105 | freg_t32 fprs[__NUM_FPRS]; | 37 | freg_t32 fprs[__NUM_FPRS]; |
106 | } _s390_fp_regs32; | 38 | } _s390_fp_regs32; |
107 | 39 | ||
108 | typedef struct | 40 | typedef struct |
109 | { | 41 | { |
110 | __u32 mask; | 42 | __u32 mask; |
111 | __u32 addr; | 43 | __u32 addr; |
112 | } _psw_t32 __attribute__ ((aligned(8))); | 44 | } _psw_t32 __attribute__ ((aligned(8))); |
113 | 45 | ||
114 | typedef struct | 46 | typedef struct |
115 | { | 47 | { |
116 | _psw_t32 psw; | 48 | _psw_t32 psw; |
117 | __u32 gprs[__NUM_GPRS]; | 49 | __u32 gprs[__NUM_GPRS]; |
118 | __u32 acrs[__NUM_ACRS]; | 50 | __u32 acrs[__NUM_ACRS]; |
119 | } _s390_regs_common32; | 51 | } _s390_regs_common32; |
120 | 52 | ||
121 | typedef struct | 53 | typedef struct |
122 | { | 54 | { |
123 | _s390_regs_common32 regs; | 55 | _s390_regs_common32 regs; |
124 | _s390_fp_regs32 fpregs; | 56 | _s390_fp_regs32 fpregs; |
125 | } _sigregs32; | 57 | } _sigregs32; |
126 | 58 | ||
127 | #define _SIGCONTEXT_NSIG32 64 | 59 | #define _SIGCONTEXT_NSIG32 64 |
128 | #define _SIGCONTEXT_NSIG_BPW32 32 | 60 | #define _SIGCONTEXT_NSIG_BPW32 32 |
129 | #define __SIGNAL_FRAMESIZE32 96 | 61 | #define __SIGNAL_FRAMESIZE32 96 |
130 | #define _SIGMASK_COPY_SIZE32 (sizeof(u32)*2) | 62 | #define _SIGMASK_COPY_SIZE32 (sizeof(u32)*2) |
131 | 63 | ||
132 | struct sigcontext32 | 64 | struct sigcontext32 |
133 | { | 65 | { |
134 | __u32 oldmask[_COMPAT_NSIG_WORDS]; | 66 | __u32 oldmask[_COMPAT_NSIG_WORDS]; |
135 | __u32 sregs; /* pointer */ | 67 | __u32 sregs; /* pointer */ |
136 | }; | 68 | }; |
137 | 69 | ||
138 | /* asm/signal.h */ | 70 | /* asm/signal.h */ |
139 | struct sigaction32 { | 71 | struct sigaction32 { |
140 | __u32 sa_handler; /* pointer */ | 72 | __u32 sa_handler; /* pointer */ |
141 | __u32 sa_flags; | 73 | __u32 sa_flags; |
142 | __u32 sa_restorer; /* pointer */ | 74 | __u32 sa_restorer; /* pointer */ |
143 | compat_sigset_t sa_mask; /* mask last for extensibility */ | 75 | compat_sigset_t sa_mask; /* mask last for extensibility */ |
144 | }; | 76 | }; |
145 | 77 | ||
146 | typedef struct { | 78 | typedef struct { |
147 | __u32 ss_sp; /* pointer */ | 79 | __u32 ss_sp; /* pointer */ |
148 | int ss_flags; | 80 | int ss_flags; |
149 | compat_size_t ss_size; | 81 | compat_size_t ss_size; |
150 | } stack_t32; | 82 | } stack_t32; |
151 | 83 | ||
152 | /* asm/ucontext.h */ | 84 | /* asm/ucontext.h */ |
153 | struct ucontext32 { | 85 | struct ucontext32 { |
154 | __u32 uc_flags; | 86 | __u32 uc_flags; |
155 | __u32 uc_link; /* pointer */ | 87 | __u32 uc_link; /* pointer */ |
156 | stack_t32 uc_stack; | 88 | stack_t32 uc_stack; |
157 | _sigregs32 uc_mcontext; | 89 | _sigregs32 uc_mcontext; |
158 | compat_sigset_t uc_sigmask; /* mask last for extensibility */ | 90 | compat_sigset_t uc_sigmask; /* mask last for extensibility */ |
159 | }; | 91 | }; |
160 | 92 | ||
161 | struct stat64_emu31; | 93 | struct stat64_emu31; |
162 | struct mmap_arg_struct_emu31; | 94 | struct mmap_arg_struct_emu31; |
163 | struct fadvise64_64_args; | 95 | struct fadvise64_64_args; |
164 | struct old_sigaction32; | 96 | struct old_sigaction32; |
165 | struct old_sigaction32; | 97 | struct old_sigaction32; |
166 | 98 | ||
167 | long sys32_chown16(const char __user * filename, u16 user, u16 group); | 99 | long sys32_chown16(const char __user * filename, u16 user, u16 group); |
168 | long sys32_lchown16(const char __user * filename, u16 user, u16 group); | 100 | long sys32_lchown16(const char __user * filename, u16 user, u16 group); |
169 | long sys32_fchown16(unsigned int fd, u16 user, u16 group); | 101 | long sys32_fchown16(unsigned int fd, u16 user, u16 group); |
170 | long sys32_setregid16(u16 rgid, u16 egid); | 102 | long sys32_setregid16(u16 rgid, u16 egid); |
171 | long sys32_setgid16(u16 gid); | 103 | long sys32_setgid16(u16 gid); |
172 | long sys32_setreuid16(u16 ruid, u16 euid); | 104 | long sys32_setreuid16(u16 ruid, u16 euid); |
173 | long sys32_setuid16(u16 uid); | 105 | long sys32_setuid16(u16 uid); |
174 | long sys32_setresuid16(u16 ruid, u16 euid, u16 suid); | 106 | long sys32_setresuid16(u16 ruid, u16 euid, u16 suid); |
175 | long sys32_getresuid16(u16 __user *ruid, u16 __user *euid, u16 __user *suid); | 107 | long sys32_getresuid16(u16 __user *ruid, u16 __user *euid, u16 __user *suid); |
176 | long sys32_setresgid16(u16 rgid, u16 egid, u16 sgid); | 108 | long sys32_setresgid16(u16 rgid, u16 egid, u16 sgid); |
177 | long sys32_getresgid16(u16 __user *rgid, u16 __user *egid, u16 __user *sgid); | 109 | long sys32_getresgid16(u16 __user *rgid, u16 __user *egid, u16 __user *sgid); |
178 | long sys32_setfsuid16(u16 uid); | 110 | long sys32_setfsuid16(u16 uid); |
179 | long sys32_setfsgid16(u16 gid); | 111 | long sys32_setfsgid16(u16 gid); |
180 | long sys32_getgroups16(int gidsetsize, u16 __user *grouplist); | 112 | long sys32_getgroups16(int gidsetsize, u16 __user *grouplist); |
181 | long sys32_setgroups16(int gidsetsize, u16 __user *grouplist); | 113 | long sys32_setgroups16(int gidsetsize, u16 __user *grouplist); |
182 | long sys32_getuid16(void); | 114 | long sys32_getuid16(void); |
183 | long sys32_geteuid16(void); | 115 | long sys32_geteuid16(void); |
184 | long sys32_getgid16(void); | 116 | long sys32_getgid16(void); |
185 | long sys32_getegid16(void); | 117 | long sys32_getegid16(void); |
186 | long sys32_ipc(u32 call, int first, int second, int third, u32 ptr); | 118 | long sys32_ipc(u32 call, int first, int second, int third, u32 ptr); |
187 | long sys32_truncate64(const char __user * path, unsigned long high, | 119 | long sys32_truncate64(const char __user * path, unsigned long high, |
188 | unsigned long low); | 120 | unsigned long low); |
189 | long sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned long low); | 121 | long sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned long low); |
190 | long sys32_sched_rr_get_interval(compat_pid_t pid, | 122 | long sys32_sched_rr_get_interval(compat_pid_t pid, |
191 | struct compat_timespec __user *interval); | 123 | struct compat_timespec __user *interval); |
192 | long sys32_rt_sigprocmask(int how, compat_sigset_t __user *set, | 124 | long sys32_rt_sigprocmask(int how, compat_sigset_t __user *set, |
193 | compat_sigset_t __user *oset, size_t sigsetsize); | 125 | compat_sigset_t __user *oset, size_t sigsetsize); |
194 | long sys32_rt_sigpending(compat_sigset_t __user *set, size_t sigsetsize); | 126 | long sys32_rt_sigpending(compat_sigset_t __user *set, size_t sigsetsize); |
195 | long sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t __user *uinfo); | 127 | long sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t __user *uinfo); |
196 | long sys32_execve(const char __user *name, compat_uptr_t __user *argv, | 128 | long sys32_execve(const char __user *name, compat_uptr_t __user *argv, |
197 | compat_uptr_t __user *envp); | 129 | compat_uptr_t __user *envp); |
198 | long sys32_init_module(void __user *umod, unsigned long len, | 130 | long sys32_init_module(void __user *umod, unsigned long len, |
199 | const char __user *uargs); | 131 | const char __user *uargs); |
200 | long sys32_delete_module(const char __user *name_user, unsigned int flags); | 132 | long sys32_delete_module(const char __user *name_user, unsigned int flags); |
201 | long sys32_pread64(unsigned int fd, char __user *ubuf, size_t count, | 133 | long sys32_pread64(unsigned int fd, char __user *ubuf, size_t count, |
202 | u32 poshi, u32 poslo); | 134 | u32 poshi, u32 poslo); |
203 | long sys32_pwrite64(unsigned int fd, const char __user *ubuf, | 135 | long sys32_pwrite64(unsigned int fd, const char __user *ubuf, |
204 | size_t count, u32 poshi, u32 poslo); | 136 | size_t count, u32 poshi, u32 poslo); |
205 | compat_ssize_t sys32_readahead(int fd, u32 offhi, u32 offlo, s32 count); | 137 | compat_ssize_t sys32_readahead(int fd, u32 offhi, u32 offlo, s32 count); |
206 | long sys32_sendfile(int out_fd, int in_fd, compat_off_t __user *offset, | 138 | long sys32_sendfile(int out_fd, int in_fd, compat_off_t __user *offset, |
207 | size_t count); | 139 | size_t count); |
208 | long sys32_sendfile64(int out_fd, int in_fd, compat_loff_t __user *offset, | 140 | long sys32_sendfile64(int out_fd, int in_fd, compat_loff_t __user *offset, |
209 | s32 count); | 141 | s32 count); |
210 | long sys32_stat64(const char __user * filename, struct stat64_emu31 __user * statbuf); | 142 | long sys32_stat64(const char __user * filename, struct stat64_emu31 __user * statbuf); |
211 | long sys32_lstat64(const char __user * filename, | 143 | long sys32_lstat64(const char __user * filename, |
212 | struct stat64_emu31 __user * statbuf); | 144 | struct stat64_emu31 __user * statbuf); |
213 | long sys32_fstat64(unsigned long fd, struct stat64_emu31 __user * statbuf); | 145 | long sys32_fstat64(unsigned long fd, struct stat64_emu31 __user * statbuf); |
214 | long sys32_fstatat64(unsigned int dfd, const char __user *filename, | 146 | long sys32_fstatat64(unsigned int dfd, const char __user *filename, |
215 | struct stat64_emu31 __user* statbuf, int flag); | 147 | struct stat64_emu31 __user* statbuf, int flag); |
216 | unsigned long old32_mmap(struct mmap_arg_struct_emu31 __user *arg); | 148 | unsigned long old32_mmap(struct mmap_arg_struct_emu31 __user *arg); |
217 | long sys32_mmap2(struct mmap_arg_struct_emu31 __user *arg); | 149 | long sys32_mmap2(struct mmap_arg_struct_emu31 __user *arg); |
218 | long sys32_read(unsigned int fd, char __user * buf, size_t count); | 150 | long sys32_read(unsigned int fd, char __user * buf, size_t count); |
219 | long sys32_write(unsigned int fd, const char __user * buf, size_t count); | 151 | long sys32_write(unsigned int fd, const char __user * buf, size_t count); |
220 | long sys32_fadvise64(int fd, loff_t offset, size_t len, int advise); | 152 | long sys32_fadvise64(int fd, loff_t offset, size_t len, int advise); |
221 | long sys32_fadvise64_64(struct fadvise64_64_args __user *args); | 153 | long sys32_fadvise64_64(struct fadvise64_64_args __user *args); |
222 | long sys32_sigaction(int sig, const struct old_sigaction32 __user *act, | 154 | long sys32_sigaction(int sig, const struct old_sigaction32 __user *act, |
223 | struct old_sigaction32 __user *oact); | 155 | struct old_sigaction32 __user *oact); |
224 | long sys32_rt_sigaction(int sig, const struct sigaction32 __user *act, | 156 | long sys32_rt_sigaction(int sig, const struct sigaction32 __user *act, |
225 | struct sigaction32 __user *oact, size_t sigsetsize); | 157 | struct sigaction32 __user *oact, size_t sigsetsize); |
226 | long sys32_sigaltstack(const stack_t32 __user *uss, stack_t32 __user *uoss); | 158 | long sys32_sigaltstack(const stack_t32 __user *uss, stack_t32 __user *uoss); |
227 | #endif /* _ASM_S390X_S390_H */ | 159 | #endif /* _ASM_S390X_S390_H */ |
228 | 160 |
arch/sparc/include/asm/compat.h
1 | #ifndef _ASM_SPARC64_COMPAT_H | 1 | #ifndef _ASM_SPARC64_COMPAT_H |
2 | #define _ASM_SPARC64_COMPAT_H | 2 | #define _ASM_SPARC64_COMPAT_H |
3 | /* | 3 | /* |
4 | * Architecture specific compatibility types | 4 | * Architecture specific compatibility types |
5 | */ | 5 | */ |
6 | #include <linux/types.h> | 6 | #include <linux/types.h> |
7 | 7 | ||
8 | #define COMPAT_USER_HZ 100 | 8 | #define COMPAT_USER_HZ 100 |
9 | #define COMPAT_UTS_MACHINE "sparc\0\0" | 9 | #define COMPAT_UTS_MACHINE "sparc\0\0" |
10 | 10 | ||
11 | typedef u32 compat_size_t; | 11 | typedef u32 compat_size_t; |
12 | typedef s32 compat_ssize_t; | 12 | typedef s32 compat_ssize_t; |
13 | typedef s32 compat_time_t; | 13 | typedef s32 compat_time_t; |
14 | typedef s32 compat_clock_t; | 14 | typedef s32 compat_clock_t; |
15 | typedef s32 compat_pid_t; | 15 | typedef s32 compat_pid_t; |
16 | typedef u16 __compat_uid_t; | 16 | typedef u16 __compat_uid_t; |
17 | typedef u16 __compat_gid_t; | 17 | typedef u16 __compat_gid_t; |
18 | typedef u32 __compat_uid32_t; | 18 | typedef u32 __compat_uid32_t; |
19 | typedef u32 __compat_gid32_t; | 19 | typedef u32 __compat_gid32_t; |
20 | typedef u16 compat_mode_t; | 20 | typedef u16 compat_mode_t; |
21 | typedef u32 compat_ino_t; | 21 | typedef u32 compat_ino_t; |
22 | typedef u16 compat_dev_t; | 22 | typedef u16 compat_dev_t; |
23 | typedef s32 compat_off_t; | 23 | typedef s32 compat_off_t; |
24 | typedef s64 compat_loff_t; | 24 | typedef s64 compat_loff_t; |
25 | typedef s16 compat_nlink_t; | 25 | typedef s16 compat_nlink_t; |
26 | typedef u16 compat_ipc_pid_t; | 26 | typedef u16 compat_ipc_pid_t; |
27 | typedef s32 compat_daddr_t; | 27 | typedef s32 compat_daddr_t; |
28 | typedef u32 compat_caddr_t; | 28 | typedef u32 compat_caddr_t; |
29 | typedef __kernel_fsid_t compat_fsid_t; | 29 | typedef __kernel_fsid_t compat_fsid_t; |
30 | typedef s32 compat_key_t; | 30 | typedef s32 compat_key_t; |
31 | typedef s32 compat_timer_t; | 31 | typedef s32 compat_timer_t; |
32 | 32 | ||
33 | typedef s32 compat_int_t; | 33 | typedef s32 compat_int_t; |
34 | typedef s32 compat_long_t; | 34 | typedef s32 compat_long_t; |
35 | typedef s64 compat_s64; | 35 | typedef s64 compat_s64; |
36 | typedef u32 compat_uint_t; | 36 | typedef u32 compat_uint_t; |
37 | typedef u32 compat_ulong_t; | 37 | typedef u32 compat_ulong_t; |
38 | typedef u64 compat_u64; | 38 | typedef u64 compat_u64; |
39 | typedef u32 compat_uptr_t; | ||
39 | 40 | ||
40 | struct compat_timespec { | 41 | struct compat_timespec { |
41 | compat_time_t tv_sec; | 42 | compat_time_t tv_sec; |
42 | s32 tv_nsec; | 43 | s32 tv_nsec; |
43 | }; | 44 | }; |
44 | 45 | ||
45 | struct compat_timeval { | 46 | struct compat_timeval { |
46 | compat_time_t tv_sec; | 47 | compat_time_t tv_sec; |
47 | s32 tv_usec; | 48 | s32 tv_usec; |
48 | }; | 49 | }; |
49 | 50 | ||
50 | struct compat_stat { | 51 | struct compat_stat { |
51 | compat_dev_t st_dev; | 52 | compat_dev_t st_dev; |
52 | compat_ino_t st_ino; | 53 | compat_ino_t st_ino; |
53 | compat_mode_t st_mode; | 54 | compat_mode_t st_mode; |
54 | compat_nlink_t st_nlink; | 55 | compat_nlink_t st_nlink; |
55 | __compat_uid_t st_uid; | 56 | __compat_uid_t st_uid; |
56 | __compat_gid_t st_gid; | 57 | __compat_gid_t st_gid; |
57 | compat_dev_t st_rdev; | 58 | compat_dev_t st_rdev; |
58 | compat_off_t st_size; | 59 | compat_off_t st_size; |
59 | compat_time_t st_atime; | 60 | compat_time_t st_atime; |
60 | compat_ulong_t st_atime_nsec; | 61 | compat_ulong_t st_atime_nsec; |
61 | compat_time_t st_mtime; | 62 | compat_time_t st_mtime; |
62 | compat_ulong_t st_mtime_nsec; | 63 | compat_ulong_t st_mtime_nsec; |
63 | compat_time_t st_ctime; | 64 | compat_time_t st_ctime; |
64 | compat_ulong_t st_ctime_nsec; | 65 | compat_ulong_t st_ctime_nsec; |
65 | compat_off_t st_blksize; | 66 | compat_off_t st_blksize; |
66 | compat_off_t st_blocks; | 67 | compat_off_t st_blocks; |
67 | u32 __unused4[2]; | 68 | u32 __unused4[2]; |
68 | }; | 69 | }; |
69 | 70 | ||
70 | struct compat_stat64 { | 71 | struct compat_stat64 { |
71 | unsigned long long st_dev; | 72 | unsigned long long st_dev; |
72 | 73 | ||
73 | unsigned long long st_ino; | 74 | unsigned long long st_ino; |
74 | 75 | ||
75 | unsigned int st_mode; | 76 | unsigned int st_mode; |
76 | unsigned int st_nlink; | 77 | unsigned int st_nlink; |
77 | 78 | ||
78 | unsigned int st_uid; | 79 | unsigned int st_uid; |
79 | unsigned int st_gid; | 80 | unsigned int st_gid; |
80 | 81 | ||
81 | unsigned long long st_rdev; | 82 | unsigned long long st_rdev; |
82 | 83 | ||
83 | unsigned char __pad3[8]; | 84 | unsigned char __pad3[8]; |
84 | 85 | ||
85 | long long st_size; | 86 | long long st_size; |
86 | unsigned int st_blksize; | 87 | unsigned int st_blksize; |
87 | 88 | ||
88 | unsigned char __pad4[8]; | 89 | unsigned char __pad4[8]; |
89 | unsigned int st_blocks; | 90 | unsigned int st_blocks; |
90 | 91 | ||
91 | unsigned int st_atime; | 92 | unsigned int st_atime; |
92 | unsigned int st_atime_nsec; | 93 | unsigned int st_atime_nsec; |
93 | 94 | ||
94 | unsigned int st_mtime; | 95 | unsigned int st_mtime; |
95 | unsigned int st_mtime_nsec; | 96 | unsigned int st_mtime_nsec; |
96 | 97 | ||
97 | unsigned int st_ctime; | 98 | unsigned int st_ctime; |
98 | unsigned int st_ctime_nsec; | 99 | unsigned int st_ctime_nsec; |
99 | 100 | ||
100 | unsigned int __unused4; | 101 | unsigned int __unused4; |
101 | unsigned int __unused5; | 102 | unsigned int __unused5; |
102 | }; | 103 | }; |
103 | 104 | ||
104 | struct compat_flock { | 105 | struct compat_flock { |
105 | short l_type; | 106 | short l_type; |
106 | short l_whence; | 107 | short l_whence; |
107 | compat_off_t l_start; | 108 | compat_off_t l_start; |
108 | compat_off_t l_len; | 109 | compat_off_t l_len; |
109 | compat_pid_t l_pid; | 110 | compat_pid_t l_pid; |
110 | short __unused; | 111 | short __unused; |
111 | }; | 112 | }; |
112 | 113 | ||
113 | #define F_GETLK64 12 | 114 | #define F_GETLK64 12 |
114 | #define F_SETLK64 13 | 115 | #define F_SETLK64 13 |
115 | #define F_SETLKW64 14 | 116 | #define F_SETLKW64 14 |
116 | 117 | ||
117 | struct compat_flock64 { | 118 | struct compat_flock64 { |
118 | short l_type; | 119 | short l_type; |
119 | short l_whence; | 120 | short l_whence; |
120 | compat_loff_t l_start; | 121 | compat_loff_t l_start; |
121 | compat_loff_t l_len; | 122 | compat_loff_t l_len; |
122 | compat_pid_t l_pid; | 123 | compat_pid_t l_pid; |
123 | short __unused; | 124 | short __unused; |
124 | }; | 125 | }; |
125 | 126 | ||
126 | struct compat_statfs { | 127 | struct compat_statfs { |
127 | int f_type; | 128 | int f_type; |
128 | int f_bsize; | 129 | int f_bsize; |
129 | int f_blocks; | 130 | int f_blocks; |
130 | int f_bfree; | 131 | int f_bfree; |
131 | int f_bavail; | 132 | int f_bavail; |
132 | int f_files; | 133 | int f_files; |
133 | int f_ffree; | 134 | int f_ffree; |
134 | compat_fsid_t f_fsid; | 135 | compat_fsid_t f_fsid; |
135 | int f_namelen; /* SunOS ignores this field. */ | 136 | int f_namelen; /* SunOS ignores this field. */ |
136 | int f_frsize; | 137 | int f_frsize; |
137 | int f_flags; | 138 | int f_flags; |
138 | int f_spare[4]; | 139 | int f_spare[4]; |
139 | }; | 140 | }; |
140 | 141 | ||
141 | #define COMPAT_RLIM_INFINITY 0x7fffffff | 142 | #define COMPAT_RLIM_INFINITY 0x7fffffff |
142 | 143 | ||
143 | typedef u32 compat_old_sigset_t; | 144 | typedef u32 compat_old_sigset_t; |
144 | 145 | ||
145 | #define _COMPAT_NSIG 64 | 146 | #define _COMPAT_NSIG 64 |
146 | #define _COMPAT_NSIG_BPW 32 | 147 | #define _COMPAT_NSIG_BPW 32 |
147 | 148 | ||
148 | typedef u32 compat_sigset_word; | 149 | typedef u32 compat_sigset_word; |
149 | 150 | ||
151 | typedef union compat_sigval { | ||
152 | compat_int_t sival_int; | ||
153 | compat_uptr_t sival_ptr; | ||
154 | } compat_sigval_t; | ||
155 | |||
156 | #define SI_PAD_SIZE32 (128/sizeof(int) - 3) | ||
157 | |||
158 | typedef struct compat_siginfo { | ||
159 | int si_signo; | ||
160 | int si_errno; | ||
161 | int si_code; | ||
162 | |||
163 | union { | ||
164 | int _pad[SI_PAD_SIZE32]; | ||
165 | |||
166 | /* kill() */ | ||
167 | struct { | ||
168 | compat_pid_t _pid; /* sender's pid */ | ||
169 | unsigned int _uid; /* sender's uid */ | ||
170 | } _kill; | ||
171 | |||
172 | /* POSIX.1b timers */ | ||
173 | struct { | ||
174 | compat_timer_t _tid; /* timer id */ | ||
175 | int _overrun; /* overrun count */ | ||
176 | compat_sigval_t _sigval; /* same as below */ | ||
177 | int _sys_private; /* not to be passed to user */ | ||
178 | } _timer; | ||
179 | |||
180 | /* POSIX.1b signals */ | ||
181 | struct { | ||
182 | compat_pid_t _pid; /* sender's pid */ | ||
183 | unsigned int _uid; /* sender's uid */ | ||
184 | compat_sigval_t _sigval; | ||
185 | } _rt; | ||
186 | |||
187 | /* SIGCHLD */ | ||
188 | struct { | ||
189 | compat_pid_t _pid; /* which child */ | ||
190 | unsigned int _uid; /* sender's uid */ | ||
191 | int _status; /* exit code */ | ||
192 | compat_clock_t _utime; | ||
193 | compat_clock_t _stime; | ||
194 | } _sigchld; | ||
195 | |||
196 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGEMT */ | ||
197 | struct { | ||
198 | u32 _addr; /* faulting insn/memory ref. */ | ||
199 | int _trapno; | ||
200 | } _sigfault; | ||
201 | |||
202 | /* SIGPOLL */ | ||
203 | struct { | ||
204 | int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ | ||
205 | int _fd; | ||
206 | } _sigpoll; | ||
207 | } _sifields; | ||
208 | } compat_siginfo_t; | ||
209 | |||
150 | #define COMPAT_OFF_T_MAX 0x7fffffff | 210 | #define COMPAT_OFF_T_MAX 0x7fffffff |
151 | #define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL | 211 | #define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL |
152 | 212 | ||
153 | /* | 213 | /* |
154 | * A pointer passed in from user mode. This should not | 214 | * A pointer passed in from user mode. This should not |
155 | * be used for syscall parameters, just declare them | 215 | * be used for syscall parameters, just declare them |
156 | * as pointers because the syscall entry code will have | 216 | * as pointers because the syscall entry code will have |
157 | * appropriately converted them already. | 217 | * appropriately converted them already. |
158 | */ | 218 | */ |
159 | typedef u32 compat_uptr_t; | ||
160 | 219 | ||
161 | static inline void __user *compat_ptr(compat_uptr_t uptr) | 220 | static inline void __user *compat_ptr(compat_uptr_t uptr) |
162 | { | 221 | { |
163 | return (void __user *)(unsigned long)uptr; | 222 | return (void __user *)(unsigned long)uptr; |
164 | } | 223 | } |
165 | 224 | ||
166 | static inline compat_uptr_t ptr_to_compat(void __user *uptr) | 225 | static inline compat_uptr_t ptr_to_compat(void __user *uptr) |
167 | { | 226 | { |
168 | return (u32)(unsigned long)uptr; | 227 | return (u32)(unsigned long)uptr; |
169 | } | 228 | } |
170 | 229 | ||
171 | static inline void __user *arch_compat_alloc_user_space(long len) | 230 | static inline void __user *arch_compat_alloc_user_space(long len) |
172 | { | 231 | { |
173 | struct pt_regs *regs = current_thread_info()->kregs; | 232 | struct pt_regs *regs = current_thread_info()->kregs; |
174 | unsigned long usp = regs->u_regs[UREG_I6]; | 233 | unsigned long usp = regs->u_regs[UREG_I6]; |
175 | 234 | ||
176 | if (!(test_thread_flag(TIF_32BIT))) | 235 | if (!(test_thread_flag(TIF_32BIT))) |
177 | usp += STACK_BIAS; | 236 | usp += STACK_BIAS; |
178 | else | 237 | else |
179 | usp &= 0xffffffffUL; | 238 | usp &= 0xffffffffUL; |
180 | 239 | ||
181 | usp -= len; | 240 | usp -= len; |
182 | usp &= ~0x7UL; | 241 | usp &= ~0x7UL; |
183 | 242 | ||
184 | return (void __user *) usp; | 243 | return (void __user *) usp; |
185 | } | 244 | } |
186 | 245 | ||
187 | struct compat_ipc64_perm { | 246 | struct compat_ipc64_perm { |
188 | compat_key_t key; | 247 | compat_key_t key; |
189 | __compat_uid32_t uid; | 248 | __compat_uid32_t uid; |
190 | __compat_gid32_t gid; | 249 | __compat_gid32_t gid; |
191 | __compat_uid32_t cuid; | 250 | __compat_uid32_t cuid; |
192 | __compat_gid32_t cgid; | 251 | __compat_gid32_t cgid; |
193 | unsigned short __pad1; | 252 | unsigned short __pad1; |
194 | compat_mode_t mode; | 253 | compat_mode_t mode; |
195 | unsigned short __pad2; | 254 | unsigned short __pad2; |
196 | unsigned short seq; | 255 | unsigned short seq; |
197 | unsigned long __unused1; /* yes they really are 64bit pads */ | 256 | unsigned long __unused1; /* yes they really are 64bit pads */ |
198 | unsigned long __unused2; | 257 | unsigned long __unused2; |
199 | }; | 258 | }; |
200 | 259 | ||
201 | struct compat_semid64_ds { | 260 | struct compat_semid64_ds { |
202 | struct compat_ipc64_perm sem_perm; | 261 | struct compat_ipc64_perm sem_perm; |
203 | unsigned int __pad1; | 262 | unsigned int __pad1; |
204 | compat_time_t sem_otime; | 263 | compat_time_t sem_otime; |
205 | unsigned int __pad2; | 264 | unsigned int __pad2; |
206 | compat_time_t sem_ctime; | 265 | compat_time_t sem_ctime; |
207 | u32 sem_nsems; | 266 | u32 sem_nsems; |
208 | u32 __unused1; | 267 | u32 __unused1; |
209 | u32 __unused2; | 268 | u32 __unused2; |
210 | }; | 269 | }; |
211 | 270 | ||
212 | struct compat_msqid64_ds { | 271 | struct compat_msqid64_ds { |
213 | struct compat_ipc64_perm msg_perm; | 272 | struct compat_ipc64_perm msg_perm; |
214 | unsigned int __pad1; | 273 | unsigned int __pad1; |
215 | compat_time_t msg_stime; | 274 | compat_time_t msg_stime; |
216 | unsigned int __pad2; | 275 | unsigned int __pad2; |
217 | compat_time_t msg_rtime; | 276 | compat_time_t msg_rtime; |
218 | unsigned int __pad3; | 277 | unsigned int __pad3; |
219 | compat_time_t msg_ctime; | 278 | compat_time_t msg_ctime; |
220 | unsigned int msg_cbytes; | 279 | unsigned int msg_cbytes; |
221 | unsigned int msg_qnum; | 280 | unsigned int msg_qnum; |
222 | unsigned int msg_qbytes; | 281 | unsigned int msg_qbytes; |
223 | compat_pid_t msg_lspid; | 282 | compat_pid_t msg_lspid; |
224 | compat_pid_t msg_lrpid; | 283 | compat_pid_t msg_lrpid; |
225 | unsigned int __unused1; | 284 | unsigned int __unused1; |
226 | unsigned int __unused2; | 285 | unsigned int __unused2; |
227 | }; | 286 | }; |
228 | 287 | ||
229 | struct compat_shmid64_ds { | 288 | struct compat_shmid64_ds { |
230 | struct compat_ipc64_perm shm_perm; | 289 | struct compat_ipc64_perm shm_perm; |
231 | unsigned int __pad1; | 290 | unsigned int __pad1; |
232 | compat_time_t shm_atime; | 291 | compat_time_t shm_atime; |
233 | unsigned int __pad2; | 292 | unsigned int __pad2; |
234 | compat_time_t shm_dtime; | 293 | compat_time_t shm_dtime; |
235 | unsigned int __pad3; | 294 | unsigned int __pad3; |
236 | compat_time_t shm_ctime; | 295 | compat_time_t shm_ctime; |
237 | compat_size_t shm_segsz; | 296 | compat_size_t shm_segsz; |
238 | compat_pid_t shm_cpid; | 297 | compat_pid_t shm_cpid; |
239 | compat_pid_t shm_lpid; | 298 | compat_pid_t shm_lpid; |
240 | unsigned int shm_nattch; | 299 | unsigned int shm_nattch; |
241 | unsigned int __unused1; | 300 | unsigned int __unused1; |
242 | unsigned int __unused2; | 301 | unsigned int __unused2; |
243 | }; | 302 | }; |
244 | 303 | ||
245 | static inline int is_compat_task(void) | 304 | static inline int is_compat_task(void) |
246 | { | 305 | { |
247 | return test_thread_flag(TIF_32BIT); | 306 | return test_thread_flag(TIF_32BIT); |
248 | } | 307 | } |
249 | 308 | ||
250 | #endif /* _ASM_SPARC64_COMPAT_H */ | 309 | #endif /* _ASM_SPARC64_COMPAT_H */ |
arch/sparc/include/asm/siginfo.h
1 | #ifndef __SPARC_SIGINFO_H | 1 | #ifndef __SPARC_SIGINFO_H |
2 | #define __SPARC_SIGINFO_H | 2 | #define __SPARC_SIGINFO_H |
3 | 3 | ||
4 | #if defined(__sparc__) && defined(__arch64__) | 4 | #if defined(__sparc__) && defined(__arch64__) |
5 | 5 | ||
6 | #define SI_PAD_SIZE32 ((SI_MAX_SIZE/sizeof(int)) - 3) | ||
7 | #define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int)) | 6 | #define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int)) |
8 | #define __ARCH_SI_BAND_T int | 7 | #define __ARCH_SI_BAND_T int |
9 | 8 | ||
10 | #endif /* defined(__sparc__) && defined(__arch64__) */ | 9 | #endif /* defined(__sparc__) && defined(__arch64__) */ |
11 | 10 | ||
12 | 11 | ||
13 | #define __ARCH_SI_TRAPNO | 12 | #define __ARCH_SI_TRAPNO |
14 | 13 | ||
15 | #include <asm-generic/siginfo.h> | 14 | #include <asm-generic/siginfo.h> |
16 | 15 | ||
17 | #ifdef __KERNEL__ | 16 | #ifdef __KERNEL__ |
18 | 17 | ||
19 | #ifdef CONFIG_COMPAT | 18 | #ifdef CONFIG_COMPAT |
20 | 19 | ||
21 | struct compat_siginfo; | 20 | struct compat_siginfo; |
22 | 21 | ||
23 | #endif /* CONFIG_COMPAT */ | 22 | #endif /* CONFIG_COMPAT */ |
24 | 23 | ||
25 | #endif /* __KERNEL__ */ | 24 | #endif /* __KERNEL__ */ |
26 | 25 | ||
27 | #define SI_NOINFO 32767 /* no information in siginfo_t */ | 26 | #define SI_NOINFO 32767 /* no information in siginfo_t */ |
28 | 27 | ||
29 | /* | 28 | /* |
30 | * SIGEMT si_codes | 29 | * SIGEMT si_codes |
31 | */ | 30 | */ |
32 | #define EMT_TAGOVF (__SI_FAULT|1) /* tag overflow */ | 31 | #define EMT_TAGOVF (__SI_FAULT|1) /* tag overflow */ |
33 | #define NSIGEMT 1 | 32 | #define NSIGEMT 1 |
34 | 33 | ||
35 | #endif /* !(__SPARC_SIGINFO_H) */ | 34 | #endif /* !(__SPARC_SIGINFO_H) */ |
36 | 35 |
arch/sparc/kernel/signal32.c
1 | /* arch/sparc64/kernel/signal32.c | 1 | /* arch/sparc64/kernel/signal32.c |
2 | * | 2 | * |
3 | * Copyright (C) 1991, 1992 Linus Torvalds | 3 | * Copyright (C) 1991, 1992 Linus Torvalds |
4 | * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) | 4 | * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) |
5 | * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx) | 5 | * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx) |
6 | * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) | 6 | * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) |
7 | * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) | 7 | * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/sched.h> | 10 | #include <linux/sched.h> |
11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
12 | #include <linux/signal.h> | 12 | #include <linux/signal.h> |
13 | #include <linux/errno.h> | 13 | #include <linux/errno.h> |
14 | #include <linux/wait.h> | 14 | #include <linux/wait.h> |
15 | #include <linux/ptrace.h> | 15 | #include <linux/ptrace.h> |
16 | #include <linux/unistd.h> | 16 | #include <linux/unistd.h> |
17 | #include <linux/mm.h> | 17 | #include <linux/mm.h> |
18 | #include <linux/tty.h> | 18 | #include <linux/tty.h> |
19 | #include <linux/binfmts.h> | 19 | #include <linux/binfmts.h> |
20 | #include <linux/compat.h> | 20 | #include <linux/compat.h> |
21 | #include <linux/bitops.h> | 21 | #include <linux/bitops.h> |
22 | #include <linux/tracehook.h> | 22 | #include <linux/tracehook.h> |
23 | 23 | ||
24 | #include <asm/uaccess.h> | 24 | #include <asm/uaccess.h> |
25 | #include <asm/ptrace.h> | 25 | #include <asm/ptrace.h> |
26 | #include <asm/pgtable.h> | 26 | #include <asm/pgtable.h> |
27 | #include <asm/psrcompat.h> | 27 | #include <asm/psrcompat.h> |
28 | #include <asm/fpumacro.h> | 28 | #include <asm/fpumacro.h> |
29 | #include <asm/visasm.h> | 29 | #include <asm/visasm.h> |
30 | #include <asm/compat_signal.h> | 30 | #include <asm/compat_signal.h> |
31 | #include <asm/switch_to.h> | 31 | #include <asm/switch_to.h> |
32 | 32 | ||
33 | #include "sigutil.h" | 33 | #include "sigutil.h" |
34 | 34 | ||
35 | /* This magic should be in g_upper[0] for all upper parts | 35 | /* This magic should be in g_upper[0] for all upper parts |
36 | * to be valid. | 36 | * to be valid. |
37 | */ | 37 | */ |
38 | #define SIGINFO_EXTRA_V8PLUS_MAGIC 0x130e269 | 38 | #define SIGINFO_EXTRA_V8PLUS_MAGIC 0x130e269 |
39 | typedef struct { | 39 | typedef struct { |
40 | unsigned int g_upper[8]; | 40 | unsigned int g_upper[8]; |
41 | unsigned int o_upper[8]; | 41 | unsigned int o_upper[8]; |
42 | unsigned int asi; | 42 | unsigned int asi; |
43 | } siginfo_extra_v8plus_t; | 43 | } siginfo_extra_v8plus_t; |
44 | 44 | ||
45 | struct signal_frame32 { | 45 | struct signal_frame32 { |
46 | struct sparc_stackf32 ss; | 46 | struct sparc_stackf32 ss; |
47 | __siginfo32_t info; | 47 | __siginfo32_t info; |
48 | /* __siginfo_fpu_t * */ u32 fpu_save; | 48 | /* __siginfo_fpu_t * */ u32 fpu_save; |
49 | unsigned int insns[2]; | 49 | unsigned int insns[2]; |
50 | unsigned int extramask[_COMPAT_NSIG_WORDS - 1]; | 50 | unsigned int extramask[_COMPAT_NSIG_WORDS - 1]; |
51 | unsigned int extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */ | 51 | unsigned int extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */ |
52 | /* Only valid if (info.si_regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */ | 52 | /* Only valid if (info.si_regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */ |
53 | siginfo_extra_v8plus_t v8plus; | 53 | siginfo_extra_v8plus_t v8plus; |
54 | /* __siginfo_rwin_t * */u32 rwin_save; | 54 | /* __siginfo_rwin_t * */u32 rwin_save; |
55 | } __attribute__((aligned(8))); | 55 | } __attribute__((aligned(8))); |
56 | 56 | ||
57 | typedef struct compat_siginfo{ | ||
58 | int si_signo; | ||
59 | int si_errno; | ||
60 | int si_code; | ||
61 | |||
62 | union { | ||
63 | int _pad[SI_PAD_SIZE32]; | ||
64 | |||
65 | /* kill() */ | ||
66 | struct { | ||
67 | compat_pid_t _pid; /* sender's pid */ | ||
68 | unsigned int _uid; /* sender's uid */ | ||
69 | } _kill; | ||
70 | |||
71 | /* POSIX.1b timers */ | ||
72 | struct { | ||
73 | compat_timer_t _tid; /* timer id */ | ||
74 | int _overrun; /* overrun count */ | ||
75 | compat_sigval_t _sigval; /* same as below */ | ||
76 | int _sys_private; /* not to be passed to user */ | ||
77 | } _timer; | ||
78 | |||
79 | /* POSIX.1b signals */ | ||
80 | struct { | ||
81 | compat_pid_t _pid; /* sender's pid */ | ||
82 | unsigned int _uid; /* sender's uid */ | ||
83 | compat_sigval_t _sigval; | ||
84 | } _rt; | ||
85 | |||
86 | /* SIGCHLD */ | ||
87 | struct { | ||
88 | compat_pid_t _pid; /* which child */ | ||
89 | unsigned int _uid; /* sender's uid */ | ||
90 | int _status; /* exit code */ | ||
91 | compat_clock_t _utime; | ||
92 | compat_clock_t _stime; | ||
93 | } _sigchld; | ||
94 | |||
95 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGEMT */ | ||
96 | struct { | ||
97 | u32 _addr; /* faulting insn/memory ref. */ | ||
98 | int _trapno; | ||
99 | } _sigfault; | ||
100 | |||
101 | /* SIGPOLL */ | ||
102 | struct { | ||
103 | int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ | ||
104 | int _fd; | ||
105 | } _sigpoll; | ||
106 | } _sifields; | ||
107 | }compat_siginfo_t; | ||
108 | |||
109 | struct rt_signal_frame32 { | 57 | struct rt_signal_frame32 { |
110 | struct sparc_stackf32 ss; | 58 | struct sparc_stackf32 ss; |
111 | compat_siginfo_t info; | 59 | compat_siginfo_t info; |
112 | struct pt_regs32 regs; | 60 | struct pt_regs32 regs; |
113 | compat_sigset_t mask; | 61 | compat_sigset_t mask; |
114 | /* __siginfo_fpu_t * */ u32 fpu_save; | 62 | /* __siginfo_fpu_t * */ u32 fpu_save; |
115 | unsigned int insns[2]; | 63 | unsigned int insns[2]; |
116 | stack_t32 stack; | 64 | stack_t32 stack; |
117 | unsigned int extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */ | 65 | unsigned int extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */ |
118 | /* Only valid if (regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */ | 66 | /* Only valid if (regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */ |
119 | siginfo_extra_v8plus_t v8plus; | 67 | siginfo_extra_v8plus_t v8plus; |
120 | /* __siginfo_rwin_t * */u32 rwin_save; | 68 | /* __siginfo_rwin_t * */u32 rwin_save; |
121 | } __attribute__((aligned(8))); | 69 | } __attribute__((aligned(8))); |
122 | 70 | ||
123 | int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from) | 71 | int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from) |
124 | { | 72 | { |
125 | int err; | 73 | int err; |
126 | 74 | ||
127 | if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t))) | 75 | if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t))) |
128 | return -EFAULT; | 76 | return -EFAULT; |
129 | 77 | ||
130 | /* If you change siginfo_t structure, please be sure | 78 | /* If you change siginfo_t structure, please be sure |
131 | this code is fixed accordingly. | 79 | this code is fixed accordingly. |
132 | It should never copy any pad contained in the structure | 80 | It should never copy any pad contained in the structure |
133 | to avoid security leaks, but must copy the generic | 81 | to avoid security leaks, but must copy the generic |
134 | 3 ints plus the relevant union member. | 82 | 3 ints plus the relevant union member. |
135 | This routine must convert siginfo from 64bit to 32bit as well | 83 | This routine must convert siginfo from 64bit to 32bit as well |
136 | at the same time. */ | 84 | at the same time. */ |
137 | err = __put_user(from->si_signo, &to->si_signo); | 85 | err = __put_user(from->si_signo, &to->si_signo); |
138 | err |= __put_user(from->si_errno, &to->si_errno); | 86 | err |= __put_user(from->si_errno, &to->si_errno); |
139 | err |= __put_user((short)from->si_code, &to->si_code); | 87 | err |= __put_user((short)from->si_code, &to->si_code); |
140 | if (from->si_code < 0) | 88 | if (from->si_code < 0) |
141 | err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE); | 89 | err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE); |
142 | else { | 90 | else { |
143 | switch (from->si_code >> 16) { | 91 | switch (from->si_code >> 16) { |
144 | case __SI_TIMER >> 16: | 92 | case __SI_TIMER >> 16: |
145 | err |= __put_user(from->si_tid, &to->si_tid); | 93 | err |= __put_user(from->si_tid, &to->si_tid); |
146 | err |= __put_user(from->si_overrun, &to->si_overrun); | 94 | err |= __put_user(from->si_overrun, &to->si_overrun); |
147 | err |= __put_user(from->si_int, &to->si_int); | 95 | err |= __put_user(from->si_int, &to->si_int); |
148 | break; | 96 | break; |
149 | case __SI_CHLD >> 16: | 97 | case __SI_CHLD >> 16: |
150 | err |= __put_user(from->si_utime, &to->si_utime); | 98 | err |= __put_user(from->si_utime, &to->si_utime); |
151 | err |= __put_user(from->si_stime, &to->si_stime); | 99 | err |= __put_user(from->si_stime, &to->si_stime); |
152 | err |= __put_user(from->si_status, &to->si_status); | 100 | err |= __put_user(from->si_status, &to->si_status); |
153 | default: | 101 | default: |
154 | err |= __put_user(from->si_pid, &to->si_pid); | 102 | err |= __put_user(from->si_pid, &to->si_pid); |
155 | err |= __put_user(from->si_uid, &to->si_uid); | 103 | err |= __put_user(from->si_uid, &to->si_uid); |
156 | break; | 104 | break; |
157 | case __SI_FAULT >> 16: | 105 | case __SI_FAULT >> 16: |
158 | err |= __put_user(from->si_trapno, &to->si_trapno); | 106 | err |= __put_user(from->si_trapno, &to->si_trapno); |
159 | err |= __put_user((unsigned long)from->si_addr, &to->si_addr); | 107 | err |= __put_user((unsigned long)from->si_addr, &to->si_addr); |
160 | break; | 108 | break; |
161 | case __SI_POLL >> 16: | 109 | case __SI_POLL >> 16: |
162 | err |= __put_user(from->si_band, &to->si_band); | 110 | err |= __put_user(from->si_band, &to->si_band); |
163 | err |= __put_user(from->si_fd, &to->si_fd); | 111 | err |= __put_user(from->si_fd, &to->si_fd); |
164 | break; | 112 | break; |
165 | case __SI_RT >> 16: /* This is not generated by the kernel as of now. */ | 113 | case __SI_RT >> 16: /* This is not generated by the kernel as of now. */ |
166 | case __SI_MESGQ >> 16: | 114 | case __SI_MESGQ >> 16: |
167 | err |= __put_user(from->si_pid, &to->si_pid); | 115 | err |= __put_user(from->si_pid, &to->si_pid); |
168 | err |= __put_user(from->si_uid, &to->si_uid); | 116 | err |= __put_user(from->si_uid, &to->si_uid); |
169 | err |= __put_user(from->si_int, &to->si_int); | 117 | err |= __put_user(from->si_int, &to->si_int); |
170 | break; | 118 | break; |
171 | } | 119 | } |
172 | } | 120 | } |
173 | return err; | 121 | return err; |
174 | } | 122 | } |
175 | 123 | ||
176 | /* CAUTION: This is just a very minimalist implementation for the | 124 | /* CAUTION: This is just a very minimalist implementation for the |
177 | * sake of compat_sys_rt_sigqueueinfo() | 125 | * sake of compat_sys_rt_sigqueueinfo() |
178 | */ | 126 | */ |
179 | int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from) | 127 | int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from) |
180 | { | 128 | { |
181 | if (!access_ok(VERIFY_WRITE, from, sizeof(compat_siginfo_t))) | 129 | if (!access_ok(VERIFY_WRITE, from, sizeof(compat_siginfo_t))) |
182 | return -EFAULT; | 130 | return -EFAULT; |
183 | 131 | ||
184 | if (copy_from_user(to, from, 3*sizeof(int)) || | 132 | if (copy_from_user(to, from, 3*sizeof(int)) || |
185 | copy_from_user(to->_sifields._pad, from->_sifields._pad, | 133 | copy_from_user(to->_sifields._pad, from->_sifields._pad, |
186 | SI_PAD_SIZE)) | 134 | SI_PAD_SIZE)) |
187 | return -EFAULT; | 135 | return -EFAULT; |
188 | 136 | ||
189 | return 0; | 137 | return 0; |
190 | } | 138 | } |
191 | 139 | ||
192 | void do_sigreturn32(struct pt_regs *regs) | 140 | void do_sigreturn32(struct pt_regs *regs) |
193 | { | 141 | { |
194 | struct signal_frame32 __user *sf; | 142 | struct signal_frame32 __user *sf; |
195 | compat_uptr_t fpu_save; | 143 | compat_uptr_t fpu_save; |
196 | compat_uptr_t rwin_save; | 144 | compat_uptr_t rwin_save; |
197 | unsigned int psr; | 145 | unsigned int psr; |
198 | unsigned pc, npc; | 146 | unsigned pc, npc; |
199 | sigset_t set; | 147 | sigset_t set; |
200 | unsigned seta[_COMPAT_NSIG_WORDS]; | 148 | unsigned seta[_COMPAT_NSIG_WORDS]; |
201 | int err, i; | 149 | int err, i; |
202 | 150 | ||
203 | /* Always make any pending restarted system calls return -EINTR */ | 151 | /* Always make any pending restarted system calls return -EINTR */ |
204 | current_thread_info()->restart_block.fn = do_no_restart_syscall; | 152 | current_thread_info()->restart_block.fn = do_no_restart_syscall; |
205 | 153 | ||
206 | synchronize_user_stack(); | 154 | synchronize_user_stack(); |
207 | 155 | ||
208 | regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL; | 156 | regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL; |
209 | sf = (struct signal_frame32 __user *) regs->u_regs[UREG_FP]; | 157 | sf = (struct signal_frame32 __user *) regs->u_regs[UREG_FP]; |
210 | 158 | ||
211 | /* 1. Make sure we are not getting garbage from the user */ | 159 | /* 1. Make sure we are not getting garbage from the user */ |
212 | if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) || | 160 | if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) || |
213 | (((unsigned long) sf) & 3)) | 161 | (((unsigned long) sf) & 3)) |
214 | goto segv; | 162 | goto segv; |
215 | 163 | ||
216 | if (get_user(pc, &sf->info.si_regs.pc) || | 164 | if (get_user(pc, &sf->info.si_regs.pc) || |
217 | __get_user(npc, &sf->info.si_regs.npc)) | 165 | __get_user(npc, &sf->info.si_regs.npc)) |
218 | goto segv; | 166 | goto segv; |
219 | 167 | ||
220 | if ((pc | npc) & 3) | 168 | if ((pc | npc) & 3) |
221 | goto segv; | 169 | goto segv; |
222 | 170 | ||
223 | if (test_thread_flag(TIF_32BIT)) { | 171 | if (test_thread_flag(TIF_32BIT)) { |
224 | pc &= 0xffffffff; | 172 | pc &= 0xffffffff; |
225 | npc &= 0xffffffff; | 173 | npc &= 0xffffffff; |
226 | } | 174 | } |
227 | regs->tpc = pc; | 175 | regs->tpc = pc; |
228 | regs->tnpc = npc; | 176 | regs->tnpc = npc; |
229 | 177 | ||
230 | /* 2. Restore the state */ | 178 | /* 2. Restore the state */ |
231 | err = __get_user(regs->y, &sf->info.si_regs.y); | 179 | err = __get_user(regs->y, &sf->info.si_regs.y); |
232 | err |= __get_user(psr, &sf->info.si_regs.psr); | 180 | err |= __get_user(psr, &sf->info.si_regs.psr); |
233 | 181 | ||
234 | for (i = UREG_G1; i <= UREG_I7; i++) | 182 | for (i = UREG_G1; i <= UREG_I7; i++) |
235 | err |= __get_user(regs->u_regs[i], &sf->info.si_regs.u_regs[i]); | 183 | err |= __get_user(regs->u_regs[i], &sf->info.si_regs.u_regs[i]); |
236 | if ((psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS) { | 184 | if ((psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS) { |
237 | err |= __get_user(i, &sf->v8plus.g_upper[0]); | 185 | err |= __get_user(i, &sf->v8plus.g_upper[0]); |
238 | if (i == SIGINFO_EXTRA_V8PLUS_MAGIC) { | 186 | if (i == SIGINFO_EXTRA_V8PLUS_MAGIC) { |
239 | unsigned long asi; | 187 | unsigned long asi; |
240 | 188 | ||
241 | for (i = UREG_G1; i <= UREG_I7; i++) | 189 | for (i = UREG_G1; i <= UREG_I7; i++) |
242 | err |= __get_user(((u32 *)regs->u_regs)[2*i], &sf->v8plus.g_upper[i]); | 190 | err |= __get_user(((u32 *)regs->u_regs)[2*i], &sf->v8plus.g_upper[i]); |
243 | err |= __get_user(asi, &sf->v8plus.asi); | 191 | err |= __get_user(asi, &sf->v8plus.asi); |
244 | regs->tstate &= ~TSTATE_ASI; | 192 | regs->tstate &= ~TSTATE_ASI; |
245 | regs->tstate |= ((asi & 0xffUL) << 24UL); | 193 | regs->tstate |= ((asi & 0xffUL) << 24UL); |
246 | } | 194 | } |
247 | } | 195 | } |
248 | 196 | ||
249 | /* User can only change condition codes in %tstate. */ | 197 | /* User can only change condition codes in %tstate. */ |
250 | regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC); | 198 | regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC); |
251 | regs->tstate |= psr_to_tstate_icc(psr); | 199 | regs->tstate |= psr_to_tstate_icc(psr); |
252 | 200 | ||
253 | /* Prevent syscall restart. */ | 201 | /* Prevent syscall restart. */ |
254 | pt_regs_clear_syscall(regs); | 202 | pt_regs_clear_syscall(regs); |
255 | 203 | ||
256 | err |= __get_user(fpu_save, &sf->fpu_save); | 204 | err |= __get_user(fpu_save, &sf->fpu_save); |
257 | if (!err && fpu_save) | 205 | if (!err && fpu_save) |
258 | err |= restore_fpu_state(regs, compat_ptr(fpu_save)); | 206 | err |= restore_fpu_state(regs, compat_ptr(fpu_save)); |
259 | err |= __get_user(rwin_save, &sf->rwin_save); | 207 | err |= __get_user(rwin_save, &sf->rwin_save); |
260 | if (!err && rwin_save) { | 208 | if (!err && rwin_save) { |
261 | if (restore_rwin_state(compat_ptr(rwin_save))) | 209 | if (restore_rwin_state(compat_ptr(rwin_save))) |
262 | goto segv; | 210 | goto segv; |
263 | } | 211 | } |
264 | err |= __get_user(seta[0], &sf->info.si_mask); | 212 | err |= __get_user(seta[0], &sf->info.si_mask); |
265 | err |= copy_from_user(seta+1, &sf->extramask, | 213 | err |= copy_from_user(seta+1, &sf->extramask, |
266 | (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int)); | 214 | (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int)); |
267 | if (err) | 215 | if (err) |
268 | goto segv; | 216 | goto segv; |
269 | switch (_NSIG_WORDS) { | 217 | switch (_NSIG_WORDS) { |
270 | case 4: set.sig[3] = seta[6] + (((long)seta[7]) << 32); | 218 | case 4: set.sig[3] = seta[6] + (((long)seta[7]) << 32); |
271 | case 3: set.sig[2] = seta[4] + (((long)seta[5]) << 32); | 219 | case 3: set.sig[2] = seta[4] + (((long)seta[5]) << 32); |
272 | case 2: set.sig[1] = seta[2] + (((long)seta[3]) << 32); | 220 | case 2: set.sig[1] = seta[2] + (((long)seta[3]) << 32); |
273 | case 1: set.sig[0] = seta[0] + (((long)seta[1]) << 32); | 221 | case 1: set.sig[0] = seta[0] + (((long)seta[1]) << 32); |
274 | } | 222 | } |
275 | set_current_blocked(&set); | 223 | set_current_blocked(&set); |
276 | return; | 224 | return; |
277 | 225 | ||
278 | segv: | 226 | segv: |
279 | force_sig(SIGSEGV, current); | 227 | force_sig(SIGSEGV, current); |
280 | } | 228 | } |
281 | 229 | ||
282 | asmlinkage void do_rt_sigreturn32(struct pt_regs *regs) | 230 | asmlinkage void do_rt_sigreturn32(struct pt_regs *regs) |
283 | { | 231 | { |
284 | struct rt_signal_frame32 __user *sf; | 232 | struct rt_signal_frame32 __user *sf; |
285 | unsigned int psr, pc, npc, u_ss_sp; | 233 | unsigned int psr, pc, npc, u_ss_sp; |
286 | compat_uptr_t fpu_save; | 234 | compat_uptr_t fpu_save; |
287 | compat_uptr_t rwin_save; | 235 | compat_uptr_t rwin_save; |
288 | mm_segment_t old_fs; | 236 | mm_segment_t old_fs; |
289 | sigset_t set; | 237 | sigset_t set; |
290 | compat_sigset_t seta; | 238 | compat_sigset_t seta; |
291 | stack_t st; | 239 | stack_t st; |
292 | int err, i; | 240 | int err, i; |
293 | 241 | ||
294 | /* Always make any pending restarted system calls return -EINTR */ | 242 | /* Always make any pending restarted system calls return -EINTR */ |
295 | current_thread_info()->restart_block.fn = do_no_restart_syscall; | 243 | current_thread_info()->restart_block.fn = do_no_restart_syscall; |
296 | 244 | ||
297 | synchronize_user_stack(); | 245 | synchronize_user_stack(); |
298 | regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL; | 246 | regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL; |
299 | sf = (struct rt_signal_frame32 __user *) regs->u_regs[UREG_FP]; | 247 | sf = (struct rt_signal_frame32 __user *) regs->u_regs[UREG_FP]; |
300 | 248 | ||
301 | /* 1. Make sure we are not getting garbage from the user */ | 249 | /* 1. Make sure we are not getting garbage from the user */ |
302 | if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) || | 250 | if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) || |
303 | (((unsigned long) sf) & 3)) | 251 | (((unsigned long) sf) & 3)) |
304 | goto segv; | 252 | goto segv; |
305 | 253 | ||
306 | if (get_user(pc, &sf->regs.pc) || | 254 | if (get_user(pc, &sf->regs.pc) || |
307 | __get_user(npc, &sf->regs.npc)) | 255 | __get_user(npc, &sf->regs.npc)) |
308 | goto segv; | 256 | goto segv; |
309 | 257 | ||
310 | if ((pc | npc) & 3) | 258 | if ((pc | npc) & 3) |
311 | goto segv; | 259 | goto segv; |
312 | 260 | ||
313 | if (test_thread_flag(TIF_32BIT)) { | 261 | if (test_thread_flag(TIF_32BIT)) { |
314 | pc &= 0xffffffff; | 262 | pc &= 0xffffffff; |
315 | npc &= 0xffffffff; | 263 | npc &= 0xffffffff; |
316 | } | 264 | } |
317 | regs->tpc = pc; | 265 | regs->tpc = pc; |
318 | regs->tnpc = npc; | 266 | regs->tnpc = npc; |
319 | 267 | ||
320 | /* 2. Restore the state */ | 268 | /* 2. Restore the state */ |
321 | err = __get_user(regs->y, &sf->regs.y); | 269 | err = __get_user(regs->y, &sf->regs.y); |
322 | err |= __get_user(psr, &sf->regs.psr); | 270 | err |= __get_user(psr, &sf->regs.psr); |
323 | 271 | ||
324 | for (i = UREG_G1; i <= UREG_I7; i++) | 272 | for (i = UREG_G1; i <= UREG_I7; i++) |
325 | err |= __get_user(regs->u_regs[i], &sf->regs.u_regs[i]); | 273 | err |= __get_user(regs->u_regs[i], &sf->regs.u_regs[i]); |
326 | if ((psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS) { | 274 | if ((psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS) { |
327 | err |= __get_user(i, &sf->v8plus.g_upper[0]); | 275 | err |= __get_user(i, &sf->v8plus.g_upper[0]); |
328 | if (i == SIGINFO_EXTRA_V8PLUS_MAGIC) { | 276 | if (i == SIGINFO_EXTRA_V8PLUS_MAGIC) { |
329 | unsigned long asi; | 277 | unsigned long asi; |
330 | 278 | ||
331 | for (i = UREG_G1; i <= UREG_I7; i++) | 279 | for (i = UREG_G1; i <= UREG_I7; i++) |
332 | err |= __get_user(((u32 *)regs->u_regs)[2*i], &sf->v8plus.g_upper[i]); | 280 | err |= __get_user(((u32 *)regs->u_regs)[2*i], &sf->v8plus.g_upper[i]); |
333 | err |= __get_user(asi, &sf->v8plus.asi); | 281 | err |= __get_user(asi, &sf->v8plus.asi); |
334 | regs->tstate &= ~TSTATE_ASI; | 282 | regs->tstate &= ~TSTATE_ASI; |
335 | regs->tstate |= ((asi & 0xffUL) << 24UL); | 283 | regs->tstate |= ((asi & 0xffUL) << 24UL); |
336 | } | 284 | } |
337 | } | 285 | } |
338 | 286 | ||
339 | /* User can only change condition codes in %tstate. */ | 287 | /* User can only change condition codes in %tstate. */ |
340 | regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC); | 288 | regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC); |
341 | regs->tstate |= psr_to_tstate_icc(psr); | 289 | regs->tstate |= psr_to_tstate_icc(psr); |
342 | 290 | ||
343 | /* Prevent syscall restart. */ | 291 | /* Prevent syscall restart. */ |
344 | pt_regs_clear_syscall(regs); | 292 | pt_regs_clear_syscall(regs); |
345 | 293 | ||
346 | err |= __get_user(fpu_save, &sf->fpu_save); | 294 | err |= __get_user(fpu_save, &sf->fpu_save); |
347 | if (!err && fpu_save) | 295 | if (!err && fpu_save) |
348 | err |= restore_fpu_state(regs, compat_ptr(fpu_save)); | 296 | err |= restore_fpu_state(regs, compat_ptr(fpu_save)); |
349 | err |= copy_from_user(&seta, &sf->mask, sizeof(compat_sigset_t)); | 297 | err |= copy_from_user(&seta, &sf->mask, sizeof(compat_sigset_t)); |
350 | err |= __get_user(u_ss_sp, &sf->stack.ss_sp); | 298 | err |= __get_user(u_ss_sp, &sf->stack.ss_sp); |
351 | st.ss_sp = compat_ptr(u_ss_sp); | 299 | st.ss_sp = compat_ptr(u_ss_sp); |
352 | err |= __get_user(st.ss_flags, &sf->stack.ss_flags); | 300 | err |= __get_user(st.ss_flags, &sf->stack.ss_flags); |
353 | err |= __get_user(st.ss_size, &sf->stack.ss_size); | 301 | err |= __get_user(st.ss_size, &sf->stack.ss_size); |
354 | if (err) | 302 | if (err) |
355 | goto segv; | 303 | goto segv; |
356 | 304 | ||
357 | /* It is more difficult to avoid calling this function than to | 305 | /* It is more difficult to avoid calling this function than to |
358 | call it and ignore errors. */ | 306 | call it and ignore errors. */ |
359 | old_fs = get_fs(); | 307 | old_fs = get_fs(); |
360 | set_fs(KERNEL_DS); | 308 | set_fs(KERNEL_DS); |
361 | do_sigaltstack((stack_t __user *) &st, NULL, (unsigned long)sf); | 309 | do_sigaltstack((stack_t __user *) &st, NULL, (unsigned long)sf); |
362 | set_fs(old_fs); | 310 | set_fs(old_fs); |
363 | 311 | ||
364 | err |= __get_user(rwin_save, &sf->rwin_save); | 312 | err |= __get_user(rwin_save, &sf->rwin_save); |
365 | if (!err && rwin_save) { | 313 | if (!err && rwin_save) { |
366 | if (restore_rwin_state(compat_ptr(rwin_save))) | 314 | if (restore_rwin_state(compat_ptr(rwin_save))) |
367 | goto segv; | 315 | goto segv; |
368 | } | 316 | } |
369 | 317 | ||
370 | switch (_NSIG_WORDS) { | 318 | switch (_NSIG_WORDS) { |
371 | case 4: set.sig[3] = seta.sig[6] + (((long)seta.sig[7]) << 32); | 319 | case 4: set.sig[3] = seta.sig[6] + (((long)seta.sig[7]) << 32); |
372 | case 3: set.sig[2] = seta.sig[4] + (((long)seta.sig[5]) << 32); | 320 | case 3: set.sig[2] = seta.sig[4] + (((long)seta.sig[5]) << 32); |
373 | case 2: set.sig[1] = seta.sig[2] + (((long)seta.sig[3]) << 32); | 321 | case 2: set.sig[1] = seta.sig[2] + (((long)seta.sig[3]) << 32); |
374 | case 1: set.sig[0] = seta.sig[0] + (((long)seta.sig[1]) << 32); | 322 | case 1: set.sig[0] = seta.sig[0] + (((long)seta.sig[1]) << 32); |
375 | } | 323 | } |
376 | set_current_blocked(&set); | 324 | set_current_blocked(&set); |
377 | return; | 325 | return; |
378 | segv: | 326 | segv: |
379 | force_sig(SIGSEGV, current); | 327 | force_sig(SIGSEGV, current); |
380 | } | 328 | } |
381 | 329 | ||
382 | /* Checks if the fp is valid */ | 330 | /* Checks if the fp is valid */ |
383 | static int invalid_frame_pointer(void __user *fp, int fplen) | 331 | static int invalid_frame_pointer(void __user *fp, int fplen) |
384 | { | 332 | { |
385 | if ((((unsigned long) fp) & 7) || ((unsigned long)fp) > 0x100000000ULL - fplen) | 333 | if ((((unsigned long) fp) & 7) || ((unsigned long)fp) > 0x100000000ULL - fplen) |
386 | return 1; | 334 | return 1; |
387 | return 0; | 335 | return 0; |
388 | } | 336 | } |
389 | 337 | ||
390 | static void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, unsigned long framesize) | 338 | static void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, unsigned long framesize) |
391 | { | 339 | { |
392 | unsigned long sp; | 340 | unsigned long sp; |
393 | 341 | ||
394 | regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL; | 342 | regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL; |
395 | sp = regs->u_regs[UREG_FP]; | 343 | sp = regs->u_regs[UREG_FP]; |
396 | 344 | ||
397 | /* | 345 | /* |
398 | * If we are on the alternate signal stack and would overflow it, don't. | 346 | * If we are on the alternate signal stack and would overflow it, don't. |
399 | * Return an always-bogus address instead so we will die with SIGSEGV. | 347 | * Return an always-bogus address instead so we will die with SIGSEGV. |
400 | */ | 348 | */ |
401 | if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize))) | 349 | if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize))) |
402 | return (void __user *) -1L; | 350 | return (void __user *) -1L; |
403 | 351 | ||
404 | /* This is the X/Open sanctioned signal stack switching. */ | 352 | /* This is the X/Open sanctioned signal stack switching. */ |
405 | if (sa->sa_flags & SA_ONSTACK) { | 353 | if (sa->sa_flags & SA_ONSTACK) { |
406 | if (sas_ss_flags(sp) == 0) | 354 | if (sas_ss_flags(sp) == 0) |
407 | sp = current->sas_ss_sp + current->sas_ss_size; | 355 | sp = current->sas_ss_sp + current->sas_ss_size; |
408 | } | 356 | } |
409 | 357 | ||
410 | sp -= framesize; | 358 | sp -= framesize; |
411 | 359 | ||
412 | /* Always align the stack frame. This handles two cases. First, | 360 | /* Always align the stack frame. This handles two cases. First, |
413 | * sigaltstack need not be mindful of platform specific stack | 361 | * sigaltstack need not be mindful of platform specific stack |
414 | * alignment. Second, if we took this signal because the stack | 362 | * alignment. Second, if we took this signal because the stack |
415 | * is not aligned properly, we'd like to take the signal cleanly | 363 | * is not aligned properly, we'd like to take the signal cleanly |
416 | * and report that. | 364 | * and report that. |
417 | */ | 365 | */ |
418 | sp &= ~15UL; | 366 | sp &= ~15UL; |
419 | 367 | ||
420 | return (void __user *) sp; | 368 | return (void __user *) sp; |
421 | } | 369 | } |
422 | 370 | ||
423 | /* The I-cache flush instruction only works in the primary ASI, which | 371 | /* The I-cache flush instruction only works in the primary ASI, which |
424 | * right now is the nucleus, aka. kernel space. | 372 | * right now is the nucleus, aka. kernel space. |
425 | * | 373 | * |
426 | * Therefore we have to kick the instructions out using the kernel | 374 | * Therefore we have to kick the instructions out using the kernel |
427 | * side linear mapping of the physical address backing the user | 375 | * side linear mapping of the physical address backing the user |
428 | * instructions. | 376 | * instructions. |
429 | */ | 377 | */ |
430 | static void flush_signal_insns(unsigned long address) | 378 | static void flush_signal_insns(unsigned long address) |
431 | { | 379 | { |
432 | unsigned long pstate, paddr; | 380 | unsigned long pstate, paddr; |
433 | pte_t *ptep, pte; | 381 | pte_t *ptep, pte; |
434 | pgd_t *pgdp; | 382 | pgd_t *pgdp; |
435 | pud_t *pudp; | 383 | pud_t *pudp; |
436 | pmd_t *pmdp; | 384 | pmd_t *pmdp; |
437 | 385 | ||
438 | /* Commit all stores of the instructions we are about to flush. */ | 386 | /* Commit all stores of the instructions we are about to flush. */ |
439 | wmb(); | 387 | wmb(); |
440 | 388 | ||
441 | /* Disable cross-call reception. In this way even a very wide | 389 | /* Disable cross-call reception. In this way even a very wide |
442 | * munmap() on another cpu can't tear down the page table | 390 | * munmap() on another cpu can't tear down the page table |
443 | * hierarchy from underneath us, since that can't complete | 391 | * hierarchy from underneath us, since that can't complete |
444 | * until the IPI tlb flush returns. | 392 | * until the IPI tlb flush returns. |
445 | */ | 393 | */ |
446 | 394 | ||
447 | __asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate)); | 395 | __asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate)); |
448 | __asm__ __volatile__("wrpr %0, %1, %%pstate" | 396 | __asm__ __volatile__("wrpr %0, %1, %%pstate" |
449 | : : "r" (pstate), "i" (PSTATE_IE)); | 397 | : : "r" (pstate), "i" (PSTATE_IE)); |
450 | 398 | ||
451 | pgdp = pgd_offset(current->mm, address); | 399 | pgdp = pgd_offset(current->mm, address); |
452 | if (pgd_none(*pgdp)) | 400 | if (pgd_none(*pgdp)) |
453 | goto out_irqs_on; | 401 | goto out_irqs_on; |
454 | pudp = pud_offset(pgdp, address); | 402 | pudp = pud_offset(pgdp, address); |
455 | if (pud_none(*pudp)) | 403 | if (pud_none(*pudp)) |
456 | goto out_irqs_on; | 404 | goto out_irqs_on; |
457 | pmdp = pmd_offset(pudp, address); | 405 | pmdp = pmd_offset(pudp, address); |
458 | if (pmd_none(*pmdp)) | 406 | if (pmd_none(*pmdp)) |
459 | goto out_irqs_on; | 407 | goto out_irqs_on; |
460 | 408 | ||
461 | ptep = pte_offset_map(pmdp, address); | 409 | ptep = pte_offset_map(pmdp, address); |
462 | pte = *ptep; | 410 | pte = *ptep; |
463 | if (!pte_present(pte)) | 411 | if (!pte_present(pte)) |
464 | goto out_unmap; | 412 | goto out_unmap; |
465 | 413 | ||
466 | paddr = (unsigned long) page_address(pte_page(pte)); | 414 | paddr = (unsigned long) page_address(pte_page(pte)); |
467 | 415 | ||
468 | __asm__ __volatile__("flush %0 + %1" | 416 | __asm__ __volatile__("flush %0 + %1" |
469 | : /* no outputs */ | 417 | : /* no outputs */ |
470 | : "r" (paddr), | 418 | : "r" (paddr), |
471 | "r" (address & (PAGE_SIZE - 1)) | 419 | "r" (address & (PAGE_SIZE - 1)) |
472 | : "memory"); | 420 | : "memory"); |
473 | 421 | ||
474 | out_unmap: | 422 | out_unmap: |
475 | pte_unmap(ptep); | 423 | pte_unmap(ptep); |
476 | out_irqs_on: | 424 | out_irqs_on: |
477 | __asm__ __volatile__("wrpr %0, 0x0, %%pstate" : : "r" (pstate)); | 425 | __asm__ __volatile__("wrpr %0, 0x0, %%pstate" : : "r" (pstate)); |
478 | 426 | ||
479 | } | 427 | } |
480 | 428 | ||
481 | static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, | 429 | static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, |
482 | int signo, sigset_t *oldset) | 430 | int signo, sigset_t *oldset) |
483 | { | 431 | { |
484 | struct signal_frame32 __user *sf; | 432 | struct signal_frame32 __user *sf; |
485 | int i, err, wsaved; | 433 | int i, err, wsaved; |
486 | void __user *tail; | 434 | void __user *tail; |
487 | int sigframe_size; | 435 | int sigframe_size; |
488 | u32 psr; | 436 | u32 psr; |
489 | unsigned int seta[_COMPAT_NSIG_WORDS]; | 437 | unsigned int seta[_COMPAT_NSIG_WORDS]; |
490 | 438 | ||
491 | /* 1. Make sure everything is clean */ | 439 | /* 1. Make sure everything is clean */ |
492 | synchronize_user_stack(); | 440 | synchronize_user_stack(); |
493 | save_and_clear_fpu(); | 441 | save_and_clear_fpu(); |
494 | 442 | ||
495 | wsaved = get_thread_wsaved(); | 443 | wsaved = get_thread_wsaved(); |
496 | 444 | ||
497 | sigframe_size = sizeof(*sf); | 445 | sigframe_size = sizeof(*sf); |
498 | if (current_thread_info()->fpsaved[0] & FPRS_FEF) | 446 | if (current_thread_info()->fpsaved[0] & FPRS_FEF) |
499 | sigframe_size += sizeof(__siginfo_fpu_t); | 447 | sigframe_size += sizeof(__siginfo_fpu_t); |
500 | if (wsaved) | 448 | if (wsaved) |
501 | sigframe_size += sizeof(__siginfo_rwin_t); | 449 | sigframe_size += sizeof(__siginfo_rwin_t); |
502 | 450 | ||
503 | sf = (struct signal_frame32 __user *) | 451 | sf = (struct signal_frame32 __user *) |
504 | get_sigframe(&ka->sa, regs, sigframe_size); | 452 | get_sigframe(&ka->sa, regs, sigframe_size); |
505 | 453 | ||
506 | if (invalid_frame_pointer(sf, sigframe_size)) | 454 | if (invalid_frame_pointer(sf, sigframe_size)) |
507 | goto sigill; | 455 | goto sigill; |
508 | 456 | ||
509 | tail = (sf + 1); | 457 | tail = (sf + 1); |
510 | 458 | ||
511 | /* 2. Save the current process state */ | 459 | /* 2. Save the current process state */ |
512 | if (test_thread_flag(TIF_32BIT)) { | 460 | if (test_thread_flag(TIF_32BIT)) { |
513 | regs->tpc &= 0xffffffff; | 461 | regs->tpc &= 0xffffffff; |
514 | regs->tnpc &= 0xffffffff; | 462 | regs->tnpc &= 0xffffffff; |
515 | } | 463 | } |
516 | err = put_user(regs->tpc, &sf->info.si_regs.pc); | 464 | err = put_user(regs->tpc, &sf->info.si_regs.pc); |
517 | err |= __put_user(regs->tnpc, &sf->info.si_regs.npc); | 465 | err |= __put_user(regs->tnpc, &sf->info.si_regs.npc); |
518 | err |= __put_user(regs->y, &sf->info.si_regs.y); | 466 | err |= __put_user(regs->y, &sf->info.si_regs.y); |
519 | psr = tstate_to_psr(regs->tstate); | 467 | psr = tstate_to_psr(regs->tstate); |
520 | if (current_thread_info()->fpsaved[0] & FPRS_FEF) | 468 | if (current_thread_info()->fpsaved[0] & FPRS_FEF) |
521 | psr |= PSR_EF; | 469 | psr |= PSR_EF; |
522 | err |= __put_user(psr, &sf->info.si_regs.psr); | 470 | err |= __put_user(psr, &sf->info.si_regs.psr); |
523 | for (i = 0; i < 16; i++) | 471 | for (i = 0; i < 16; i++) |
524 | err |= __put_user(regs->u_regs[i], &sf->info.si_regs.u_regs[i]); | 472 | err |= __put_user(regs->u_regs[i], &sf->info.si_regs.u_regs[i]); |
525 | err |= __put_user(sizeof(siginfo_extra_v8plus_t), &sf->extra_size); | 473 | err |= __put_user(sizeof(siginfo_extra_v8plus_t), &sf->extra_size); |
526 | err |= __put_user(SIGINFO_EXTRA_V8PLUS_MAGIC, &sf->v8plus.g_upper[0]); | 474 | err |= __put_user(SIGINFO_EXTRA_V8PLUS_MAGIC, &sf->v8plus.g_upper[0]); |
527 | for (i = 1; i < 16; i++) | 475 | for (i = 1; i < 16; i++) |
528 | err |= __put_user(((u32 *)regs->u_regs)[2*i], | 476 | err |= __put_user(((u32 *)regs->u_regs)[2*i], |
529 | &sf->v8plus.g_upper[i]); | 477 | &sf->v8plus.g_upper[i]); |
530 | err |= __put_user((regs->tstate & TSTATE_ASI) >> 24UL, | 478 | err |= __put_user((regs->tstate & TSTATE_ASI) >> 24UL, |
531 | &sf->v8plus.asi); | 479 | &sf->v8plus.asi); |
532 | 480 | ||
533 | if (psr & PSR_EF) { | 481 | if (psr & PSR_EF) { |
534 | __siginfo_fpu_t __user *fp = tail; | 482 | __siginfo_fpu_t __user *fp = tail; |
535 | tail += sizeof(*fp); | 483 | tail += sizeof(*fp); |
536 | err |= save_fpu_state(regs, fp); | 484 | err |= save_fpu_state(regs, fp); |
537 | err |= __put_user((u64)fp, &sf->fpu_save); | 485 | err |= __put_user((u64)fp, &sf->fpu_save); |
538 | } else { | 486 | } else { |
539 | err |= __put_user(0, &sf->fpu_save); | 487 | err |= __put_user(0, &sf->fpu_save); |
540 | } | 488 | } |
541 | if (wsaved) { | 489 | if (wsaved) { |
542 | __siginfo_rwin_t __user *rwp = tail; | 490 | __siginfo_rwin_t __user *rwp = tail; |
543 | tail += sizeof(*rwp); | 491 | tail += sizeof(*rwp); |
544 | err |= save_rwin_state(wsaved, rwp); | 492 | err |= save_rwin_state(wsaved, rwp); |
545 | err |= __put_user((u64)rwp, &sf->rwin_save); | 493 | err |= __put_user((u64)rwp, &sf->rwin_save); |
546 | set_thread_wsaved(0); | 494 | set_thread_wsaved(0); |
547 | } else { | 495 | } else { |
548 | err |= __put_user(0, &sf->rwin_save); | 496 | err |= __put_user(0, &sf->rwin_save); |
549 | } | 497 | } |
550 | 498 | ||
551 | switch (_NSIG_WORDS) { | 499 | switch (_NSIG_WORDS) { |
552 | case 4: seta[7] = (oldset->sig[3] >> 32); | 500 | case 4: seta[7] = (oldset->sig[3] >> 32); |
553 | seta[6] = oldset->sig[3]; | 501 | seta[6] = oldset->sig[3]; |
554 | case 3: seta[5] = (oldset->sig[2] >> 32); | 502 | case 3: seta[5] = (oldset->sig[2] >> 32); |
555 | seta[4] = oldset->sig[2]; | 503 | seta[4] = oldset->sig[2]; |
556 | case 2: seta[3] = (oldset->sig[1] >> 32); | 504 | case 2: seta[3] = (oldset->sig[1] >> 32); |
557 | seta[2] = oldset->sig[1]; | 505 | seta[2] = oldset->sig[1]; |
558 | case 1: seta[1] = (oldset->sig[0] >> 32); | 506 | case 1: seta[1] = (oldset->sig[0] >> 32); |
559 | seta[0] = oldset->sig[0]; | 507 | seta[0] = oldset->sig[0]; |
560 | } | 508 | } |
561 | err |= __put_user(seta[0], &sf->info.si_mask); | 509 | err |= __put_user(seta[0], &sf->info.si_mask); |
562 | err |= __copy_to_user(sf->extramask, seta + 1, | 510 | err |= __copy_to_user(sf->extramask, seta + 1, |
563 | (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int)); | 511 | (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int)); |
564 | 512 | ||
565 | if (!wsaved) { | 513 | if (!wsaved) { |
566 | err |= copy_in_user((u32 __user *)sf, | 514 | err |= copy_in_user((u32 __user *)sf, |
567 | (u32 __user *)(regs->u_regs[UREG_FP]), | 515 | (u32 __user *)(regs->u_regs[UREG_FP]), |
568 | sizeof(struct reg_window32)); | 516 | sizeof(struct reg_window32)); |
569 | } else { | 517 | } else { |
570 | struct reg_window *rp; | 518 | struct reg_window *rp; |
571 | 519 | ||
572 | rp = ¤t_thread_info()->reg_window[wsaved - 1]; | 520 | rp = ¤t_thread_info()->reg_window[wsaved - 1]; |
573 | for (i = 0; i < 8; i++) | 521 | for (i = 0; i < 8; i++) |
574 | err |= __put_user(rp->locals[i], &sf->ss.locals[i]); | 522 | err |= __put_user(rp->locals[i], &sf->ss.locals[i]); |
575 | for (i = 0; i < 6; i++) | 523 | for (i = 0; i < 6; i++) |
576 | err |= __put_user(rp->ins[i], &sf->ss.ins[i]); | 524 | err |= __put_user(rp->ins[i], &sf->ss.ins[i]); |
577 | err |= __put_user(rp->ins[6], &sf->ss.fp); | 525 | err |= __put_user(rp->ins[6], &sf->ss.fp); |
578 | err |= __put_user(rp->ins[7], &sf->ss.callers_pc); | 526 | err |= __put_user(rp->ins[7], &sf->ss.callers_pc); |
579 | } | 527 | } |
580 | if (err) | 528 | if (err) |
581 | goto sigsegv; | 529 | goto sigsegv; |
582 | 530 | ||
583 | /* 3. signal handler back-trampoline and parameters */ | 531 | /* 3. signal handler back-trampoline and parameters */ |
584 | regs->u_regs[UREG_FP] = (unsigned long) sf; | 532 | regs->u_regs[UREG_FP] = (unsigned long) sf; |
585 | regs->u_regs[UREG_I0] = signo; | 533 | regs->u_regs[UREG_I0] = signo; |
586 | regs->u_regs[UREG_I1] = (unsigned long) &sf->info; | 534 | regs->u_regs[UREG_I1] = (unsigned long) &sf->info; |
587 | regs->u_regs[UREG_I2] = (unsigned long) &sf->info; | 535 | regs->u_regs[UREG_I2] = (unsigned long) &sf->info; |
588 | 536 | ||
589 | /* 4. signal handler */ | 537 | /* 4. signal handler */ |
590 | regs->tpc = (unsigned long) ka->sa.sa_handler; | 538 | regs->tpc = (unsigned long) ka->sa.sa_handler; |
591 | regs->tnpc = (regs->tpc + 4); | 539 | regs->tnpc = (regs->tpc + 4); |
592 | if (test_thread_flag(TIF_32BIT)) { | 540 | if (test_thread_flag(TIF_32BIT)) { |
593 | regs->tpc &= 0xffffffff; | 541 | regs->tpc &= 0xffffffff; |
594 | regs->tnpc &= 0xffffffff; | 542 | regs->tnpc &= 0xffffffff; |
595 | } | 543 | } |
596 | 544 | ||
597 | /* 5. return to kernel instructions */ | 545 | /* 5. return to kernel instructions */ |
598 | if (ka->ka_restorer) { | 546 | if (ka->ka_restorer) { |
599 | regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; | 547 | regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; |
600 | } else { | 548 | } else { |
601 | unsigned long address = ((unsigned long)&(sf->insns[0])); | 549 | unsigned long address = ((unsigned long)&(sf->insns[0])); |
602 | 550 | ||
603 | regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2); | 551 | regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2); |
604 | 552 | ||
605 | err = __put_user(0x821020d8, &sf->insns[0]); /*mov __NR_sigreturn, %g1*/ | 553 | err = __put_user(0x821020d8, &sf->insns[0]); /*mov __NR_sigreturn, %g1*/ |
606 | err |= __put_user(0x91d02010, &sf->insns[1]); /*t 0x10*/ | 554 | err |= __put_user(0x91d02010, &sf->insns[1]); /*t 0x10*/ |
607 | if (err) | 555 | if (err) |
608 | goto sigsegv; | 556 | goto sigsegv; |
609 | flush_signal_insns(address); | 557 | flush_signal_insns(address); |
610 | } | 558 | } |
611 | return 0; | 559 | return 0; |
612 | 560 | ||
613 | sigill: | 561 | sigill: |
614 | do_exit(SIGILL); | 562 | do_exit(SIGILL); |
615 | return -EINVAL; | 563 | return -EINVAL; |
616 | 564 | ||
617 | sigsegv: | 565 | sigsegv: |
618 | force_sigsegv(signo, current); | 566 | force_sigsegv(signo, current); |
619 | return -EFAULT; | 567 | return -EFAULT; |
620 | } | 568 | } |
621 | 569 | ||
622 | static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, | 570 | static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, |
623 | unsigned long signr, sigset_t *oldset, | 571 | unsigned long signr, sigset_t *oldset, |
624 | siginfo_t *info) | 572 | siginfo_t *info) |
625 | { | 573 | { |
626 | struct rt_signal_frame32 __user *sf; | 574 | struct rt_signal_frame32 __user *sf; |
627 | int i, err, wsaved; | 575 | int i, err, wsaved; |
628 | void __user *tail; | 576 | void __user *tail; |
629 | int sigframe_size; | 577 | int sigframe_size; |
630 | u32 psr; | 578 | u32 psr; |
631 | compat_sigset_t seta; | 579 | compat_sigset_t seta; |
632 | 580 | ||
633 | /* 1. Make sure everything is clean */ | 581 | /* 1. Make sure everything is clean */ |
634 | synchronize_user_stack(); | 582 | synchronize_user_stack(); |
635 | save_and_clear_fpu(); | 583 | save_and_clear_fpu(); |
636 | 584 | ||
637 | wsaved = get_thread_wsaved(); | 585 | wsaved = get_thread_wsaved(); |
638 | 586 | ||
639 | sigframe_size = sizeof(*sf); | 587 | sigframe_size = sizeof(*sf); |
640 | if (current_thread_info()->fpsaved[0] & FPRS_FEF) | 588 | if (current_thread_info()->fpsaved[0] & FPRS_FEF) |
641 | sigframe_size += sizeof(__siginfo_fpu_t); | 589 | sigframe_size += sizeof(__siginfo_fpu_t); |
642 | if (wsaved) | 590 | if (wsaved) |
643 | sigframe_size += sizeof(__siginfo_rwin_t); | 591 | sigframe_size += sizeof(__siginfo_rwin_t); |
644 | 592 | ||
645 | sf = (struct rt_signal_frame32 __user *) | 593 | sf = (struct rt_signal_frame32 __user *) |
646 | get_sigframe(&ka->sa, regs, sigframe_size); | 594 | get_sigframe(&ka->sa, regs, sigframe_size); |
647 | 595 | ||
648 | if (invalid_frame_pointer(sf, sigframe_size)) | 596 | if (invalid_frame_pointer(sf, sigframe_size)) |
649 | goto sigill; | 597 | goto sigill; |
650 | 598 | ||
651 | tail = (sf + 1); | 599 | tail = (sf + 1); |
652 | 600 | ||
653 | /* 2. Save the current process state */ | 601 | /* 2. Save the current process state */ |
654 | if (test_thread_flag(TIF_32BIT)) { | 602 | if (test_thread_flag(TIF_32BIT)) { |
655 | regs->tpc &= 0xffffffff; | 603 | regs->tpc &= 0xffffffff; |
656 | regs->tnpc &= 0xffffffff; | 604 | regs->tnpc &= 0xffffffff; |
657 | } | 605 | } |
658 | err = put_user(regs->tpc, &sf->regs.pc); | 606 | err = put_user(regs->tpc, &sf->regs.pc); |
659 | err |= __put_user(regs->tnpc, &sf->regs.npc); | 607 | err |= __put_user(regs->tnpc, &sf->regs.npc); |
660 | err |= __put_user(regs->y, &sf->regs.y); | 608 | err |= __put_user(regs->y, &sf->regs.y); |
661 | psr = tstate_to_psr(regs->tstate); | 609 | psr = tstate_to_psr(regs->tstate); |
662 | if (current_thread_info()->fpsaved[0] & FPRS_FEF) | 610 | if (current_thread_info()->fpsaved[0] & FPRS_FEF) |
663 | psr |= PSR_EF; | 611 | psr |= PSR_EF; |
664 | err |= __put_user(psr, &sf->regs.psr); | 612 | err |= __put_user(psr, &sf->regs.psr); |
665 | for (i = 0; i < 16; i++) | 613 | for (i = 0; i < 16; i++) |
666 | err |= __put_user(regs->u_regs[i], &sf->regs.u_regs[i]); | 614 | err |= __put_user(regs->u_regs[i], &sf->regs.u_regs[i]); |
667 | err |= __put_user(sizeof(siginfo_extra_v8plus_t), &sf->extra_size); | 615 | err |= __put_user(sizeof(siginfo_extra_v8plus_t), &sf->extra_size); |
668 | err |= __put_user(SIGINFO_EXTRA_V8PLUS_MAGIC, &sf->v8plus.g_upper[0]); | 616 | err |= __put_user(SIGINFO_EXTRA_V8PLUS_MAGIC, &sf->v8plus.g_upper[0]); |
669 | for (i = 1; i < 16; i++) | 617 | for (i = 1; i < 16; i++) |
670 | err |= __put_user(((u32 *)regs->u_regs)[2*i], | 618 | err |= __put_user(((u32 *)regs->u_regs)[2*i], |
671 | &sf->v8plus.g_upper[i]); | 619 | &sf->v8plus.g_upper[i]); |
672 | err |= __put_user((regs->tstate & TSTATE_ASI) >> 24UL, | 620 | err |= __put_user((regs->tstate & TSTATE_ASI) >> 24UL, |
673 | &sf->v8plus.asi); | 621 | &sf->v8plus.asi); |
674 | 622 | ||
675 | if (psr & PSR_EF) { | 623 | if (psr & PSR_EF) { |
676 | __siginfo_fpu_t __user *fp = tail; | 624 | __siginfo_fpu_t __user *fp = tail; |
677 | tail += sizeof(*fp); | 625 | tail += sizeof(*fp); |
678 | err |= save_fpu_state(regs, fp); | 626 | err |= save_fpu_state(regs, fp); |
679 | err |= __put_user((u64)fp, &sf->fpu_save); | 627 | err |= __put_user((u64)fp, &sf->fpu_save); |
680 | } else { | 628 | } else { |
681 | err |= __put_user(0, &sf->fpu_save); | 629 | err |= __put_user(0, &sf->fpu_save); |
682 | } | 630 | } |
683 | if (wsaved) { | 631 | if (wsaved) { |
684 | __siginfo_rwin_t __user *rwp = tail; | 632 | __siginfo_rwin_t __user *rwp = tail; |
685 | tail += sizeof(*rwp); | 633 | tail += sizeof(*rwp); |
686 | err |= save_rwin_state(wsaved, rwp); | 634 | err |= save_rwin_state(wsaved, rwp); |
687 | err |= __put_user((u64)rwp, &sf->rwin_save); | 635 | err |= __put_user((u64)rwp, &sf->rwin_save); |
688 | set_thread_wsaved(0); | 636 | set_thread_wsaved(0); |
689 | } else { | 637 | } else { |
690 | err |= __put_user(0, &sf->rwin_save); | 638 | err |= __put_user(0, &sf->rwin_save); |
691 | } | 639 | } |
692 | 640 | ||
693 | /* Update the siginfo structure. */ | 641 | /* Update the siginfo structure. */ |
694 | err |= copy_siginfo_to_user32(&sf->info, info); | 642 | err |= copy_siginfo_to_user32(&sf->info, info); |
695 | 643 | ||
696 | /* Setup sigaltstack */ | 644 | /* Setup sigaltstack */ |
697 | err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp); | 645 | err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp); |
698 | err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &sf->stack.ss_flags); | 646 | err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &sf->stack.ss_flags); |
699 | err |= __put_user(current->sas_ss_size, &sf->stack.ss_size); | 647 | err |= __put_user(current->sas_ss_size, &sf->stack.ss_size); |
700 | 648 | ||
701 | switch (_NSIG_WORDS) { | 649 | switch (_NSIG_WORDS) { |
702 | case 4: seta.sig[7] = (oldset->sig[3] >> 32); | 650 | case 4: seta.sig[7] = (oldset->sig[3] >> 32); |
703 | seta.sig[6] = oldset->sig[3]; | 651 | seta.sig[6] = oldset->sig[3]; |
704 | case 3: seta.sig[5] = (oldset->sig[2] >> 32); | 652 | case 3: seta.sig[5] = (oldset->sig[2] >> 32); |
705 | seta.sig[4] = oldset->sig[2]; | 653 | seta.sig[4] = oldset->sig[2]; |
706 | case 2: seta.sig[3] = (oldset->sig[1] >> 32); | 654 | case 2: seta.sig[3] = (oldset->sig[1] >> 32); |
707 | seta.sig[2] = oldset->sig[1]; | 655 | seta.sig[2] = oldset->sig[1]; |
708 | case 1: seta.sig[1] = (oldset->sig[0] >> 32); | 656 | case 1: seta.sig[1] = (oldset->sig[0] >> 32); |
709 | seta.sig[0] = oldset->sig[0]; | 657 | seta.sig[0] = oldset->sig[0]; |
710 | } | 658 | } |
711 | err |= __copy_to_user(&sf->mask, &seta, sizeof(compat_sigset_t)); | 659 | err |= __copy_to_user(&sf->mask, &seta, sizeof(compat_sigset_t)); |
712 | 660 | ||
713 | if (!wsaved) { | 661 | if (!wsaved) { |
714 | err |= copy_in_user((u32 __user *)sf, | 662 | err |= copy_in_user((u32 __user *)sf, |
715 | (u32 __user *)(regs->u_regs[UREG_FP]), | 663 | (u32 __user *)(regs->u_regs[UREG_FP]), |
716 | sizeof(struct reg_window32)); | 664 | sizeof(struct reg_window32)); |
717 | } else { | 665 | } else { |
718 | struct reg_window *rp; | 666 | struct reg_window *rp; |
719 | 667 | ||
720 | rp = ¤t_thread_info()->reg_window[wsaved - 1]; | 668 | rp = ¤t_thread_info()->reg_window[wsaved - 1]; |
721 | for (i = 0; i < 8; i++) | 669 | for (i = 0; i < 8; i++) |
722 | err |= __put_user(rp->locals[i], &sf->ss.locals[i]); | 670 | err |= __put_user(rp->locals[i], &sf->ss.locals[i]); |
723 | for (i = 0; i < 6; i++) | 671 | for (i = 0; i < 6; i++) |
724 | err |= __put_user(rp->ins[i], &sf->ss.ins[i]); | 672 | err |= __put_user(rp->ins[i], &sf->ss.ins[i]); |
725 | err |= __put_user(rp->ins[6], &sf->ss.fp); | 673 | err |= __put_user(rp->ins[6], &sf->ss.fp); |
726 | err |= __put_user(rp->ins[7], &sf->ss.callers_pc); | 674 | err |= __put_user(rp->ins[7], &sf->ss.callers_pc); |
727 | } | 675 | } |
728 | if (err) | 676 | if (err) |
729 | goto sigsegv; | 677 | goto sigsegv; |
730 | 678 | ||
731 | /* 3. signal handler back-trampoline and parameters */ | 679 | /* 3. signal handler back-trampoline and parameters */ |
732 | regs->u_regs[UREG_FP] = (unsigned long) sf; | 680 | regs->u_regs[UREG_FP] = (unsigned long) sf; |
733 | regs->u_regs[UREG_I0] = signr; | 681 | regs->u_regs[UREG_I0] = signr; |
734 | regs->u_regs[UREG_I1] = (unsigned long) &sf->info; | 682 | regs->u_regs[UREG_I1] = (unsigned long) &sf->info; |
735 | regs->u_regs[UREG_I2] = (unsigned long) &sf->regs; | 683 | regs->u_regs[UREG_I2] = (unsigned long) &sf->regs; |
736 | 684 | ||
737 | /* 4. signal handler */ | 685 | /* 4. signal handler */ |
738 | regs->tpc = (unsigned long) ka->sa.sa_handler; | 686 | regs->tpc = (unsigned long) ka->sa.sa_handler; |
739 | regs->tnpc = (regs->tpc + 4); | 687 | regs->tnpc = (regs->tpc + 4); |
740 | if (test_thread_flag(TIF_32BIT)) { | 688 | if (test_thread_flag(TIF_32BIT)) { |
741 | regs->tpc &= 0xffffffff; | 689 | regs->tpc &= 0xffffffff; |
742 | regs->tnpc &= 0xffffffff; | 690 | regs->tnpc &= 0xffffffff; |
743 | } | 691 | } |
744 | 692 | ||
745 | /* 5. return to kernel instructions */ | 693 | /* 5. return to kernel instructions */ |
746 | if (ka->ka_restorer) | 694 | if (ka->ka_restorer) |
747 | regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; | 695 | regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; |
748 | else { | 696 | else { |
749 | unsigned long address = ((unsigned long)&(sf->insns[0])); | 697 | unsigned long address = ((unsigned long)&(sf->insns[0])); |
750 | 698 | ||
751 | regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2); | 699 | regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2); |
752 | 700 | ||
753 | /* mov __NR_rt_sigreturn, %g1 */ | 701 | /* mov __NR_rt_sigreturn, %g1 */ |
754 | err |= __put_user(0x82102065, &sf->insns[0]); | 702 | err |= __put_user(0x82102065, &sf->insns[0]); |
755 | 703 | ||
756 | /* t 0x10 */ | 704 | /* t 0x10 */ |
757 | err |= __put_user(0x91d02010, &sf->insns[1]); | 705 | err |= __put_user(0x91d02010, &sf->insns[1]); |
758 | if (err) | 706 | if (err) |
759 | goto sigsegv; | 707 | goto sigsegv; |
760 | 708 | ||
761 | flush_signal_insns(address); | 709 | flush_signal_insns(address); |
762 | } | 710 | } |
763 | return 0; | 711 | return 0; |
764 | 712 | ||
765 | sigill: | 713 | sigill: |
766 | do_exit(SIGILL); | 714 | do_exit(SIGILL); |
767 | return -EINVAL; | 715 | return -EINVAL; |
768 | 716 | ||
769 | sigsegv: | 717 | sigsegv: |
770 | force_sigsegv(signr, current); | 718 | force_sigsegv(signr, current); |
771 | return -EFAULT; | 719 | return -EFAULT; |
772 | } | 720 | } |
773 | 721 | ||
774 | static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka, | 722 | static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka, |
775 | siginfo_t *info, | 723 | siginfo_t *info, |
776 | sigset_t *oldset, struct pt_regs *regs) | 724 | sigset_t *oldset, struct pt_regs *regs) |
777 | { | 725 | { |
778 | int err; | 726 | int err; |
779 | 727 | ||
780 | if (ka->sa.sa_flags & SA_SIGINFO) | 728 | if (ka->sa.sa_flags & SA_SIGINFO) |
781 | err = setup_rt_frame32(ka, regs, signr, oldset, info); | 729 | err = setup_rt_frame32(ka, regs, signr, oldset, info); |
782 | else | 730 | else |
783 | err = setup_frame32(ka, regs, signr, oldset); | 731 | err = setup_frame32(ka, regs, signr, oldset); |
784 | 732 | ||
785 | if (err) | 733 | if (err) |
786 | return; | 734 | return; |
787 | 735 | ||
788 | signal_delivered(signr, info, ka, regs, 0); | 736 | signal_delivered(signr, info, ka, regs, 0); |
789 | } | 737 | } |
790 | 738 | ||
791 | static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs, | 739 | static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs, |
792 | struct sigaction *sa) | 740 | struct sigaction *sa) |
793 | { | 741 | { |
794 | switch (regs->u_regs[UREG_I0]) { | 742 | switch (regs->u_regs[UREG_I0]) { |
795 | case ERESTART_RESTARTBLOCK: | 743 | case ERESTART_RESTARTBLOCK: |
796 | case ERESTARTNOHAND: | 744 | case ERESTARTNOHAND: |
797 | no_system_call_restart: | 745 | no_system_call_restart: |
798 | regs->u_regs[UREG_I0] = EINTR; | 746 | regs->u_regs[UREG_I0] = EINTR; |
799 | regs->tstate |= TSTATE_ICARRY; | 747 | regs->tstate |= TSTATE_ICARRY; |
800 | break; | 748 | break; |
801 | case ERESTARTSYS: | 749 | case ERESTARTSYS: |
802 | if (!(sa->sa_flags & SA_RESTART)) | 750 | if (!(sa->sa_flags & SA_RESTART)) |
803 | goto no_system_call_restart; | 751 | goto no_system_call_restart; |
804 | /* fallthrough */ | 752 | /* fallthrough */ |
805 | case ERESTARTNOINTR: | 753 | case ERESTARTNOINTR: |
806 | regs->u_regs[UREG_I0] = orig_i0; | 754 | regs->u_regs[UREG_I0] = orig_i0; |
807 | regs->tpc -= 4; | 755 | regs->tpc -= 4; |
808 | regs->tnpc -= 4; | 756 | regs->tnpc -= 4; |
809 | } | 757 | } |
810 | } | 758 | } |
811 | 759 | ||
812 | /* Note that 'init' is a special process: it doesn't get signals it doesn't | 760 | /* Note that 'init' is a special process: it doesn't get signals it doesn't |
813 | * want to handle. Thus you cannot kill init even with a SIGKILL even by | 761 | * want to handle. Thus you cannot kill init even with a SIGKILL even by |
814 | * mistake. | 762 | * mistake. |
815 | */ | 763 | */ |
816 | void do_signal32(sigset_t *oldset, struct pt_regs * regs) | 764 | void do_signal32(sigset_t *oldset, struct pt_regs * regs) |
817 | { | 765 | { |
818 | struct k_sigaction ka; | 766 | struct k_sigaction ka; |
819 | unsigned long orig_i0; | 767 | unsigned long orig_i0; |
820 | int restart_syscall; | 768 | int restart_syscall; |
821 | siginfo_t info; | 769 | siginfo_t info; |
822 | int signr; | 770 | int signr; |
823 | 771 | ||
824 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); | 772 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); |
825 | 773 | ||
826 | restart_syscall = 0; | 774 | restart_syscall = 0; |
827 | orig_i0 = 0; | 775 | orig_i0 = 0; |
828 | if (pt_regs_is_syscall(regs) && | 776 | if (pt_regs_is_syscall(regs) && |
829 | (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) { | 777 | (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) { |
830 | restart_syscall = 1; | 778 | restart_syscall = 1; |
831 | orig_i0 = regs->u_regs[UREG_G6]; | 779 | orig_i0 = regs->u_regs[UREG_G6]; |
832 | } | 780 | } |
833 | 781 | ||
834 | if (signr > 0) { | 782 | if (signr > 0) { |
835 | if (restart_syscall) | 783 | if (restart_syscall) |
836 | syscall_restart32(orig_i0, regs, &ka.sa); | 784 | syscall_restart32(orig_i0, regs, &ka.sa); |
837 | handle_signal32(signr, &ka, &info, oldset, regs); | 785 | handle_signal32(signr, &ka, &info, oldset, regs); |
838 | return; | 786 | return; |
839 | } | 787 | } |
840 | if (restart_syscall && | 788 | if (restart_syscall && |
841 | (regs->u_regs[UREG_I0] == ERESTARTNOHAND || | 789 | (regs->u_regs[UREG_I0] == ERESTARTNOHAND || |
842 | regs->u_regs[UREG_I0] == ERESTARTSYS || | 790 | regs->u_regs[UREG_I0] == ERESTARTSYS || |
843 | regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { | 791 | regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { |
844 | /* replay the system call when we are done */ | 792 | /* replay the system call when we are done */ |
845 | regs->u_regs[UREG_I0] = orig_i0; | 793 | regs->u_regs[UREG_I0] = orig_i0; |
846 | regs->tpc -= 4; | 794 | regs->tpc -= 4; |
847 | regs->tnpc -= 4; | 795 | regs->tnpc -= 4; |
848 | pt_regs_clear_syscall(regs); | 796 | pt_regs_clear_syscall(regs); |
849 | } | 797 | } |
850 | if (restart_syscall && | 798 | if (restart_syscall && |
851 | regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { | 799 | regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { |
852 | regs->u_regs[UREG_G1] = __NR_restart_syscall; | 800 | regs->u_regs[UREG_G1] = __NR_restart_syscall; |
853 | regs->tpc -= 4; | 801 | regs->tpc -= 4; |
854 | regs->tnpc -= 4; | 802 | regs->tnpc -= 4; |
855 | pt_regs_clear_syscall(regs); | 803 | pt_regs_clear_syscall(regs); |
856 | } | 804 | } |
857 | 805 | ||
858 | /* If there's no signal to deliver, we just put the saved sigmask | 806 | /* If there's no signal to deliver, we just put the saved sigmask |
859 | * back | 807 | * back |
860 | */ | 808 | */ |
861 | restore_saved_sigmask(); | 809 | restore_saved_sigmask(); |
862 | } | 810 | } |
863 | 811 | ||
864 | struct sigstack32 { | 812 | struct sigstack32 { |
865 | u32 the_stack; | 813 | u32 the_stack; |
866 | int cur_status; | 814 | int cur_status; |
867 | }; | 815 | }; |
868 | 816 | ||
869 | asmlinkage int do_sys32_sigstack(u32 u_ssptr, u32 u_ossptr, unsigned long sp) | 817 | asmlinkage int do_sys32_sigstack(u32 u_ssptr, u32 u_ossptr, unsigned long sp) |
870 | { | 818 | { |
871 | struct sigstack32 __user *ssptr = | 819 | struct sigstack32 __user *ssptr = |
872 | (struct sigstack32 __user *)((unsigned long)(u_ssptr)); | 820 | (struct sigstack32 __user *)((unsigned long)(u_ssptr)); |
873 | struct sigstack32 __user *ossptr = | 821 | struct sigstack32 __user *ossptr = |
874 | (struct sigstack32 __user *)((unsigned long)(u_ossptr)); | 822 | (struct sigstack32 __user *)((unsigned long)(u_ossptr)); |
875 | int ret = -EFAULT; | 823 | int ret = -EFAULT; |
876 | 824 | ||
877 | /* First see if old state is wanted. */ | 825 | /* First see if old state is wanted. */ |
878 | if (ossptr) { | 826 | if (ossptr) { |
879 | if (put_user(current->sas_ss_sp + current->sas_ss_size, | 827 | if (put_user(current->sas_ss_sp + current->sas_ss_size, |
880 | &ossptr->the_stack) || | 828 | &ossptr->the_stack) || |
881 | __put_user(on_sig_stack(sp), &ossptr->cur_status)) | 829 | __put_user(on_sig_stack(sp), &ossptr->cur_status)) |
882 | goto out; | 830 | goto out; |
883 | } | 831 | } |
884 | 832 | ||
885 | /* Now see if we want to update the new state. */ | 833 | /* Now see if we want to update the new state. */ |
886 | if (ssptr) { | 834 | if (ssptr) { |
887 | u32 ss_sp; | 835 | u32 ss_sp; |
888 | 836 | ||
889 | if (get_user(ss_sp, &ssptr->the_stack)) | 837 | if (get_user(ss_sp, &ssptr->the_stack)) |
890 | goto out; | 838 | goto out; |
891 | 839 | ||
892 | /* If the current stack was set with sigaltstack, don't | 840 | /* If the current stack was set with sigaltstack, don't |
893 | * swap stacks while we are on it. | 841 | * swap stacks while we are on it. |
894 | */ | 842 | */ |
895 | ret = -EPERM; | 843 | ret = -EPERM; |
896 | if (current->sas_ss_sp && on_sig_stack(sp)) | 844 | if (current->sas_ss_sp && on_sig_stack(sp)) |
897 | goto out; | 845 | goto out; |
898 | 846 | ||
899 | /* Since we don't know the extent of the stack, and we don't | 847 | /* Since we don't know the extent of the stack, and we don't |
900 | * track onstack-ness, but rather calculate it, we must | 848 | * track onstack-ness, but rather calculate it, we must |
901 | * presume a size. Ho hum this interface is lossy. | 849 | * presume a size. Ho hum this interface is lossy. |
902 | */ | 850 | */ |
903 | current->sas_ss_sp = (unsigned long)ss_sp - SIGSTKSZ; | 851 | current->sas_ss_sp = (unsigned long)ss_sp - SIGSTKSZ; |
904 | current->sas_ss_size = SIGSTKSZ; | 852 | current->sas_ss_size = SIGSTKSZ; |
905 | } | 853 | } |
906 | 854 | ||
907 | ret = 0; | 855 | ret = 0; |
908 | out: | 856 | out: |
909 | return ret; | 857 | return ret; |
910 | } | 858 | } |
911 | 859 | ||
912 | asmlinkage long do_sys32_sigaltstack(u32 ussa, u32 uossa, unsigned long sp) | 860 | asmlinkage long do_sys32_sigaltstack(u32 ussa, u32 uossa, unsigned long sp) |
913 | { | 861 | { |
914 | stack_t uss, uoss; | 862 | stack_t uss, uoss; |
915 | u32 u_ss_sp = 0; | 863 | u32 u_ss_sp = 0; |
916 | int ret; | 864 | int ret; |
917 | mm_segment_t old_fs; | 865 | mm_segment_t old_fs; |
918 | stack_t32 __user *uss32 = compat_ptr(ussa); | 866 | stack_t32 __user *uss32 = compat_ptr(ussa); |
919 | stack_t32 __user *uoss32 = compat_ptr(uossa); | 867 | stack_t32 __user *uoss32 = compat_ptr(uossa); |
920 | 868 | ||
921 | if (ussa && (get_user(u_ss_sp, &uss32->ss_sp) || | 869 | if (ussa && (get_user(u_ss_sp, &uss32->ss_sp) || |
922 | __get_user(uss.ss_flags, &uss32->ss_flags) || | 870 | __get_user(uss.ss_flags, &uss32->ss_flags) || |
923 | __get_user(uss.ss_size, &uss32->ss_size))) | 871 | __get_user(uss.ss_size, &uss32->ss_size))) |
924 | return -EFAULT; | 872 | return -EFAULT; |
925 | uss.ss_sp = compat_ptr(u_ss_sp); | 873 | uss.ss_sp = compat_ptr(u_ss_sp); |
926 | old_fs = get_fs(); | 874 | old_fs = get_fs(); |
927 | set_fs(KERNEL_DS); | 875 | set_fs(KERNEL_DS); |
928 | ret = do_sigaltstack(ussa ? (stack_t __user *) &uss : NULL, | 876 | ret = do_sigaltstack(ussa ? (stack_t __user *) &uss : NULL, |
929 | uossa ? (stack_t __user *) &uoss : NULL, sp); | 877 | uossa ? (stack_t __user *) &uoss : NULL, sp); |
930 | set_fs(old_fs); | 878 | set_fs(old_fs); |
931 | if (!ret && uossa && (put_user(ptr_to_compat(uoss.ss_sp), &uoss32->ss_sp) || | 879 | if (!ret && uossa && (put_user(ptr_to_compat(uoss.ss_sp), &uoss32->ss_sp) || |
932 | __put_user(uoss.ss_flags, &uoss32->ss_flags) || | 880 | __put_user(uoss.ss_flags, &uoss32->ss_flags) || |
933 | __put_user(uoss.ss_size, &uoss32->ss_size))) | 881 | __put_user(uoss.ss_size, &uoss32->ss_size))) |
934 | return -EFAULT; | 882 | return -EFAULT; |
935 | return ret; | 883 | return ret; |
936 | } | 884 | } |
937 | 885 |
arch/tile/include/asm/compat.h
1 | /* | 1 | /* |
2 | * Copyright 2010 Tilera Corporation. All Rights Reserved. | 2 | * Copyright 2010 Tilera Corporation. All Rights Reserved. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or | 4 | * This program is free software; you can redistribute it and/or |
5 | * modify it under the terms of the GNU General Public License | 5 | * modify it under the terms of the GNU General Public License |
6 | * as published by the Free Software Foundation, version 2. | 6 | * as published by the Free Software Foundation, version 2. |
7 | * | 7 | * |
8 | * This program is distributed in the hope that it will be useful, but | 8 | * This program is distributed in the hope that it will be useful, but |
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of | 9 | * WITHOUT ANY WARRANTY; without even the implied warranty of |
10 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or | 10 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or |
11 | * NON INFRINGEMENT. See the GNU General Public License for | 11 | * NON INFRINGEMENT. See the GNU General Public License for |
12 | * more details. | 12 | * more details. |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #ifndef _ASM_TILE_COMPAT_H | 15 | #ifndef _ASM_TILE_COMPAT_H |
16 | #define _ASM_TILE_COMPAT_H | 16 | #define _ASM_TILE_COMPAT_H |
17 | 17 | ||
18 | /* | 18 | /* |
19 | * Architecture specific compatibility types | 19 | * Architecture specific compatibility types |
20 | */ | 20 | */ |
21 | #include <linux/types.h> | 21 | #include <linux/types.h> |
22 | #include <linux/sched.h> | 22 | #include <linux/sched.h> |
23 | 23 | ||
24 | #define COMPAT_USER_HZ 100 | 24 | #define COMPAT_USER_HZ 100 |
25 | 25 | ||
26 | /* "long" and pointer-based types are different. */ | 26 | /* "long" and pointer-based types are different. */ |
27 | typedef s32 compat_long_t; | 27 | typedef s32 compat_long_t; |
28 | typedef u32 compat_ulong_t; | 28 | typedef u32 compat_ulong_t; |
29 | typedef u32 compat_size_t; | 29 | typedef u32 compat_size_t; |
30 | typedef s32 compat_ssize_t; | 30 | typedef s32 compat_ssize_t; |
31 | typedef s32 compat_off_t; | 31 | typedef s32 compat_off_t; |
32 | typedef s32 compat_time_t; | 32 | typedef s32 compat_time_t; |
33 | typedef s32 compat_clock_t; | 33 | typedef s32 compat_clock_t; |
34 | typedef u32 compat_ino_t; | 34 | typedef u32 compat_ino_t; |
35 | typedef u32 compat_caddr_t; | 35 | typedef u32 compat_caddr_t; |
36 | typedef u32 compat_uptr_t; | 36 | typedef u32 compat_uptr_t; |
37 | 37 | ||
38 | /* Many types are "int" or otherwise the same. */ | 38 | /* Many types are "int" or otherwise the same. */ |
39 | typedef __kernel_pid_t compat_pid_t; | 39 | typedef __kernel_pid_t compat_pid_t; |
40 | typedef __kernel_uid_t __compat_uid_t; | 40 | typedef __kernel_uid_t __compat_uid_t; |
41 | typedef __kernel_gid_t __compat_gid_t; | 41 | typedef __kernel_gid_t __compat_gid_t; |
42 | typedef __kernel_uid32_t __compat_uid32_t; | 42 | typedef __kernel_uid32_t __compat_uid32_t; |
43 | typedef __kernel_uid32_t __compat_gid32_t; | 43 | typedef __kernel_uid32_t __compat_gid32_t; |
44 | typedef __kernel_mode_t compat_mode_t; | 44 | typedef __kernel_mode_t compat_mode_t; |
45 | typedef __kernel_dev_t compat_dev_t; | 45 | typedef __kernel_dev_t compat_dev_t; |
46 | typedef __kernel_loff_t compat_loff_t; | 46 | typedef __kernel_loff_t compat_loff_t; |
47 | typedef __kernel_ipc_pid_t compat_ipc_pid_t; | 47 | typedef __kernel_ipc_pid_t compat_ipc_pid_t; |
48 | typedef __kernel_daddr_t compat_daddr_t; | 48 | typedef __kernel_daddr_t compat_daddr_t; |
49 | typedef __kernel_fsid_t compat_fsid_t; | 49 | typedef __kernel_fsid_t compat_fsid_t; |
50 | typedef __kernel_timer_t compat_timer_t; | 50 | typedef __kernel_timer_t compat_timer_t; |
51 | typedef __kernel_key_t compat_key_t; | 51 | typedef __kernel_key_t compat_key_t; |
52 | typedef int compat_int_t; | 52 | typedef int compat_int_t; |
53 | typedef s64 compat_s64; | 53 | typedef s64 compat_s64; |
54 | typedef uint compat_uint_t; | 54 | typedef uint compat_uint_t; |
55 | typedef u64 compat_u64; | 55 | typedef u64 compat_u64; |
56 | 56 | ||
57 | /* We use the same register dump format in 32-bit images. */ | 57 | /* We use the same register dump format in 32-bit images. */ |
58 | typedef unsigned long compat_elf_greg_t; | 58 | typedef unsigned long compat_elf_greg_t; |
59 | #define COMPAT_ELF_NGREG (sizeof(struct pt_regs) / sizeof(compat_elf_greg_t)) | 59 | #define COMPAT_ELF_NGREG (sizeof(struct pt_regs) / sizeof(compat_elf_greg_t)) |
60 | typedef compat_elf_greg_t compat_elf_gregset_t[COMPAT_ELF_NGREG]; | 60 | typedef compat_elf_greg_t compat_elf_gregset_t[COMPAT_ELF_NGREG]; |
61 | 61 | ||
62 | struct compat_timespec { | 62 | struct compat_timespec { |
63 | compat_time_t tv_sec; | 63 | compat_time_t tv_sec; |
64 | s32 tv_nsec; | 64 | s32 tv_nsec; |
65 | }; | 65 | }; |
66 | 66 | ||
67 | struct compat_timeval { | 67 | struct compat_timeval { |
68 | compat_time_t tv_sec; | 68 | compat_time_t tv_sec; |
69 | s32 tv_usec; | 69 | s32 tv_usec; |
70 | }; | 70 | }; |
71 | 71 | ||
72 | #define compat_stat stat | 72 | #define compat_stat stat |
73 | #define compat_statfs statfs | 73 | #define compat_statfs statfs |
74 | 74 | ||
75 | struct compat_sysctl { | 75 | struct compat_sysctl { |
76 | unsigned int name; | 76 | unsigned int name; |
77 | int nlen; | 77 | int nlen; |
78 | unsigned int oldval; | 78 | unsigned int oldval; |
79 | unsigned int oldlenp; | 79 | unsigned int oldlenp; |
80 | unsigned int newval; | 80 | unsigned int newval; |
81 | unsigned int newlen; | 81 | unsigned int newlen; |
82 | unsigned int __unused[4]; | 82 | unsigned int __unused[4]; |
83 | }; | 83 | }; |
84 | 84 | ||
85 | 85 | ||
86 | struct compat_flock { | 86 | struct compat_flock { |
87 | short l_type; | 87 | short l_type; |
88 | short l_whence; | 88 | short l_whence; |
89 | compat_off_t l_start; | 89 | compat_off_t l_start; |
90 | compat_off_t l_len; | 90 | compat_off_t l_len; |
91 | compat_pid_t l_pid; | 91 | compat_pid_t l_pid; |
92 | }; | 92 | }; |
93 | 93 | ||
94 | #define F_GETLK64 12 /* using 'struct flock64' */ | 94 | #define F_GETLK64 12 /* using 'struct flock64' */ |
95 | #define F_SETLK64 13 | 95 | #define F_SETLK64 13 |
96 | #define F_SETLKW64 14 | 96 | #define F_SETLKW64 14 |
97 | 97 | ||
98 | struct compat_flock64 { | 98 | struct compat_flock64 { |
99 | short l_type; | 99 | short l_type; |
100 | short l_whence; | 100 | short l_whence; |
101 | compat_loff_t l_start; | 101 | compat_loff_t l_start; |
102 | compat_loff_t l_len; | 102 | compat_loff_t l_len; |
103 | compat_pid_t l_pid; | 103 | compat_pid_t l_pid; |
104 | }; | 104 | }; |
105 | 105 | ||
106 | #define COMPAT_RLIM_INFINITY 0xffffffff | 106 | #define COMPAT_RLIM_INFINITY 0xffffffff |
107 | 107 | ||
108 | #define _COMPAT_NSIG 64 | 108 | #define _COMPAT_NSIG 64 |
109 | #define _COMPAT_NSIG_BPW 32 | 109 | #define _COMPAT_NSIG_BPW 32 |
110 | 110 | ||
111 | typedef u32 compat_sigset_word; | 111 | typedef u32 compat_sigset_word; |
112 | 112 | ||
113 | typedef union compat_sigval { | ||
114 | compat_int_t sival_int; | ||
115 | compat_uptr_t sival_ptr; | ||
116 | } compat_sigval_t; | ||
117 | |||
118 | #define COMPAT_SI_PAD_SIZE (128/sizeof(int) - 3) | ||
119 | |||
120 | typedef struct compat_siginfo { | ||
121 | int si_signo; | ||
122 | int si_errno; | ||
123 | int si_code; | ||
124 | |||
125 | union { | ||
126 | int _pad[COMPAT_SI_PAD_SIZE]; | ||
127 | |||
128 | /* kill() */ | ||
129 | struct { | ||
130 | unsigned int _pid; /* sender's pid */ | ||
131 | unsigned int _uid; /* sender's uid */ | ||
132 | } _kill; | ||
133 | |||
134 | /* POSIX.1b timers */ | ||
135 | struct { | ||
136 | compat_timer_t _tid; /* timer id */ | ||
137 | int _overrun; /* overrun count */ | ||
138 | compat_sigval_t _sigval; /* same as below */ | ||
139 | int _sys_private; /* not to be passed to user */ | ||
140 | int _overrun_incr; /* amount to add to overrun */ | ||
141 | } _timer; | ||
142 | |||
143 | /* POSIX.1b signals */ | ||
144 | struct { | ||
145 | unsigned int _pid; /* sender's pid */ | ||
146 | unsigned int _uid; /* sender's uid */ | ||
147 | compat_sigval_t _sigval; | ||
148 | } _rt; | ||
149 | |||
150 | /* SIGCHLD */ | ||
151 | struct { | ||
152 | unsigned int _pid; /* which child */ | ||
153 | unsigned int _uid; /* sender's uid */ | ||
154 | int _status; /* exit code */ | ||
155 | compat_clock_t _utime; | ||
156 | compat_clock_t _stime; | ||
157 | } _sigchld; | ||
158 | |||
159 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ | ||
160 | struct { | ||
161 | unsigned int _addr; /* faulting insn/memory ref. */ | ||
162 | #ifdef __ARCH_SI_TRAPNO | ||
163 | int _trapno; /* TRAP # which caused the signal */ | ||
164 | #endif | ||
165 | } _sigfault; | ||
166 | |||
167 | /* SIGPOLL */ | ||
168 | struct { | ||
169 | int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ | ||
170 | int _fd; | ||
171 | } _sigpoll; | ||
172 | } _sifields; | ||
173 | } compat_siginfo_t; | ||
174 | |||
113 | #define COMPAT_OFF_T_MAX 0x7fffffff | 175 | #define COMPAT_OFF_T_MAX 0x7fffffff |
114 | #define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL | 176 | #define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL |
115 | 177 | ||
116 | struct compat_ipc64_perm { | 178 | struct compat_ipc64_perm { |
117 | compat_key_t key; | 179 | compat_key_t key; |
118 | __compat_uid32_t uid; | 180 | __compat_uid32_t uid; |
119 | __compat_gid32_t gid; | 181 | __compat_gid32_t gid; |
120 | __compat_uid32_t cuid; | 182 | __compat_uid32_t cuid; |
121 | __compat_gid32_t cgid; | 183 | __compat_gid32_t cgid; |
122 | unsigned short mode; | 184 | unsigned short mode; |
123 | unsigned short __pad1; | 185 | unsigned short __pad1; |
124 | unsigned short seq; | 186 | unsigned short seq; |
125 | unsigned short __pad2; | 187 | unsigned short __pad2; |
126 | compat_ulong_t unused1; | 188 | compat_ulong_t unused1; |
127 | compat_ulong_t unused2; | 189 | compat_ulong_t unused2; |
128 | }; | 190 | }; |
129 | 191 | ||
130 | struct compat_semid64_ds { | 192 | struct compat_semid64_ds { |
131 | struct compat_ipc64_perm sem_perm; | 193 | struct compat_ipc64_perm sem_perm; |
132 | compat_time_t sem_otime; | 194 | compat_time_t sem_otime; |
133 | compat_ulong_t __unused1; | 195 | compat_ulong_t __unused1; |
134 | compat_time_t sem_ctime; | 196 | compat_time_t sem_ctime; |
135 | compat_ulong_t __unused2; | 197 | compat_ulong_t __unused2; |
136 | compat_ulong_t sem_nsems; | 198 | compat_ulong_t sem_nsems; |
137 | compat_ulong_t __unused3; | 199 | compat_ulong_t __unused3; |
138 | compat_ulong_t __unused4; | 200 | compat_ulong_t __unused4; |
139 | }; | 201 | }; |
140 | 202 | ||
141 | struct compat_msqid64_ds { | 203 | struct compat_msqid64_ds { |
142 | struct compat_ipc64_perm msg_perm; | 204 | struct compat_ipc64_perm msg_perm; |
143 | compat_time_t msg_stime; | 205 | compat_time_t msg_stime; |
144 | compat_ulong_t __unused1; | 206 | compat_ulong_t __unused1; |
145 | compat_time_t msg_rtime; | 207 | compat_time_t msg_rtime; |
146 | compat_ulong_t __unused2; | 208 | compat_ulong_t __unused2; |
147 | compat_time_t msg_ctime; | 209 | compat_time_t msg_ctime; |
148 | compat_ulong_t __unused3; | 210 | compat_ulong_t __unused3; |
149 | compat_ulong_t msg_cbytes; | 211 | compat_ulong_t msg_cbytes; |
150 | compat_ulong_t msg_qnum; | 212 | compat_ulong_t msg_qnum; |
151 | compat_ulong_t msg_qbytes; | 213 | compat_ulong_t msg_qbytes; |
152 | compat_pid_t msg_lspid; | 214 | compat_pid_t msg_lspid; |
153 | compat_pid_t msg_lrpid; | 215 | compat_pid_t msg_lrpid; |
154 | compat_ulong_t __unused4; | 216 | compat_ulong_t __unused4; |
155 | compat_ulong_t __unused5; | 217 | compat_ulong_t __unused5; |
156 | }; | 218 | }; |
157 | 219 | ||
158 | struct compat_shmid64_ds { | 220 | struct compat_shmid64_ds { |
159 | struct compat_ipc64_perm shm_perm; | 221 | struct compat_ipc64_perm shm_perm; |
160 | compat_size_t shm_segsz; | 222 | compat_size_t shm_segsz; |
161 | compat_time_t shm_atime; | 223 | compat_time_t shm_atime; |
162 | compat_ulong_t __unused1; | 224 | compat_ulong_t __unused1; |
163 | compat_time_t shm_dtime; | 225 | compat_time_t shm_dtime; |
164 | compat_ulong_t __unused2; | 226 | compat_ulong_t __unused2; |
165 | compat_time_t shm_ctime; | 227 | compat_time_t shm_ctime; |
166 | compat_ulong_t __unused3; | 228 | compat_ulong_t __unused3; |
167 | compat_pid_t shm_cpid; | 229 | compat_pid_t shm_cpid; |
168 | compat_pid_t shm_lpid; | 230 | compat_pid_t shm_lpid; |
169 | compat_ulong_t shm_nattch; | 231 | compat_ulong_t shm_nattch; |
170 | compat_ulong_t __unused4; | 232 | compat_ulong_t __unused4; |
171 | compat_ulong_t __unused5; | 233 | compat_ulong_t __unused5; |
172 | }; | 234 | }; |
173 | 235 | ||
174 | /* | 236 | /* |
175 | * A pointer passed in from user mode. This should not | 237 | * A pointer passed in from user mode. This should not |
176 | * be used for syscall parameters, just declare them | 238 | * be used for syscall parameters, just declare them |
177 | * as pointers because the syscall entry code will have | 239 | * as pointers because the syscall entry code will have |
178 | * appropriately converted them already. | 240 | * appropriately converted them already. |
179 | */ | 241 | */ |
180 | 242 | ||
181 | static inline void __user *compat_ptr(compat_uptr_t uptr) | 243 | static inline void __user *compat_ptr(compat_uptr_t uptr) |
182 | { | 244 | { |
183 | return (void __user *)(long)(s32)uptr; | 245 | return (void __user *)(long)(s32)uptr; |
184 | } | 246 | } |
185 | 247 | ||
186 | static inline compat_uptr_t ptr_to_compat(void __user *uptr) | 248 | static inline compat_uptr_t ptr_to_compat(void __user *uptr) |
187 | { | 249 | { |
188 | return (u32)(unsigned long)uptr; | 250 | return (u32)(unsigned long)uptr; |
189 | } | 251 | } |
190 | 252 | ||
191 | /* Sign-extend when storing a kernel pointer to a user's ptregs. */ | 253 | /* Sign-extend when storing a kernel pointer to a user's ptregs. */ |
192 | static inline unsigned long ptr_to_compat_reg(void __user *uptr) | 254 | static inline unsigned long ptr_to_compat_reg(void __user *uptr) |
193 | { | 255 | { |
194 | return (long)(int)(long __force)uptr; | 256 | return (long)(int)(long __force)uptr; |
195 | } | 257 | } |
196 | 258 | ||
197 | static inline void __user *arch_compat_alloc_user_space(long len) | 259 | static inline void __user *arch_compat_alloc_user_space(long len) |
198 | { | 260 | { |
199 | struct pt_regs *regs = task_pt_regs(current); | 261 | struct pt_regs *regs = task_pt_regs(current); |
200 | return (void __user *)regs->sp - len; | 262 | return (void __user *)regs->sp - len; |
201 | } | 263 | } |
202 | 264 | ||
203 | static inline int is_compat_task(void) | 265 | static inline int is_compat_task(void) |
204 | { | 266 | { |
205 | return current_thread_info()->status & TS_COMPAT; | 267 | return current_thread_info()->status & TS_COMPAT; |
206 | } | 268 | } |
207 | 269 | ||
208 | extern int compat_setup_rt_frame(int sig, struct k_sigaction *ka, | 270 | extern int compat_setup_rt_frame(int sig, struct k_sigaction *ka, |
209 | siginfo_t *info, sigset_t *set, | 271 | siginfo_t *info, sigset_t *set, |
210 | struct pt_regs *regs); | 272 | struct pt_regs *regs); |
211 | 273 | ||
212 | /* Compat syscalls. */ | 274 | /* Compat syscalls. */ |
213 | struct compat_sigaction; | 275 | struct compat_sigaction; |
214 | struct compat_siginfo; | 276 | struct compat_siginfo; |
215 | struct compat_sigaltstack; | 277 | struct compat_sigaltstack; |
216 | long compat_sys_execve(const char __user *path, | 278 | long compat_sys_execve(const char __user *path, |
217 | compat_uptr_t __user *argv, | 279 | compat_uptr_t __user *argv, |
218 | compat_uptr_t __user *envp, struct pt_regs *); | 280 | compat_uptr_t __user *envp, struct pt_regs *); |
219 | long compat_sys_rt_sigaction(int sig, struct compat_sigaction __user *act, | 281 | long compat_sys_rt_sigaction(int sig, struct compat_sigaction __user *act, |
220 | struct compat_sigaction __user *oact, | 282 | struct compat_sigaction __user *oact, |
221 | size_t sigsetsize); | 283 | size_t sigsetsize); |
222 | long compat_sys_rt_sigqueueinfo(int pid, int sig, | 284 | long compat_sys_rt_sigqueueinfo(int pid, int sig, |
223 | struct compat_siginfo __user *uinfo); | 285 | struct compat_siginfo __user *uinfo); |
224 | long compat_sys_rt_sigreturn(struct pt_regs *); | 286 | long compat_sys_rt_sigreturn(struct pt_regs *); |
225 | long compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr, | 287 | long compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr, |
226 | struct compat_sigaltstack __user *uoss_ptr, | 288 | struct compat_sigaltstack __user *uoss_ptr, |
227 | struct pt_regs *); | 289 | struct pt_regs *); |
228 | long compat_sys_truncate64(char __user *filename, u32 dummy, u32 low, u32 high); | 290 | long compat_sys_truncate64(char __user *filename, u32 dummy, u32 low, u32 high); |
229 | long compat_sys_ftruncate64(unsigned int fd, u32 dummy, u32 low, u32 high); | 291 | long compat_sys_ftruncate64(unsigned int fd, u32 dummy, u32 low, u32 high); |
230 | long compat_sys_pread64(unsigned int fd, char __user *ubuf, size_t count, | 292 | long compat_sys_pread64(unsigned int fd, char __user *ubuf, size_t count, |
231 | u32 dummy, u32 low, u32 high); | 293 | u32 dummy, u32 low, u32 high); |
232 | long compat_sys_pwrite64(unsigned int fd, char __user *ubuf, size_t count, | 294 | long compat_sys_pwrite64(unsigned int fd, char __user *ubuf, size_t count, |
233 | u32 dummy, u32 low, u32 high); | 295 | u32 dummy, u32 low, u32 high); |
234 | long compat_sys_lookup_dcookie(u32 low, u32 high, char __user *buf, size_t len); | 296 | long compat_sys_lookup_dcookie(u32 low, u32 high, char __user *buf, size_t len); |
235 | long compat_sys_sync_file_range2(int fd, unsigned int flags, | 297 | long compat_sys_sync_file_range2(int fd, unsigned int flags, |
236 | u32 offset_lo, u32 offset_hi, | 298 | u32 offset_lo, u32 offset_hi, |
237 | u32 nbytes_lo, u32 nbytes_hi); | 299 | u32 nbytes_lo, u32 nbytes_hi); |
238 | long compat_sys_fallocate(int fd, int mode, | 300 | long compat_sys_fallocate(int fd, int mode, |
239 | u32 offset_lo, u32 offset_hi, | 301 | u32 offset_lo, u32 offset_hi, |
240 | u32 len_lo, u32 len_hi); | 302 | u32 len_lo, u32 len_hi); |
241 | long compat_sys_sched_rr_get_interval(compat_pid_t pid, | 303 | long compat_sys_sched_rr_get_interval(compat_pid_t pid, |
242 | struct compat_timespec __user *interval); | 304 | struct compat_timespec __user *interval); |
243 | 305 | ||
244 | /* These are the intvec_64.S trampolines. */ | 306 | /* These are the intvec_64.S trampolines. */ |
245 | long _compat_sys_execve(const char __user *path, | 307 | long _compat_sys_execve(const char __user *path, |
246 | const compat_uptr_t __user *argv, | 308 | const compat_uptr_t __user *argv, |
247 | const compat_uptr_t __user *envp); | 309 | const compat_uptr_t __user *envp); |
248 | long _compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr, | 310 | long _compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr, |
249 | struct compat_sigaltstack __user *uoss_ptr); | 311 | struct compat_sigaltstack __user *uoss_ptr); |
250 | long _compat_sys_rt_sigreturn(void); | 312 | long _compat_sys_rt_sigreturn(void); |
251 | 313 | ||
252 | #endif /* _ASM_TILE_COMPAT_H */ | 314 | #endif /* _ASM_TILE_COMPAT_H */ |
253 | 315 |
arch/tile/kernel/compat_signal.c
1 | /* | 1 | /* |
2 | * Copyright 2010 Tilera Corporation. All Rights Reserved. | 2 | * Copyright 2010 Tilera Corporation. All Rights Reserved. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or | 4 | * This program is free software; you can redistribute it and/or |
5 | * modify it under the terms of the GNU General Public License | 5 | * modify it under the terms of the GNU General Public License |
6 | * as published by the Free Software Foundation, version 2. | 6 | * as published by the Free Software Foundation, version 2. |
7 | * | 7 | * |
8 | * This program is distributed in the hope that it will be useful, but | 8 | * This program is distributed in the hope that it will be useful, but |
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of | 9 | * WITHOUT ANY WARRANTY; without even the implied warranty of |
10 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or | 10 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or |
11 | * NON INFRINGEMENT. See the GNU General Public License for | 11 | * NON INFRINGEMENT. See the GNU General Public License for |
12 | * more details. | 12 | * more details. |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/sched.h> | 15 | #include <linux/sched.h> |
16 | #include <linux/mm.h> | 16 | #include <linux/mm.h> |
17 | #include <linux/smp.h> | 17 | #include <linux/smp.h> |
18 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
19 | #include <linux/signal.h> | 19 | #include <linux/signal.h> |
20 | #include <linux/errno.h> | 20 | #include <linux/errno.h> |
21 | #include <linux/wait.h> | 21 | #include <linux/wait.h> |
22 | #include <linux/unistd.h> | 22 | #include <linux/unistd.h> |
23 | #include <linux/stddef.h> | 23 | #include <linux/stddef.h> |
24 | #include <linux/personality.h> | 24 | #include <linux/personality.h> |
25 | #include <linux/suspend.h> | 25 | #include <linux/suspend.h> |
26 | #include <linux/ptrace.h> | 26 | #include <linux/ptrace.h> |
27 | #include <linux/elf.h> | 27 | #include <linux/elf.h> |
28 | #include <linux/compat.h> | 28 | #include <linux/compat.h> |
29 | #include <linux/syscalls.h> | 29 | #include <linux/syscalls.h> |
30 | #include <linux/uaccess.h> | 30 | #include <linux/uaccess.h> |
31 | #include <asm/processor.h> | 31 | #include <asm/processor.h> |
32 | #include <asm/ucontext.h> | 32 | #include <asm/ucontext.h> |
33 | #include <asm/sigframe.h> | 33 | #include <asm/sigframe.h> |
34 | #include <asm/syscalls.h> | 34 | #include <asm/syscalls.h> |
35 | #include <arch/interrupts.h> | 35 | #include <arch/interrupts.h> |
36 | 36 | ||
37 | struct compat_sigaction { | 37 | struct compat_sigaction { |
38 | compat_uptr_t sa_handler; | 38 | compat_uptr_t sa_handler; |
39 | compat_ulong_t sa_flags; | 39 | compat_ulong_t sa_flags; |
40 | compat_uptr_t sa_restorer; | 40 | compat_uptr_t sa_restorer; |
41 | sigset_t sa_mask __packed; | 41 | sigset_t sa_mask __packed; |
42 | }; | 42 | }; |
43 | 43 | ||
44 | struct compat_sigaltstack { | 44 | struct compat_sigaltstack { |
45 | compat_uptr_t ss_sp; | 45 | compat_uptr_t ss_sp; |
46 | int ss_flags; | 46 | int ss_flags; |
47 | compat_size_t ss_size; | 47 | compat_size_t ss_size; |
48 | }; | 48 | }; |
49 | 49 | ||
50 | struct compat_ucontext { | 50 | struct compat_ucontext { |
51 | compat_ulong_t uc_flags; | 51 | compat_ulong_t uc_flags; |
52 | compat_uptr_t uc_link; | 52 | compat_uptr_t uc_link; |
53 | struct compat_sigaltstack uc_stack; | 53 | struct compat_sigaltstack uc_stack; |
54 | struct sigcontext uc_mcontext; | 54 | struct sigcontext uc_mcontext; |
55 | sigset_t uc_sigmask; /* mask last for extensibility */ | 55 | sigset_t uc_sigmask; /* mask last for extensibility */ |
56 | }; | 56 | }; |
57 | 57 | ||
58 | #define COMPAT_SI_PAD_SIZE ((SI_MAX_SIZE - 3 * sizeof(int)) / sizeof(int)) | ||
59 | |||
60 | struct compat_siginfo { | ||
61 | int si_signo; | ||
62 | int si_errno; | ||
63 | int si_code; | ||
64 | |||
65 | union { | ||
66 | int _pad[COMPAT_SI_PAD_SIZE]; | ||
67 | |||
68 | /* kill() */ | ||
69 | struct { | ||
70 | unsigned int _pid; /* sender's pid */ | ||
71 | unsigned int _uid; /* sender's uid */ | ||
72 | } _kill; | ||
73 | |||
74 | /* POSIX.1b timers */ | ||
75 | struct { | ||
76 | compat_timer_t _tid; /* timer id */ | ||
77 | int _overrun; /* overrun count */ | ||
78 | compat_sigval_t _sigval; /* same as below */ | ||
79 | int _sys_private; /* not to be passed to user */ | ||
80 | int _overrun_incr; /* amount to add to overrun */ | ||
81 | } _timer; | ||
82 | |||
83 | /* POSIX.1b signals */ | ||
84 | struct { | ||
85 | unsigned int _pid; /* sender's pid */ | ||
86 | unsigned int _uid; /* sender's uid */ | ||
87 | compat_sigval_t _sigval; | ||
88 | } _rt; | ||
89 | |||
90 | /* SIGCHLD */ | ||
91 | struct { | ||
92 | unsigned int _pid; /* which child */ | ||
93 | unsigned int _uid; /* sender's uid */ | ||
94 | int _status; /* exit code */ | ||
95 | compat_clock_t _utime; | ||
96 | compat_clock_t _stime; | ||
97 | } _sigchld; | ||
98 | |||
99 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ | ||
100 | struct { | ||
101 | unsigned int _addr; /* faulting insn/memory ref. */ | ||
102 | #ifdef __ARCH_SI_TRAPNO | ||
103 | int _trapno; /* TRAP # which caused the signal */ | ||
104 | #endif | ||
105 | } _sigfault; | ||
106 | |||
107 | /* SIGPOLL */ | ||
108 | struct { | ||
109 | int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ | ||
110 | int _fd; | ||
111 | } _sigpoll; | ||
112 | } _sifields; | ||
113 | }; | ||
114 | |||
115 | struct compat_rt_sigframe { | 58 | struct compat_rt_sigframe { |
116 | unsigned char save_area[C_ABI_SAVE_AREA_SIZE]; /* caller save area */ | 59 | unsigned char save_area[C_ABI_SAVE_AREA_SIZE]; /* caller save area */ |
117 | struct compat_siginfo info; | 60 | struct compat_siginfo info; |
118 | struct compat_ucontext uc; | 61 | struct compat_ucontext uc; |
119 | }; | 62 | }; |
120 | 63 | ||
121 | long compat_sys_rt_sigaction(int sig, struct compat_sigaction __user *act, | 64 | long compat_sys_rt_sigaction(int sig, struct compat_sigaction __user *act, |
122 | struct compat_sigaction __user *oact, | 65 | struct compat_sigaction __user *oact, |
123 | size_t sigsetsize) | 66 | size_t sigsetsize) |
124 | { | 67 | { |
125 | struct k_sigaction new_sa, old_sa; | 68 | struct k_sigaction new_sa, old_sa; |
126 | int ret = -EINVAL; | 69 | int ret = -EINVAL; |
127 | 70 | ||
128 | /* XXX: Don't preclude handling different sized sigset_t's. */ | 71 | /* XXX: Don't preclude handling different sized sigset_t's. */ |
129 | if (sigsetsize != sizeof(sigset_t)) | 72 | if (sigsetsize != sizeof(sigset_t)) |
130 | goto out; | 73 | goto out; |
131 | 74 | ||
132 | if (act) { | 75 | if (act) { |
133 | compat_uptr_t handler, restorer; | 76 | compat_uptr_t handler, restorer; |
134 | 77 | ||
135 | if (!access_ok(VERIFY_READ, act, sizeof(*act)) || | 78 | if (!access_ok(VERIFY_READ, act, sizeof(*act)) || |
136 | __get_user(handler, &act->sa_handler) || | 79 | __get_user(handler, &act->sa_handler) || |
137 | __get_user(new_sa.sa.sa_flags, &act->sa_flags) || | 80 | __get_user(new_sa.sa.sa_flags, &act->sa_flags) || |
138 | __get_user(restorer, &act->sa_restorer) || | 81 | __get_user(restorer, &act->sa_restorer) || |
139 | __copy_from_user(&new_sa.sa.sa_mask, &act->sa_mask, | 82 | __copy_from_user(&new_sa.sa.sa_mask, &act->sa_mask, |
140 | sizeof(sigset_t))) | 83 | sizeof(sigset_t))) |
141 | return -EFAULT; | 84 | return -EFAULT; |
142 | new_sa.sa.sa_handler = compat_ptr(handler); | 85 | new_sa.sa.sa_handler = compat_ptr(handler); |
143 | new_sa.sa.sa_restorer = compat_ptr(restorer); | 86 | new_sa.sa.sa_restorer = compat_ptr(restorer); |
144 | } | 87 | } |
145 | 88 | ||
146 | ret = do_sigaction(sig, act ? &new_sa : NULL, oact ? &old_sa : NULL); | 89 | ret = do_sigaction(sig, act ? &new_sa : NULL, oact ? &old_sa : NULL); |
147 | 90 | ||
148 | if (!ret && oact) { | 91 | if (!ret && oact) { |
149 | if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || | 92 | if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || |
150 | __put_user(ptr_to_compat(old_sa.sa.sa_handler), | 93 | __put_user(ptr_to_compat(old_sa.sa.sa_handler), |
151 | &oact->sa_handler) || | 94 | &oact->sa_handler) || |
152 | __put_user(ptr_to_compat(old_sa.sa.sa_restorer), | 95 | __put_user(ptr_to_compat(old_sa.sa.sa_restorer), |
153 | &oact->sa_restorer) || | 96 | &oact->sa_restorer) || |
154 | __put_user(old_sa.sa.sa_flags, &oact->sa_flags) || | 97 | __put_user(old_sa.sa.sa_flags, &oact->sa_flags) || |
155 | __copy_to_user(&oact->sa_mask, &old_sa.sa.sa_mask, | 98 | __copy_to_user(&oact->sa_mask, &old_sa.sa.sa_mask, |
156 | sizeof(sigset_t))) | 99 | sizeof(sigset_t))) |
157 | return -EFAULT; | 100 | return -EFAULT; |
158 | } | 101 | } |
159 | out: | 102 | out: |
160 | return ret; | 103 | return ret; |
161 | } | 104 | } |
162 | 105 | ||
163 | long compat_sys_rt_sigqueueinfo(int pid, int sig, | 106 | long compat_sys_rt_sigqueueinfo(int pid, int sig, |
164 | struct compat_siginfo __user *uinfo) | 107 | struct compat_siginfo __user *uinfo) |
165 | { | 108 | { |
166 | siginfo_t info; | 109 | siginfo_t info; |
167 | int ret; | 110 | int ret; |
168 | mm_segment_t old_fs = get_fs(); | 111 | mm_segment_t old_fs = get_fs(); |
169 | 112 | ||
170 | if (copy_siginfo_from_user32(&info, uinfo)) | 113 | if (copy_siginfo_from_user32(&info, uinfo)) |
171 | return -EFAULT; | 114 | return -EFAULT; |
172 | set_fs(KERNEL_DS); | 115 | set_fs(KERNEL_DS); |
173 | ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __force __user *)&info); | 116 | ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __force __user *)&info); |
174 | set_fs(old_fs); | 117 | set_fs(old_fs); |
175 | return ret; | 118 | return ret; |
176 | } | 119 | } |
177 | 120 | ||
178 | int copy_siginfo_to_user32(struct compat_siginfo __user *to, siginfo_t *from) | 121 | int copy_siginfo_to_user32(struct compat_siginfo __user *to, siginfo_t *from) |
179 | { | 122 | { |
180 | int err; | 123 | int err; |
181 | 124 | ||
182 | if (!access_ok(VERIFY_WRITE, to, sizeof(struct compat_siginfo))) | 125 | if (!access_ok(VERIFY_WRITE, to, sizeof(struct compat_siginfo))) |
183 | return -EFAULT; | 126 | return -EFAULT; |
184 | 127 | ||
185 | /* If you change siginfo_t structure, please make sure that | 128 | /* If you change siginfo_t structure, please make sure that |
186 | this code is fixed accordingly. | 129 | this code is fixed accordingly. |
187 | It should never copy any pad contained in the structure | 130 | It should never copy any pad contained in the structure |
188 | to avoid security leaks, but must copy the generic | 131 | to avoid security leaks, but must copy the generic |
189 | 3 ints plus the relevant union member. */ | 132 | 3 ints plus the relevant union member. */ |
190 | err = __put_user(from->si_signo, &to->si_signo); | 133 | err = __put_user(from->si_signo, &to->si_signo); |
191 | err |= __put_user(from->si_errno, &to->si_errno); | 134 | err |= __put_user(from->si_errno, &to->si_errno); |
192 | err |= __put_user((short)from->si_code, &to->si_code); | 135 | err |= __put_user((short)from->si_code, &to->si_code); |
193 | 136 | ||
194 | if (from->si_code < 0) { | 137 | if (from->si_code < 0) { |
195 | err |= __put_user(from->si_pid, &to->si_pid); | 138 | err |= __put_user(from->si_pid, &to->si_pid); |
196 | err |= __put_user(from->si_uid, &to->si_uid); | 139 | err |= __put_user(from->si_uid, &to->si_uid); |
197 | err |= __put_user(ptr_to_compat(from->si_ptr), &to->si_ptr); | 140 | err |= __put_user(ptr_to_compat(from->si_ptr), &to->si_ptr); |
198 | } else { | 141 | } else { |
199 | /* | 142 | /* |
200 | * First 32bits of unions are always present: | 143 | * First 32bits of unions are always present: |
201 | * si_pid === si_band === si_tid === si_addr(LS half) | 144 | * si_pid === si_band === si_tid === si_addr(LS half) |
202 | */ | 145 | */ |
203 | err |= __put_user(from->_sifields._pad[0], | 146 | err |= __put_user(from->_sifields._pad[0], |
204 | &to->_sifields._pad[0]); | 147 | &to->_sifields._pad[0]); |
205 | switch (from->si_code >> 16) { | 148 | switch (from->si_code >> 16) { |
206 | case __SI_FAULT >> 16: | 149 | case __SI_FAULT >> 16: |
207 | break; | 150 | break; |
208 | case __SI_CHLD >> 16: | 151 | case __SI_CHLD >> 16: |
209 | err |= __put_user(from->si_utime, &to->si_utime); | 152 | err |= __put_user(from->si_utime, &to->si_utime); |
210 | err |= __put_user(from->si_stime, &to->si_stime); | 153 | err |= __put_user(from->si_stime, &to->si_stime); |
211 | err |= __put_user(from->si_status, &to->si_status); | 154 | err |= __put_user(from->si_status, &to->si_status); |
212 | /* FALL THROUGH */ | 155 | /* FALL THROUGH */ |
213 | default: | 156 | default: |
214 | case __SI_KILL >> 16: | 157 | case __SI_KILL >> 16: |
215 | err |= __put_user(from->si_uid, &to->si_uid); | 158 | err |= __put_user(from->si_uid, &to->si_uid); |
216 | break; | 159 | break; |
217 | case __SI_POLL >> 16: | 160 | case __SI_POLL >> 16: |
218 | err |= __put_user(from->si_fd, &to->si_fd); | 161 | err |= __put_user(from->si_fd, &to->si_fd); |
219 | break; | 162 | break; |
220 | case __SI_TIMER >> 16: | 163 | case __SI_TIMER >> 16: |
221 | err |= __put_user(from->si_overrun, &to->si_overrun); | 164 | err |= __put_user(from->si_overrun, &to->si_overrun); |
222 | err |= __put_user(ptr_to_compat(from->si_ptr), | 165 | err |= __put_user(ptr_to_compat(from->si_ptr), |
223 | &to->si_ptr); | 166 | &to->si_ptr); |
224 | break; | 167 | break; |
225 | /* This is not generated by the kernel as of now. */ | 168 | /* This is not generated by the kernel as of now. */ |
226 | case __SI_RT >> 16: | 169 | case __SI_RT >> 16: |
227 | case __SI_MESGQ >> 16: | 170 | case __SI_MESGQ >> 16: |
228 | err |= __put_user(from->si_uid, &to->si_uid); | 171 | err |= __put_user(from->si_uid, &to->si_uid); |
229 | err |= __put_user(from->si_int, &to->si_int); | 172 | err |= __put_user(from->si_int, &to->si_int); |
230 | break; | 173 | break; |
231 | } | 174 | } |
232 | } | 175 | } |
233 | return err; | 176 | return err; |
234 | } | 177 | } |
235 | 178 | ||
236 | int copy_siginfo_from_user32(siginfo_t *to, struct compat_siginfo __user *from) | 179 | int copy_siginfo_from_user32(siginfo_t *to, struct compat_siginfo __user *from) |
237 | { | 180 | { |
238 | int err; | 181 | int err; |
239 | u32 ptr32; | 182 | u32 ptr32; |
240 | 183 | ||
241 | if (!access_ok(VERIFY_READ, from, sizeof(struct compat_siginfo))) | 184 | if (!access_ok(VERIFY_READ, from, sizeof(struct compat_siginfo))) |
242 | return -EFAULT; | 185 | return -EFAULT; |
243 | 186 | ||
244 | err = __get_user(to->si_signo, &from->si_signo); | 187 | err = __get_user(to->si_signo, &from->si_signo); |
245 | err |= __get_user(to->si_errno, &from->si_errno); | 188 | err |= __get_user(to->si_errno, &from->si_errno); |
246 | err |= __get_user(to->si_code, &from->si_code); | 189 | err |= __get_user(to->si_code, &from->si_code); |
247 | 190 | ||
248 | err |= __get_user(to->si_pid, &from->si_pid); | 191 | err |= __get_user(to->si_pid, &from->si_pid); |
249 | err |= __get_user(to->si_uid, &from->si_uid); | 192 | err |= __get_user(to->si_uid, &from->si_uid); |
250 | err |= __get_user(ptr32, &from->si_ptr); | 193 | err |= __get_user(ptr32, &from->si_ptr); |
251 | to->si_ptr = compat_ptr(ptr32); | 194 | to->si_ptr = compat_ptr(ptr32); |
252 | 195 | ||
253 | return err; | 196 | return err; |
254 | } | 197 | } |
255 | 198 | ||
256 | long compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr, | 199 | long compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr, |
257 | struct compat_sigaltstack __user *uoss_ptr, | 200 | struct compat_sigaltstack __user *uoss_ptr, |
258 | struct pt_regs *regs) | 201 | struct pt_regs *regs) |
259 | { | 202 | { |
260 | stack_t uss, uoss; | 203 | stack_t uss, uoss; |
261 | int ret; | 204 | int ret; |
262 | mm_segment_t seg; | 205 | mm_segment_t seg; |
263 | 206 | ||
264 | if (uss_ptr) { | 207 | if (uss_ptr) { |
265 | u32 ptr; | 208 | u32 ptr; |
266 | 209 | ||
267 | memset(&uss, 0, sizeof(stack_t)); | 210 | memset(&uss, 0, sizeof(stack_t)); |
268 | if (!access_ok(VERIFY_READ, uss_ptr, sizeof(*uss_ptr)) || | 211 | if (!access_ok(VERIFY_READ, uss_ptr, sizeof(*uss_ptr)) || |
269 | __get_user(ptr, &uss_ptr->ss_sp) || | 212 | __get_user(ptr, &uss_ptr->ss_sp) || |
270 | __get_user(uss.ss_flags, &uss_ptr->ss_flags) || | 213 | __get_user(uss.ss_flags, &uss_ptr->ss_flags) || |
271 | __get_user(uss.ss_size, &uss_ptr->ss_size)) | 214 | __get_user(uss.ss_size, &uss_ptr->ss_size)) |
272 | return -EFAULT; | 215 | return -EFAULT; |
273 | uss.ss_sp = compat_ptr(ptr); | 216 | uss.ss_sp = compat_ptr(ptr); |
274 | } | 217 | } |
275 | seg = get_fs(); | 218 | seg = get_fs(); |
276 | set_fs(KERNEL_DS); | 219 | set_fs(KERNEL_DS); |
277 | ret = do_sigaltstack(uss_ptr ? (stack_t __user __force *)&uss : NULL, | 220 | ret = do_sigaltstack(uss_ptr ? (stack_t __user __force *)&uss : NULL, |
278 | (stack_t __user __force *)&uoss, | 221 | (stack_t __user __force *)&uoss, |
279 | (unsigned long)compat_ptr(regs->sp)); | 222 | (unsigned long)compat_ptr(regs->sp)); |
280 | set_fs(seg); | 223 | set_fs(seg); |
281 | if (ret >= 0 && uoss_ptr) { | 224 | if (ret >= 0 && uoss_ptr) { |
282 | if (!access_ok(VERIFY_WRITE, uoss_ptr, sizeof(*uoss_ptr)) || | 225 | if (!access_ok(VERIFY_WRITE, uoss_ptr, sizeof(*uoss_ptr)) || |
283 | __put_user(ptr_to_compat(uoss.ss_sp), &uoss_ptr->ss_sp) || | 226 | __put_user(ptr_to_compat(uoss.ss_sp), &uoss_ptr->ss_sp) || |
284 | __put_user(uoss.ss_flags, &uoss_ptr->ss_flags) || | 227 | __put_user(uoss.ss_flags, &uoss_ptr->ss_flags) || |
285 | __put_user(uoss.ss_size, &uoss_ptr->ss_size)) | 228 | __put_user(uoss.ss_size, &uoss_ptr->ss_size)) |
286 | ret = -EFAULT; | 229 | ret = -EFAULT; |
287 | } | 230 | } |
288 | return ret; | 231 | return ret; |
289 | } | 232 | } |
290 | 233 | ||
291 | /* The assembly shim for this function arranges to ignore the return value. */ | 234 | /* The assembly shim for this function arranges to ignore the return value. */ |
292 | long compat_sys_rt_sigreturn(struct pt_regs *regs) | 235 | long compat_sys_rt_sigreturn(struct pt_regs *regs) |
293 | { | 236 | { |
294 | struct compat_rt_sigframe __user *frame = | 237 | struct compat_rt_sigframe __user *frame = |
295 | (struct compat_rt_sigframe __user *) compat_ptr(regs->sp); | 238 | (struct compat_rt_sigframe __user *) compat_ptr(regs->sp); |
296 | sigset_t set; | 239 | sigset_t set; |
297 | 240 | ||
298 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) | 241 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) |
299 | goto badframe; | 242 | goto badframe; |
300 | if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) | 243 | if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) |
301 | goto badframe; | 244 | goto badframe; |
302 | 245 | ||
303 | set_current_blocked(&set); | 246 | set_current_blocked(&set); |
304 | 247 | ||
305 | if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) | 248 | if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) |
306 | goto badframe; | 249 | goto badframe; |
307 | 250 | ||
308 | if (compat_sys_sigaltstack(&frame->uc.uc_stack, NULL, regs) != 0) | 251 | if (compat_sys_sigaltstack(&frame->uc.uc_stack, NULL, regs) != 0) |
309 | goto badframe; | 252 | goto badframe; |
310 | 253 | ||
311 | return 0; | 254 | return 0; |
312 | 255 | ||
313 | badframe: | 256 | badframe: |
314 | signal_fault("bad sigreturn frame", regs, frame, 0); | 257 | signal_fault("bad sigreturn frame", regs, frame, 0); |
315 | return 0; | 258 | return 0; |
316 | } | 259 | } |
317 | 260 | ||
318 | /* | 261 | /* |
319 | * Determine which stack to use.. | 262 | * Determine which stack to use.. |
320 | */ | 263 | */ |
321 | static inline void __user *compat_get_sigframe(struct k_sigaction *ka, | 264 | static inline void __user *compat_get_sigframe(struct k_sigaction *ka, |
322 | struct pt_regs *regs, | 265 | struct pt_regs *regs, |
323 | size_t frame_size) | 266 | size_t frame_size) |
324 | { | 267 | { |
325 | unsigned long sp; | 268 | unsigned long sp; |
326 | 269 | ||
327 | /* Default to using normal stack */ | 270 | /* Default to using normal stack */ |
328 | sp = (unsigned long)compat_ptr(regs->sp); | 271 | sp = (unsigned long)compat_ptr(regs->sp); |
329 | 272 | ||
330 | /* | 273 | /* |
331 | * If we are on the alternate signal stack and would overflow | 274 | * If we are on the alternate signal stack and would overflow |
332 | * it, don't. Return an always-bogus address instead so we | 275 | * it, don't. Return an always-bogus address instead so we |
333 | * will die with SIGSEGV. | 276 | * will die with SIGSEGV. |
334 | */ | 277 | */ |
335 | if (on_sig_stack(sp) && !likely(on_sig_stack(sp - frame_size))) | 278 | if (on_sig_stack(sp) && !likely(on_sig_stack(sp - frame_size))) |
336 | return (void __user __force *)-1UL; | 279 | return (void __user __force *)-1UL; |
337 | 280 | ||
338 | /* This is the X/Open sanctioned signal stack switching. */ | 281 | /* This is the X/Open sanctioned signal stack switching. */ |
339 | if (ka->sa.sa_flags & SA_ONSTACK) { | 282 | if (ka->sa.sa_flags & SA_ONSTACK) { |
340 | if (sas_ss_flags(sp) == 0) | 283 | if (sas_ss_flags(sp) == 0) |
341 | sp = current->sas_ss_sp + current->sas_ss_size; | 284 | sp = current->sas_ss_sp + current->sas_ss_size; |
342 | } | 285 | } |
343 | 286 | ||
344 | sp -= frame_size; | 287 | sp -= frame_size; |
345 | /* | 288 | /* |
346 | * Align the stack pointer according to the TILE ABI, | 289 | * Align the stack pointer according to the TILE ABI, |
347 | * i.e. so that on function entry (sp & 15) == 0. | 290 | * i.e. so that on function entry (sp & 15) == 0. |
348 | */ | 291 | */ |
349 | sp &= -16UL; | 292 | sp &= -16UL; |
350 | return (void __user *) sp; | 293 | return (void __user *) sp; |
351 | } | 294 | } |
352 | 295 | ||
353 | int compat_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | 296 | int compat_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, |
354 | sigset_t *set, struct pt_regs *regs) | 297 | sigset_t *set, struct pt_regs *regs) |
355 | { | 298 | { |
356 | unsigned long restorer; | 299 | unsigned long restorer; |
357 | struct compat_rt_sigframe __user *frame; | 300 | struct compat_rt_sigframe __user *frame; |
358 | int err = 0; | 301 | int err = 0; |
359 | int usig; | 302 | int usig; |
360 | 303 | ||
361 | frame = compat_get_sigframe(ka, regs, sizeof(*frame)); | 304 | frame = compat_get_sigframe(ka, regs, sizeof(*frame)); |
362 | 305 | ||
363 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) | 306 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) |
364 | goto give_sigsegv; | 307 | goto give_sigsegv; |
365 | 308 | ||
366 | usig = current_thread_info()->exec_domain | 309 | usig = current_thread_info()->exec_domain |
367 | && current_thread_info()->exec_domain->signal_invmap | 310 | && current_thread_info()->exec_domain->signal_invmap |
368 | && sig < 32 | 311 | && sig < 32 |
369 | ? current_thread_info()->exec_domain->signal_invmap[sig] | 312 | ? current_thread_info()->exec_domain->signal_invmap[sig] |
370 | : sig; | 313 | : sig; |
371 | 314 | ||
372 | /* Always write at least the signal number for the stack backtracer. */ | 315 | /* Always write at least the signal number for the stack backtracer. */ |
373 | if (ka->sa.sa_flags & SA_SIGINFO) { | 316 | if (ka->sa.sa_flags & SA_SIGINFO) { |
374 | /* At sigreturn time, restore the callee-save registers too. */ | 317 | /* At sigreturn time, restore the callee-save registers too. */ |
375 | err |= copy_siginfo_to_user32(&frame->info, info); | 318 | err |= copy_siginfo_to_user32(&frame->info, info); |
376 | regs->flags |= PT_FLAGS_RESTORE_REGS; | 319 | regs->flags |= PT_FLAGS_RESTORE_REGS; |
377 | } else { | 320 | } else { |
378 | err |= __put_user(info->si_signo, &frame->info.si_signo); | 321 | err |= __put_user(info->si_signo, &frame->info.si_signo); |
379 | } | 322 | } |
380 | 323 | ||
381 | /* Create the ucontext. */ | 324 | /* Create the ucontext. */ |
382 | err |= __clear_user(&frame->save_area, sizeof(frame->save_area)); | 325 | err |= __clear_user(&frame->save_area, sizeof(frame->save_area)); |
383 | err |= __put_user(0, &frame->uc.uc_flags); | 326 | err |= __put_user(0, &frame->uc.uc_flags); |
384 | err |= __put_user(0, &frame->uc.uc_link); | 327 | err |= __put_user(0, &frame->uc.uc_link); |
385 | err |= __put_user(ptr_to_compat((void *)(current->sas_ss_sp)), | 328 | err |= __put_user(ptr_to_compat((void *)(current->sas_ss_sp)), |
386 | &frame->uc.uc_stack.ss_sp); | 329 | &frame->uc.uc_stack.ss_sp); |
387 | err |= __put_user(sas_ss_flags(regs->sp), | 330 | err |= __put_user(sas_ss_flags(regs->sp), |
388 | &frame->uc.uc_stack.ss_flags); | 331 | &frame->uc.uc_stack.ss_flags); |
389 | err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); | 332 | err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); |
390 | err |= setup_sigcontext(&frame->uc.uc_mcontext, regs); | 333 | err |= setup_sigcontext(&frame->uc.uc_mcontext, regs); |
391 | err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); | 334 | err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); |
392 | if (err) | 335 | if (err) |
393 | goto give_sigsegv; | 336 | goto give_sigsegv; |
394 | 337 | ||
395 | restorer = VDSO_BASE; | 338 | restorer = VDSO_BASE; |
396 | if (ka->sa.sa_flags & SA_RESTORER) | 339 | if (ka->sa.sa_flags & SA_RESTORER) |
397 | restorer = ptr_to_compat_reg(ka->sa.sa_restorer); | 340 | restorer = ptr_to_compat_reg(ka->sa.sa_restorer); |
398 | 341 | ||
399 | /* | 342 | /* |
400 | * Set up registers for signal handler. | 343 | * Set up registers for signal handler. |
401 | * Registers that we don't modify keep the value they had from | 344 | * Registers that we don't modify keep the value they had from |
402 | * user-space at the time we took the signal. | 345 | * user-space at the time we took the signal. |
403 | * We always pass siginfo and mcontext, regardless of SA_SIGINFO, | 346 | * We always pass siginfo and mcontext, regardless of SA_SIGINFO, |
404 | * since some things rely on this (e.g. glibc's debug/segfault.c). | 347 | * since some things rely on this (e.g. glibc's debug/segfault.c). |
405 | */ | 348 | */ |
406 | regs->pc = ptr_to_compat_reg(ka->sa.sa_handler); | 349 | regs->pc = ptr_to_compat_reg(ka->sa.sa_handler); |
407 | regs->ex1 = PL_ICS_EX1(USER_PL, 1); /* set crit sec in handler */ | 350 | regs->ex1 = PL_ICS_EX1(USER_PL, 1); /* set crit sec in handler */ |
408 | regs->sp = ptr_to_compat_reg(frame); | 351 | regs->sp = ptr_to_compat_reg(frame); |
409 | regs->lr = restorer; | 352 | regs->lr = restorer; |
410 | regs->regs[0] = (unsigned long) usig; | 353 | regs->regs[0] = (unsigned long) usig; |
411 | regs->regs[1] = ptr_to_compat_reg(&frame->info); | 354 | regs->regs[1] = ptr_to_compat_reg(&frame->info); |
412 | regs->regs[2] = ptr_to_compat_reg(&frame->uc); | 355 | regs->regs[2] = ptr_to_compat_reg(&frame->uc); |
413 | regs->flags |= PT_FLAGS_CALLER_SAVES; | 356 | regs->flags |= PT_FLAGS_CALLER_SAVES; |
414 | 357 | ||
415 | /* | 358 | /* |
416 | * Notify any tracer that was single-stepping it. | 359 | * Notify any tracer that was single-stepping it. |
417 | * The tracer may want to single-step inside the | 360 | * The tracer may want to single-step inside the |
418 | * handler too. | 361 | * handler too. |
419 | */ | 362 | */ |
420 | if (test_thread_flag(TIF_SINGLESTEP)) | 363 | if (test_thread_flag(TIF_SINGLESTEP)) |
421 | ptrace_notify(SIGTRAP); | 364 | ptrace_notify(SIGTRAP); |
422 | 365 | ||
423 | return 0; | 366 | return 0; |
424 | 367 | ||
425 | give_sigsegv: | 368 | give_sigsegv: |
426 | signal_fault("bad setup frame", regs, frame, sig); | 369 | signal_fault("bad setup frame", regs, frame, sig); |
427 | return -EFAULT; | 370 | return -EFAULT; |
428 | } | 371 | } |
429 | 372 |
arch/x86/include/asm/compat.h
1 | #ifndef _ASM_X86_COMPAT_H | 1 | #ifndef _ASM_X86_COMPAT_H |
2 | #define _ASM_X86_COMPAT_H | 2 | #define _ASM_X86_COMPAT_H |
3 | 3 | ||
4 | /* | 4 | /* |
5 | * Architecture specific compatibility types | 5 | * Architecture specific compatibility types |
6 | */ | 6 | */ |
7 | #include <linux/types.h> | 7 | #include <linux/types.h> |
8 | #include <linux/sched.h> | 8 | #include <linux/sched.h> |
9 | #include <asm/processor.h> | 9 | #include <asm/processor.h> |
10 | #include <asm/user32.h> | 10 | #include <asm/user32.h> |
11 | #include <asm/unistd.h> | 11 | #include <asm/unistd.h> |
12 | 12 | ||
13 | #define COMPAT_USER_HZ 100 | 13 | #define COMPAT_USER_HZ 100 |
14 | #define COMPAT_UTS_MACHINE "i686\0\0" | 14 | #define COMPAT_UTS_MACHINE "i686\0\0" |
15 | 15 | ||
16 | typedef u32 compat_size_t; | 16 | typedef u32 compat_size_t; |
17 | typedef s32 compat_ssize_t; | 17 | typedef s32 compat_ssize_t; |
18 | typedef s32 compat_time_t; | 18 | typedef s32 compat_time_t; |
19 | typedef s32 compat_clock_t; | 19 | typedef s32 compat_clock_t; |
20 | typedef s32 compat_pid_t; | 20 | typedef s32 compat_pid_t; |
21 | typedef u16 __compat_uid_t; | 21 | typedef u16 __compat_uid_t; |
22 | typedef u16 __compat_gid_t; | 22 | typedef u16 __compat_gid_t; |
23 | typedef u32 __compat_uid32_t; | 23 | typedef u32 __compat_uid32_t; |
24 | typedef u32 __compat_gid32_t; | 24 | typedef u32 __compat_gid32_t; |
25 | typedef u16 compat_mode_t; | 25 | typedef u16 compat_mode_t; |
26 | typedef u32 compat_ino_t; | 26 | typedef u32 compat_ino_t; |
27 | typedef u16 compat_dev_t; | 27 | typedef u16 compat_dev_t; |
28 | typedef s32 compat_off_t; | 28 | typedef s32 compat_off_t; |
29 | typedef s64 compat_loff_t; | 29 | typedef s64 compat_loff_t; |
30 | typedef u16 compat_nlink_t; | 30 | typedef u16 compat_nlink_t; |
31 | typedef u16 compat_ipc_pid_t; | 31 | typedef u16 compat_ipc_pid_t; |
32 | typedef s32 compat_daddr_t; | 32 | typedef s32 compat_daddr_t; |
33 | typedef u32 compat_caddr_t; | 33 | typedef u32 compat_caddr_t; |
34 | typedef __kernel_fsid_t compat_fsid_t; | 34 | typedef __kernel_fsid_t compat_fsid_t; |
35 | typedef s32 compat_timer_t; | 35 | typedef s32 compat_timer_t; |
36 | typedef s32 compat_key_t; | 36 | typedef s32 compat_key_t; |
37 | 37 | ||
38 | typedef s32 compat_int_t; | 38 | typedef s32 compat_int_t; |
39 | typedef s32 compat_long_t; | 39 | typedef s32 compat_long_t; |
40 | typedef s64 __attribute__((aligned(4))) compat_s64; | 40 | typedef s64 __attribute__((aligned(4))) compat_s64; |
41 | typedef u32 compat_uint_t; | 41 | typedef u32 compat_uint_t; |
42 | typedef u32 compat_ulong_t; | 42 | typedef u32 compat_ulong_t; |
43 | typedef u64 __attribute__((aligned(4))) compat_u64; | 43 | typedef u64 __attribute__((aligned(4))) compat_u64; |
44 | typedef u32 compat_uptr_t; | ||
44 | 45 | ||
45 | struct compat_timespec { | 46 | struct compat_timespec { |
46 | compat_time_t tv_sec; | 47 | compat_time_t tv_sec; |
47 | s32 tv_nsec; | 48 | s32 tv_nsec; |
48 | }; | 49 | }; |
49 | 50 | ||
50 | struct compat_timeval { | 51 | struct compat_timeval { |
51 | compat_time_t tv_sec; | 52 | compat_time_t tv_sec; |
52 | s32 tv_usec; | 53 | s32 tv_usec; |
53 | }; | 54 | }; |
54 | 55 | ||
55 | struct compat_stat { | 56 | struct compat_stat { |
56 | compat_dev_t st_dev; | 57 | compat_dev_t st_dev; |
57 | u16 __pad1; | 58 | u16 __pad1; |
58 | compat_ino_t st_ino; | 59 | compat_ino_t st_ino; |
59 | compat_mode_t st_mode; | 60 | compat_mode_t st_mode; |
60 | compat_nlink_t st_nlink; | 61 | compat_nlink_t st_nlink; |
61 | __compat_uid_t st_uid; | 62 | __compat_uid_t st_uid; |
62 | __compat_gid_t st_gid; | 63 | __compat_gid_t st_gid; |
63 | compat_dev_t st_rdev; | 64 | compat_dev_t st_rdev; |
64 | u16 __pad2; | 65 | u16 __pad2; |
65 | u32 st_size; | 66 | u32 st_size; |
66 | u32 st_blksize; | 67 | u32 st_blksize; |
67 | u32 st_blocks; | 68 | u32 st_blocks; |
68 | u32 st_atime; | 69 | u32 st_atime; |
69 | u32 st_atime_nsec; | 70 | u32 st_atime_nsec; |
70 | u32 st_mtime; | 71 | u32 st_mtime; |
71 | u32 st_mtime_nsec; | 72 | u32 st_mtime_nsec; |
72 | u32 st_ctime; | 73 | u32 st_ctime; |
73 | u32 st_ctime_nsec; | 74 | u32 st_ctime_nsec; |
74 | u32 __unused4; | 75 | u32 __unused4; |
75 | u32 __unused5; | 76 | u32 __unused5; |
76 | }; | 77 | }; |
77 | 78 | ||
78 | struct compat_flock { | 79 | struct compat_flock { |
79 | short l_type; | 80 | short l_type; |
80 | short l_whence; | 81 | short l_whence; |
81 | compat_off_t l_start; | 82 | compat_off_t l_start; |
82 | compat_off_t l_len; | 83 | compat_off_t l_len; |
83 | compat_pid_t l_pid; | 84 | compat_pid_t l_pid; |
84 | }; | 85 | }; |
85 | 86 | ||
86 | #define F_GETLK64 12 /* using 'struct flock64' */ | 87 | #define F_GETLK64 12 /* using 'struct flock64' */ |
87 | #define F_SETLK64 13 | 88 | #define F_SETLK64 13 |
88 | #define F_SETLKW64 14 | 89 | #define F_SETLKW64 14 |
89 | 90 | ||
90 | /* | 91 | /* |
91 | * IA32 uses 4 byte alignment for 64 bit quantities, | 92 | * IA32 uses 4 byte alignment for 64 bit quantities, |
92 | * so we need to pack this structure. | 93 | * so we need to pack this structure. |
93 | */ | 94 | */ |
94 | struct compat_flock64 { | 95 | struct compat_flock64 { |
95 | short l_type; | 96 | short l_type; |
96 | short l_whence; | 97 | short l_whence; |
97 | compat_loff_t l_start; | 98 | compat_loff_t l_start; |
98 | compat_loff_t l_len; | 99 | compat_loff_t l_len; |
99 | compat_pid_t l_pid; | 100 | compat_pid_t l_pid; |
100 | } __attribute__((packed)); | 101 | } __attribute__((packed)); |
101 | 102 | ||
102 | struct compat_statfs { | 103 | struct compat_statfs { |
103 | int f_type; | 104 | int f_type; |
104 | int f_bsize; | 105 | int f_bsize; |
105 | int f_blocks; | 106 | int f_blocks; |
106 | int f_bfree; | 107 | int f_bfree; |
107 | int f_bavail; | 108 | int f_bavail; |
108 | int f_files; | 109 | int f_files; |
109 | int f_ffree; | 110 | int f_ffree; |
110 | compat_fsid_t f_fsid; | 111 | compat_fsid_t f_fsid; |
111 | int f_namelen; /* SunOS ignores this field. */ | 112 | int f_namelen; /* SunOS ignores this field. */ |
112 | int f_frsize; | 113 | int f_frsize; |
113 | int f_flags; | 114 | int f_flags; |
114 | int f_spare[4]; | 115 | int f_spare[4]; |
115 | }; | 116 | }; |
116 | 117 | ||
117 | #define COMPAT_RLIM_OLD_INFINITY 0x7fffffff | 118 | #define COMPAT_RLIM_OLD_INFINITY 0x7fffffff |
118 | #define COMPAT_RLIM_INFINITY 0xffffffff | 119 | #define COMPAT_RLIM_INFINITY 0xffffffff |
119 | 120 | ||
120 | typedef u32 compat_old_sigset_t; /* at least 32 bits */ | 121 | typedef u32 compat_old_sigset_t; /* at least 32 bits */ |
121 | 122 | ||
122 | #define _COMPAT_NSIG 64 | 123 | #define _COMPAT_NSIG 64 |
123 | #define _COMPAT_NSIG_BPW 32 | 124 | #define _COMPAT_NSIG_BPW 32 |
124 | 125 | ||
125 | typedef u32 compat_sigset_word; | 126 | typedef u32 compat_sigset_word; |
126 | 127 | ||
128 | typedef union compat_sigval { | ||
129 | compat_int_t sival_int; | ||
130 | compat_uptr_t sival_ptr; | ||
131 | } compat_sigval_t; | ||
132 | |||
133 | typedef struct compat_siginfo { | ||
134 | int si_signo; | ||
135 | int si_errno; | ||
136 | int si_code; | ||
137 | |||
138 | union { | ||
139 | int _pad[128/sizeof(int) - 3]; | ||
140 | |||
141 | /* kill() */ | ||
142 | struct { | ||
143 | unsigned int _pid; /* sender's pid */ | ||
144 | unsigned int _uid; /* sender's uid */ | ||
145 | } _kill; | ||
146 | |||
147 | /* POSIX.1b timers */ | ||
148 | struct { | ||
149 | compat_timer_t _tid; /* timer id */ | ||
150 | int _overrun; /* overrun count */ | ||
151 | compat_sigval_t _sigval; /* same as below */ | ||
152 | int _sys_private; /* not to be passed to user */ | ||
153 | int _overrun_incr; /* amount to add to overrun */ | ||
154 | } _timer; | ||
155 | |||
156 | /* POSIX.1b signals */ | ||
157 | struct { | ||
158 | unsigned int _pid; /* sender's pid */ | ||
159 | unsigned int _uid; /* sender's uid */ | ||
160 | compat_sigval_t _sigval; | ||
161 | } _rt; | ||
162 | |||
163 | /* SIGCHLD */ | ||
164 | struct { | ||
165 | unsigned int _pid; /* which child */ | ||
166 | unsigned int _uid; /* sender's uid */ | ||
167 | int _status; /* exit code */ | ||
168 | compat_clock_t _utime; | ||
169 | compat_clock_t _stime; | ||
170 | } _sigchld; | ||
171 | |||
172 | /* SIGCHLD (x32 version) */ | ||
173 | struct { | ||
174 | unsigned int _pid; /* which child */ | ||
175 | unsigned int _uid; /* sender's uid */ | ||
176 | int _status; /* exit code */ | ||
177 | compat_s64 _utime; | ||
178 | compat_s64 _stime; | ||
179 | } _sigchld_x32; | ||
180 | |||
181 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ | ||
182 | struct { | ||
183 | unsigned int _addr; /* faulting insn/memory ref. */ | ||
184 | } _sigfault; | ||
185 | |||
186 | /* SIGPOLL */ | ||
187 | struct { | ||
188 | int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ | ||
189 | int _fd; | ||
190 | } _sigpoll; | ||
191 | |||
192 | struct { | ||
193 | unsigned int _call_addr; /* calling insn */ | ||
194 | int _syscall; /* triggering system call number */ | ||
195 | unsigned int _arch; /* AUDIT_ARCH_* of syscall */ | ||
196 | } _sigsys; | ||
197 | } _sifields; | ||
198 | } compat_siginfo_t; | ||
199 | |||
127 | #define COMPAT_OFF_T_MAX 0x7fffffff | 200 | #define COMPAT_OFF_T_MAX 0x7fffffff |
128 | #define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL | 201 | #define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL |
129 | 202 | ||
130 | struct compat_ipc64_perm { | 203 | struct compat_ipc64_perm { |
131 | compat_key_t key; | 204 | compat_key_t key; |
132 | __compat_uid32_t uid; | 205 | __compat_uid32_t uid; |
133 | __compat_gid32_t gid; | 206 | __compat_gid32_t gid; |
134 | __compat_uid32_t cuid; | 207 | __compat_uid32_t cuid; |
135 | __compat_gid32_t cgid; | 208 | __compat_gid32_t cgid; |
136 | unsigned short mode; | 209 | unsigned short mode; |
137 | unsigned short __pad1; | 210 | unsigned short __pad1; |
138 | unsigned short seq; | 211 | unsigned short seq; |
139 | unsigned short __pad2; | 212 | unsigned short __pad2; |
140 | compat_ulong_t unused1; | 213 | compat_ulong_t unused1; |
141 | compat_ulong_t unused2; | 214 | compat_ulong_t unused2; |
142 | }; | 215 | }; |
143 | 216 | ||
144 | struct compat_semid64_ds { | 217 | struct compat_semid64_ds { |
145 | struct compat_ipc64_perm sem_perm; | 218 | struct compat_ipc64_perm sem_perm; |
146 | compat_time_t sem_otime; | 219 | compat_time_t sem_otime; |
147 | compat_ulong_t __unused1; | 220 | compat_ulong_t __unused1; |
148 | compat_time_t sem_ctime; | 221 | compat_time_t sem_ctime; |
149 | compat_ulong_t __unused2; | 222 | compat_ulong_t __unused2; |
150 | compat_ulong_t sem_nsems; | 223 | compat_ulong_t sem_nsems; |
151 | compat_ulong_t __unused3; | 224 | compat_ulong_t __unused3; |
152 | compat_ulong_t __unused4; | 225 | compat_ulong_t __unused4; |
153 | }; | 226 | }; |
154 | 227 | ||
155 | struct compat_msqid64_ds { | 228 | struct compat_msqid64_ds { |
156 | struct compat_ipc64_perm msg_perm; | 229 | struct compat_ipc64_perm msg_perm; |
157 | compat_time_t msg_stime; | 230 | compat_time_t msg_stime; |
158 | compat_ulong_t __unused1; | 231 | compat_ulong_t __unused1; |
159 | compat_time_t msg_rtime; | 232 | compat_time_t msg_rtime; |
160 | compat_ulong_t __unused2; | 233 | compat_ulong_t __unused2; |
161 | compat_time_t msg_ctime; | 234 | compat_time_t msg_ctime; |
162 | compat_ulong_t __unused3; | 235 | compat_ulong_t __unused3; |
163 | compat_ulong_t msg_cbytes; | 236 | compat_ulong_t msg_cbytes; |
164 | compat_ulong_t msg_qnum; | 237 | compat_ulong_t msg_qnum; |
165 | compat_ulong_t msg_qbytes; | 238 | compat_ulong_t msg_qbytes; |
166 | compat_pid_t msg_lspid; | 239 | compat_pid_t msg_lspid; |
167 | compat_pid_t msg_lrpid; | 240 | compat_pid_t msg_lrpid; |
168 | compat_ulong_t __unused4; | 241 | compat_ulong_t __unused4; |
169 | compat_ulong_t __unused5; | 242 | compat_ulong_t __unused5; |
170 | }; | 243 | }; |
171 | 244 | ||
172 | struct compat_shmid64_ds { | 245 | struct compat_shmid64_ds { |
173 | struct compat_ipc64_perm shm_perm; | 246 | struct compat_ipc64_perm shm_perm; |
174 | compat_size_t shm_segsz; | 247 | compat_size_t shm_segsz; |
175 | compat_time_t shm_atime; | 248 | compat_time_t shm_atime; |
176 | compat_ulong_t __unused1; | 249 | compat_ulong_t __unused1; |
177 | compat_time_t shm_dtime; | 250 | compat_time_t shm_dtime; |
178 | compat_ulong_t __unused2; | 251 | compat_ulong_t __unused2; |
179 | compat_time_t shm_ctime; | 252 | compat_time_t shm_ctime; |
180 | compat_ulong_t __unused3; | 253 | compat_ulong_t __unused3; |
181 | compat_pid_t shm_cpid; | 254 | compat_pid_t shm_cpid; |
182 | compat_pid_t shm_lpid; | 255 | compat_pid_t shm_lpid; |
183 | compat_ulong_t shm_nattch; | 256 | compat_ulong_t shm_nattch; |
184 | compat_ulong_t __unused4; | 257 | compat_ulong_t __unused4; |
185 | compat_ulong_t __unused5; | 258 | compat_ulong_t __unused5; |
186 | }; | 259 | }; |
187 | 260 | ||
188 | /* | 261 | /* |
189 | * The type of struct elf_prstatus.pr_reg in compatible core dumps. | 262 | * The type of struct elf_prstatus.pr_reg in compatible core dumps. |
190 | */ | 263 | */ |
191 | #ifdef CONFIG_X86_X32_ABI | 264 | #ifdef CONFIG_X86_X32_ABI |
192 | typedef struct user_regs_struct compat_elf_gregset_t; | 265 | typedef struct user_regs_struct compat_elf_gregset_t; |
193 | 266 | ||
194 | #define PR_REG_SIZE(S) (test_thread_flag(TIF_IA32) ? 68 : 216) | 267 | #define PR_REG_SIZE(S) (test_thread_flag(TIF_IA32) ? 68 : 216) |
195 | #define PRSTATUS_SIZE(S) (test_thread_flag(TIF_IA32) ? 144 : 296) | 268 | #define PRSTATUS_SIZE(S) (test_thread_flag(TIF_IA32) ? 144 : 296) |
196 | #define SET_PR_FPVALID(S,V) \ | 269 | #define SET_PR_FPVALID(S,V) \ |
197 | do { *(int *) (((void *) &((S)->pr_reg)) + PR_REG_SIZE(0)) = (V); } \ | 270 | do { *(int *) (((void *) &((S)->pr_reg)) + PR_REG_SIZE(0)) = (V); } \ |
198 | while (0) | 271 | while (0) |
199 | 272 | ||
200 | #define COMPAT_USE_64BIT_TIME \ | 273 | #define COMPAT_USE_64BIT_TIME \ |
201 | (!!(task_pt_regs(current)->orig_ax & __X32_SYSCALL_BIT)) | 274 | (!!(task_pt_regs(current)->orig_ax & __X32_SYSCALL_BIT)) |
202 | #else | 275 | #else |
203 | typedef struct user_regs_struct32 compat_elf_gregset_t; | 276 | typedef struct user_regs_struct32 compat_elf_gregset_t; |
204 | #endif | 277 | #endif |
205 | 278 | ||
206 | /* | 279 | /* |
207 | * A pointer passed in from user mode. This should not | 280 | * A pointer passed in from user mode. This should not |
208 | * be used for syscall parameters, just declare them | 281 | * be used for syscall parameters, just declare them |
209 | * as pointers because the syscall entry code will have | 282 | * as pointers because the syscall entry code will have |
210 | * appropriately converted them already. | 283 | * appropriately converted them already. |
211 | */ | 284 | */ |
212 | typedef u32 compat_uptr_t; | ||
213 | 285 | ||
214 | static inline void __user *compat_ptr(compat_uptr_t uptr) | 286 | static inline void __user *compat_ptr(compat_uptr_t uptr) |
215 | { | 287 | { |
216 | return (void __user *)(unsigned long)uptr; | 288 | return (void __user *)(unsigned long)uptr; |
217 | } | 289 | } |
218 | 290 | ||
219 | static inline compat_uptr_t ptr_to_compat(void __user *uptr) | 291 | static inline compat_uptr_t ptr_to_compat(void __user *uptr) |
220 | { | 292 | { |
221 | return (u32)(unsigned long)uptr; | 293 | return (u32)(unsigned long)uptr; |
222 | } | 294 | } |
223 | 295 | ||
224 | static inline void __user *arch_compat_alloc_user_space(long len) | 296 | static inline void __user *arch_compat_alloc_user_space(long len) |
225 | { | 297 | { |
226 | compat_uptr_t sp; | 298 | compat_uptr_t sp; |
227 | 299 | ||
228 | if (test_thread_flag(TIF_IA32)) { | 300 | if (test_thread_flag(TIF_IA32)) { |
229 | sp = task_pt_regs(current)->sp; | 301 | sp = task_pt_regs(current)->sp; |
230 | } else { | 302 | } else { |
231 | /* -128 for the x32 ABI redzone */ | 303 | /* -128 for the x32 ABI redzone */ |
232 | sp = this_cpu_read(old_rsp) - 128; | 304 | sp = this_cpu_read(old_rsp) - 128; |
233 | } | 305 | } |
234 | 306 | ||
235 | return (void __user *)round_down(sp - len, 16); | 307 | return (void __user *)round_down(sp - len, 16); |
236 | } | 308 | } |
237 | 309 | ||
238 | static inline bool is_x32_task(void) | 310 | static inline bool is_x32_task(void) |
239 | { | 311 | { |
240 | #ifdef CONFIG_X86_X32_ABI | 312 | #ifdef CONFIG_X86_X32_ABI |
241 | if (task_pt_regs(current)->orig_ax & __X32_SYSCALL_BIT) | 313 | if (task_pt_regs(current)->orig_ax & __X32_SYSCALL_BIT) |
242 | return true; | 314 | return true; |
243 | #endif | 315 | #endif |
244 | return false; | 316 | return false; |
245 | } | 317 | } |
246 | 318 | ||
247 | static inline bool is_compat_task(void) | 319 | static inline bool is_compat_task(void) |
248 | { | 320 | { |
249 | return is_ia32_task() || is_x32_task(); | 321 | return is_ia32_task() || is_x32_task(); |
250 | } | 322 | } |
251 | 323 | ||
252 | #endif /* _ASM_X86_COMPAT_H */ | 324 | #endif /* _ASM_X86_COMPAT_H */ |
arch/x86/include/asm/ia32.h
1 | #ifndef _ASM_X86_IA32_H | 1 | #ifndef _ASM_X86_IA32_H |
2 | #define _ASM_X86_IA32_H | 2 | #define _ASM_X86_IA32_H |
3 | 3 | ||
4 | 4 | ||
5 | #ifdef CONFIG_IA32_EMULATION | 5 | #ifdef CONFIG_IA32_EMULATION |
6 | 6 | ||
7 | #include <linux/compat.h> | 7 | #include <linux/compat.h> |
8 | 8 | ||
9 | /* | 9 | /* |
10 | * 32 bit structures for IA32 support. | 10 | * 32 bit structures for IA32 support. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <asm/sigcontext32.h> | 13 | #include <asm/sigcontext32.h> |
14 | 14 | ||
15 | /* signal.h */ | 15 | /* signal.h */ |
16 | struct sigaction32 { | 16 | struct sigaction32 { |
17 | unsigned int sa_handler; /* Really a pointer, but need to deal | 17 | unsigned int sa_handler; /* Really a pointer, but need to deal |
18 | with 32 bits */ | 18 | with 32 bits */ |
19 | unsigned int sa_flags; | 19 | unsigned int sa_flags; |
20 | unsigned int sa_restorer; /* Another 32 bit pointer */ | 20 | unsigned int sa_restorer; /* Another 32 bit pointer */ |
21 | compat_sigset_t sa_mask; /* A 32 bit mask */ | 21 | compat_sigset_t sa_mask; /* A 32 bit mask */ |
22 | }; | 22 | }; |
23 | 23 | ||
24 | struct old_sigaction32 { | 24 | struct old_sigaction32 { |
25 | unsigned int sa_handler; /* Really a pointer, but need to deal | 25 | unsigned int sa_handler; /* Really a pointer, but need to deal |
26 | with 32 bits */ | 26 | with 32 bits */ |
27 | compat_old_sigset_t sa_mask; /* A 32 bit mask */ | 27 | compat_old_sigset_t sa_mask; /* A 32 bit mask */ |
28 | unsigned int sa_flags; | 28 | unsigned int sa_flags; |
29 | unsigned int sa_restorer; /* Another 32 bit pointer */ | 29 | unsigned int sa_restorer; /* Another 32 bit pointer */ |
30 | }; | 30 | }; |
31 | 31 | ||
32 | typedef struct sigaltstack_ia32 { | 32 | typedef struct sigaltstack_ia32 { |
33 | unsigned int ss_sp; | 33 | unsigned int ss_sp; |
34 | int ss_flags; | 34 | int ss_flags; |
35 | unsigned int ss_size; | 35 | unsigned int ss_size; |
36 | } stack_ia32_t; | 36 | } stack_ia32_t; |
37 | 37 | ||
38 | struct ucontext_ia32 { | 38 | struct ucontext_ia32 { |
39 | unsigned int uc_flags; | 39 | unsigned int uc_flags; |
40 | unsigned int uc_link; | 40 | unsigned int uc_link; |
41 | stack_ia32_t uc_stack; | 41 | stack_ia32_t uc_stack; |
42 | struct sigcontext_ia32 uc_mcontext; | 42 | struct sigcontext_ia32 uc_mcontext; |
43 | compat_sigset_t uc_sigmask; /* mask last for extensibility */ | 43 | compat_sigset_t uc_sigmask; /* mask last for extensibility */ |
44 | }; | 44 | }; |
45 | 45 | ||
46 | struct ucontext_x32 { | 46 | struct ucontext_x32 { |
47 | unsigned int uc_flags; | 47 | unsigned int uc_flags; |
48 | unsigned int uc_link; | 48 | unsigned int uc_link; |
49 | stack_ia32_t uc_stack; | 49 | stack_ia32_t uc_stack; |
50 | unsigned int uc__pad0; /* needed for alignment */ | 50 | unsigned int uc__pad0; /* needed for alignment */ |
51 | struct sigcontext uc_mcontext; /* the 64-bit sigcontext type */ | 51 | struct sigcontext uc_mcontext; /* the 64-bit sigcontext type */ |
52 | compat_sigset_t uc_sigmask; /* mask last for extensibility */ | 52 | compat_sigset_t uc_sigmask; /* mask last for extensibility */ |
53 | }; | 53 | }; |
54 | 54 | ||
55 | /* This matches struct stat64 in glibc2.2, hence the absolutely | 55 | /* This matches struct stat64 in glibc2.2, hence the absolutely |
56 | * insane amounts of padding around dev_t's. | 56 | * insane amounts of padding around dev_t's. |
57 | */ | 57 | */ |
58 | struct stat64 { | 58 | struct stat64 { |
59 | unsigned long long st_dev; | 59 | unsigned long long st_dev; |
60 | unsigned char __pad0[4]; | 60 | unsigned char __pad0[4]; |
61 | 61 | ||
62 | #define STAT64_HAS_BROKEN_ST_INO 1 | 62 | #define STAT64_HAS_BROKEN_ST_INO 1 |
63 | unsigned int __st_ino; | 63 | unsigned int __st_ino; |
64 | 64 | ||
65 | unsigned int st_mode; | 65 | unsigned int st_mode; |
66 | unsigned int st_nlink; | 66 | unsigned int st_nlink; |
67 | 67 | ||
68 | unsigned int st_uid; | 68 | unsigned int st_uid; |
69 | unsigned int st_gid; | 69 | unsigned int st_gid; |
70 | 70 | ||
71 | unsigned long long st_rdev; | 71 | unsigned long long st_rdev; |
72 | unsigned char __pad3[4]; | 72 | unsigned char __pad3[4]; |
73 | 73 | ||
74 | long long st_size; | 74 | long long st_size; |
75 | unsigned int st_blksize; | 75 | unsigned int st_blksize; |
76 | 76 | ||
77 | long long st_blocks;/* Number 512-byte blocks allocated */ | 77 | long long st_blocks;/* Number 512-byte blocks allocated */ |
78 | 78 | ||
79 | unsigned st_atime; | 79 | unsigned st_atime; |
80 | unsigned st_atime_nsec; | 80 | unsigned st_atime_nsec; |
81 | unsigned st_mtime; | 81 | unsigned st_mtime; |
82 | unsigned st_mtime_nsec; | 82 | unsigned st_mtime_nsec; |
83 | unsigned st_ctime; | 83 | unsigned st_ctime; |
84 | unsigned st_ctime_nsec; | 84 | unsigned st_ctime_nsec; |
85 | 85 | ||
86 | unsigned long long st_ino; | 86 | unsigned long long st_ino; |
87 | } __attribute__((packed)); | 87 | } __attribute__((packed)); |
88 | 88 | ||
89 | typedef struct compat_siginfo { | ||
90 | int si_signo; | ||
91 | int si_errno; | ||
92 | int si_code; | ||
93 | |||
94 | union { | ||
95 | int _pad[((128 / sizeof(int)) - 3)]; | ||
96 | |||
97 | /* kill() */ | ||
98 | struct { | ||
99 | unsigned int _pid; /* sender's pid */ | ||
100 | unsigned int _uid; /* sender's uid */ | ||
101 | } _kill; | ||
102 | |||
103 | /* POSIX.1b timers */ | ||
104 | struct { | ||
105 | compat_timer_t _tid; /* timer id */ | ||
106 | int _overrun; /* overrun count */ | ||
107 | compat_sigval_t _sigval; /* same as below */ | ||
108 | int _sys_private; /* not to be passed to user */ | ||
109 | int _overrun_incr; /* amount to add to overrun */ | ||
110 | } _timer; | ||
111 | |||
112 | /* POSIX.1b signals */ | ||
113 | struct { | ||
114 | unsigned int _pid; /* sender's pid */ | ||
115 | unsigned int _uid; /* sender's uid */ | ||
116 | compat_sigval_t _sigval; | ||
117 | } _rt; | ||
118 | |||
119 | /* SIGCHLD */ | ||
120 | struct { | ||
121 | unsigned int _pid; /* which child */ | ||
122 | unsigned int _uid; /* sender's uid */ | ||
123 | int _status; /* exit code */ | ||
124 | compat_clock_t _utime; | ||
125 | compat_clock_t _stime; | ||
126 | } _sigchld; | ||
127 | |||
128 | /* SIGCHLD (x32 version) */ | ||
129 | struct { | ||
130 | unsigned int _pid; /* which child */ | ||
131 | unsigned int _uid; /* sender's uid */ | ||
132 | int _status; /* exit code */ | ||
133 | compat_s64 _utime; | ||
134 | compat_s64 _stime; | ||
135 | } _sigchld_x32; | ||
136 | |||
137 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ | ||
138 | struct { | ||
139 | unsigned int _addr; /* faulting insn/memory ref. */ | ||
140 | } _sigfault; | ||
141 | |||
142 | /* SIGPOLL */ | ||
143 | struct { | ||
144 | int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ | ||
145 | int _fd; | ||
146 | } _sigpoll; | ||
147 | |||
148 | struct { | ||
149 | unsigned int _call_addr; /* calling insn */ | ||
150 | int _syscall; /* triggering system call number */ | ||
151 | unsigned int _arch; /* AUDIT_ARCH_* of syscall */ | ||
152 | } _sigsys; | ||
153 | } _sifields; | ||
154 | } compat_siginfo_t; | ||
155 | |||
156 | #define IA32_STACK_TOP IA32_PAGE_OFFSET | 89 | #define IA32_STACK_TOP IA32_PAGE_OFFSET |
157 | 90 | ||
158 | #ifdef __KERNEL__ | 91 | #ifdef __KERNEL__ |
159 | struct linux_binprm; | 92 | struct linux_binprm; |
160 | extern int ia32_setup_arg_pages(struct linux_binprm *bprm, | 93 | extern int ia32_setup_arg_pages(struct linux_binprm *bprm, |
161 | unsigned long stack_top, int exec_stack); | 94 | unsigned long stack_top, int exec_stack); |
162 | struct mm_struct; | 95 | struct mm_struct; |
163 | extern void ia32_pick_mmap_layout(struct mm_struct *mm); | 96 | extern void ia32_pick_mmap_layout(struct mm_struct *mm); |
164 | 97 | ||
165 | #endif | 98 | #endif |
166 | 99 | ||
167 | #endif /* !CONFIG_IA32_SUPPORT */ | 100 | #endif /* !CONFIG_IA32_SUPPORT */ |
168 | 101 | ||
169 | #endif /* _ASM_X86_IA32_H */ | 102 | #endif /* _ASM_X86_IA32_H */ |
170 | 103 |
include/linux/compat.h
1 | #ifndef _LINUX_COMPAT_H | 1 | #ifndef _LINUX_COMPAT_H |
2 | #define _LINUX_COMPAT_H | 2 | #define _LINUX_COMPAT_H |
3 | /* | 3 | /* |
4 | * These are the type definitions for the architecture specific | 4 | * These are the type definitions for the architecture specific |
5 | * syscall compatibility layer. | 5 | * syscall compatibility layer. |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #ifdef CONFIG_COMPAT | 8 | #ifdef CONFIG_COMPAT |
9 | 9 | ||
10 | #include <linux/stat.h> | 10 | #include <linux/stat.h> |
11 | #include <linux/param.h> /* for HZ */ | 11 | #include <linux/param.h> /* for HZ */ |
12 | #include <linux/sem.h> | 12 | #include <linux/sem.h> |
13 | #include <linux/socket.h> | 13 | #include <linux/socket.h> |
14 | #include <linux/if.h> | 14 | #include <linux/if.h> |
15 | #include <linux/fs.h> | 15 | #include <linux/fs.h> |
16 | #include <linux/aio_abi.h> /* for aio_context_t */ | 16 | #include <linux/aio_abi.h> /* for aio_context_t */ |
17 | 17 | ||
18 | #include <asm/compat.h> | 18 | #include <asm/compat.h> |
19 | #include <asm/siginfo.h> | 19 | #include <asm/siginfo.h> |
20 | #include <asm/signal.h> | 20 | #include <asm/signal.h> |
21 | 21 | ||
22 | #ifndef COMPAT_USE_64BIT_TIME | 22 | #ifndef COMPAT_USE_64BIT_TIME |
23 | #define COMPAT_USE_64BIT_TIME 0 | 23 | #define COMPAT_USE_64BIT_TIME 0 |
24 | #endif | 24 | #endif |
25 | 25 | ||
26 | #define compat_jiffies_to_clock_t(x) \ | 26 | #define compat_jiffies_to_clock_t(x) \ |
27 | (((unsigned long)(x) * COMPAT_USER_HZ) / HZ) | 27 | (((unsigned long)(x) * COMPAT_USER_HZ) / HZ) |
28 | 28 | ||
29 | typedef __compat_uid32_t compat_uid_t; | 29 | typedef __compat_uid32_t compat_uid_t; |
30 | typedef __compat_gid32_t compat_gid_t; | 30 | typedef __compat_gid32_t compat_gid_t; |
31 | 31 | ||
32 | struct compat_sel_arg_struct; | 32 | struct compat_sel_arg_struct; |
33 | struct rusage; | 33 | struct rusage; |
34 | 34 | ||
35 | struct compat_itimerspec { | 35 | struct compat_itimerspec { |
36 | struct compat_timespec it_interval; | 36 | struct compat_timespec it_interval; |
37 | struct compat_timespec it_value; | 37 | struct compat_timespec it_value; |
38 | }; | 38 | }; |
39 | 39 | ||
40 | struct compat_utimbuf { | 40 | struct compat_utimbuf { |
41 | compat_time_t actime; | 41 | compat_time_t actime; |
42 | compat_time_t modtime; | 42 | compat_time_t modtime; |
43 | }; | 43 | }; |
44 | 44 | ||
45 | struct compat_itimerval { | 45 | struct compat_itimerval { |
46 | struct compat_timeval it_interval; | 46 | struct compat_timeval it_interval; |
47 | struct compat_timeval it_value; | 47 | struct compat_timeval it_value; |
48 | }; | 48 | }; |
49 | 49 | ||
50 | struct compat_tms { | 50 | struct compat_tms { |
51 | compat_clock_t tms_utime; | 51 | compat_clock_t tms_utime; |
52 | compat_clock_t tms_stime; | 52 | compat_clock_t tms_stime; |
53 | compat_clock_t tms_cutime; | 53 | compat_clock_t tms_cutime; |
54 | compat_clock_t tms_cstime; | 54 | compat_clock_t tms_cstime; |
55 | }; | 55 | }; |
56 | 56 | ||
57 | struct compat_timex { | 57 | struct compat_timex { |
58 | compat_uint_t modes; | 58 | compat_uint_t modes; |
59 | compat_long_t offset; | 59 | compat_long_t offset; |
60 | compat_long_t freq; | 60 | compat_long_t freq; |
61 | compat_long_t maxerror; | 61 | compat_long_t maxerror; |
62 | compat_long_t esterror; | 62 | compat_long_t esterror; |
63 | compat_int_t status; | 63 | compat_int_t status; |
64 | compat_long_t constant; | 64 | compat_long_t constant; |
65 | compat_long_t precision; | 65 | compat_long_t precision; |
66 | compat_long_t tolerance; | 66 | compat_long_t tolerance; |
67 | struct compat_timeval time; | 67 | struct compat_timeval time; |
68 | compat_long_t tick; | 68 | compat_long_t tick; |
69 | compat_long_t ppsfreq; | 69 | compat_long_t ppsfreq; |
70 | compat_long_t jitter; | 70 | compat_long_t jitter; |
71 | compat_int_t shift; | 71 | compat_int_t shift; |
72 | compat_long_t stabil; | 72 | compat_long_t stabil; |
73 | compat_long_t jitcnt; | 73 | compat_long_t jitcnt; |
74 | compat_long_t calcnt; | 74 | compat_long_t calcnt; |
75 | compat_long_t errcnt; | 75 | compat_long_t errcnt; |
76 | compat_long_t stbcnt; | 76 | compat_long_t stbcnt; |
77 | compat_int_t tai; | 77 | compat_int_t tai; |
78 | 78 | ||
79 | compat_int_t:32; compat_int_t:32; compat_int_t:32; compat_int_t:32; | 79 | compat_int_t:32; compat_int_t:32; compat_int_t:32; compat_int_t:32; |
80 | compat_int_t:32; compat_int_t:32; compat_int_t:32; compat_int_t:32; | 80 | compat_int_t:32; compat_int_t:32; compat_int_t:32; compat_int_t:32; |
81 | compat_int_t:32; compat_int_t:32; compat_int_t:32; | 81 | compat_int_t:32; compat_int_t:32; compat_int_t:32; |
82 | }; | 82 | }; |
83 | 83 | ||
84 | #define _COMPAT_NSIG_WORDS (_COMPAT_NSIG / _COMPAT_NSIG_BPW) | 84 | #define _COMPAT_NSIG_WORDS (_COMPAT_NSIG / _COMPAT_NSIG_BPW) |
85 | 85 | ||
86 | typedef struct { | 86 | typedef struct { |
87 | compat_sigset_word sig[_COMPAT_NSIG_WORDS]; | 87 | compat_sigset_word sig[_COMPAT_NSIG_WORDS]; |
88 | } compat_sigset_t; | 88 | } compat_sigset_t; |
89 | 89 | ||
90 | /* | 90 | /* |
91 | * These functions operate strictly on struct compat_time* | 91 | * These functions operate strictly on struct compat_time* |
92 | */ | 92 | */ |
93 | extern int get_compat_timespec(struct timespec *, | 93 | extern int get_compat_timespec(struct timespec *, |
94 | const struct compat_timespec __user *); | 94 | const struct compat_timespec __user *); |
95 | extern int put_compat_timespec(const struct timespec *, | 95 | extern int put_compat_timespec(const struct timespec *, |
96 | struct compat_timespec __user *); | 96 | struct compat_timespec __user *); |
97 | extern int get_compat_timeval(struct timeval *, | 97 | extern int get_compat_timeval(struct timeval *, |
98 | const struct compat_timeval __user *); | 98 | const struct compat_timeval __user *); |
99 | extern int put_compat_timeval(const struct timeval *, | 99 | extern int put_compat_timeval(const struct timeval *, |
100 | struct compat_timeval __user *); | 100 | struct compat_timeval __user *); |
101 | /* | 101 | /* |
102 | * These functions operate on 32- or 64-bit specs depending on | 102 | * These functions operate on 32- or 64-bit specs depending on |
103 | * COMPAT_USE_64BIT_TIME, hence the void user pointer arguments and the | 103 | * COMPAT_USE_64BIT_TIME, hence the void user pointer arguments and the |
104 | * naming as compat_get/put_ rather than get/put_compat_. | 104 | * naming as compat_get/put_ rather than get/put_compat_. |
105 | */ | 105 | */ |
106 | extern int compat_get_timespec(struct timespec *, const void __user *); | 106 | extern int compat_get_timespec(struct timespec *, const void __user *); |
107 | extern int compat_put_timespec(const struct timespec *, void __user *); | 107 | extern int compat_put_timespec(const struct timespec *, void __user *); |
108 | extern int compat_get_timeval(struct timeval *, const void __user *); | 108 | extern int compat_get_timeval(struct timeval *, const void __user *); |
109 | extern int compat_put_timeval(const struct timeval *, void __user *); | 109 | extern int compat_put_timeval(const struct timeval *, void __user *); |
110 | 110 | ||
111 | struct compat_iovec { | 111 | struct compat_iovec { |
112 | compat_uptr_t iov_base; | 112 | compat_uptr_t iov_base; |
113 | compat_size_t iov_len; | 113 | compat_size_t iov_len; |
114 | }; | 114 | }; |
115 | 115 | ||
116 | struct compat_rlimit { | 116 | struct compat_rlimit { |
117 | compat_ulong_t rlim_cur; | 117 | compat_ulong_t rlim_cur; |
118 | compat_ulong_t rlim_max; | 118 | compat_ulong_t rlim_max; |
119 | }; | 119 | }; |
120 | 120 | ||
121 | struct compat_rusage { | 121 | struct compat_rusage { |
122 | struct compat_timeval ru_utime; | 122 | struct compat_timeval ru_utime; |
123 | struct compat_timeval ru_stime; | 123 | struct compat_timeval ru_stime; |
124 | compat_long_t ru_maxrss; | 124 | compat_long_t ru_maxrss; |
125 | compat_long_t ru_ixrss; | 125 | compat_long_t ru_ixrss; |
126 | compat_long_t ru_idrss; | 126 | compat_long_t ru_idrss; |
127 | compat_long_t ru_isrss; | 127 | compat_long_t ru_isrss; |
128 | compat_long_t ru_minflt; | 128 | compat_long_t ru_minflt; |
129 | compat_long_t ru_majflt; | 129 | compat_long_t ru_majflt; |
130 | compat_long_t ru_nswap; | 130 | compat_long_t ru_nswap; |
131 | compat_long_t ru_inblock; | 131 | compat_long_t ru_inblock; |
132 | compat_long_t ru_oublock; | 132 | compat_long_t ru_oublock; |
133 | compat_long_t ru_msgsnd; | 133 | compat_long_t ru_msgsnd; |
134 | compat_long_t ru_msgrcv; | 134 | compat_long_t ru_msgrcv; |
135 | compat_long_t ru_nsignals; | 135 | compat_long_t ru_nsignals; |
136 | compat_long_t ru_nvcsw; | 136 | compat_long_t ru_nvcsw; |
137 | compat_long_t ru_nivcsw; | 137 | compat_long_t ru_nivcsw; |
138 | }; | 138 | }; |
139 | 139 | ||
140 | extern int put_compat_rusage(const struct rusage *, | 140 | extern int put_compat_rusage(const struct rusage *, |
141 | struct compat_rusage __user *); | 141 | struct compat_rusage __user *); |
142 | 142 | ||
143 | struct compat_siginfo; | 143 | struct compat_siginfo; |
144 | 144 | ||
145 | extern asmlinkage long compat_sys_waitid(int, compat_pid_t, | 145 | extern asmlinkage long compat_sys_waitid(int, compat_pid_t, |
146 | struct compat_siginfo __user *, int, | 146 | struct compat_siginfo __user *, int, |
147 | struct compat_rusage __user *); | 147 | struct compat_rusage __user *); |
148 | 148 | ||
149 | struct compat_dirent { | 149 | struct compat_dirent { |
150 | u32 d_ino; | 150 | u32 d_ino; |
151 | compat_off_t d_off; | 151 | compat_off_t d_off; |
152 | u16 d_reclen; | 152 | u16 d_reclen; |
153 | char d_name[256]; | 153 | char d_name[256]; |
154 | }; | 154 | }; |
155 | 155 | ||
156 | struct compat_ustat { | 156 | struct compat_ustat { |
157 | compat_daddr_t f_tfree; | 157 | compat_daddr_t f_tfree; |
158 | compat_ino_t f_tinode; | 158 | compat_ino_t f_tinode; |
159 | char f_fname[6]; | 159 | char f_fname[6]; |
160 | char f_fpack[6]; | 160 | char f_fpack[6]; |
161 | }; | 161 | }; |
162 | 162 | ||
163 | typedef union compat_sigval { | ||
164 | compat_int_t sival_int; | ||
165 | compat_uptr_t sival_ptr; | ||
166 | } compat_sigval_t; | ||
167 | |||
168 | #define COMPAT_SIGEV_PAD_SIZE ((SIGEV_MAX_SIZE/sizeof(int)) - 3) | 163 | #define COMPAT_SIGEV_PAD_SIZE ((SIGEV_MAX_SIZE/sizeof(int)) - 3) |
169 | 164 | ||
170 | typedef struct compat_sigevent { | 165 | typedef struct compat_sigevent { |
171 | compat_sigval_t sigev_value; | 166 | compat_sigval_t sigev_value; |
172 | compat_int_t sigev_signo; | 167 | compat_int_t sigev_signo; |
173 | compat_int_t sigev_notify; | 168 | compat_int_t sigev_notify; |
174 | union { | 169 | union { |
175 | compat_int_t _pad[COMPAT_SIGEV_PAD_SIZE]; | 170 | compat_int_t _pad[COMPAT_SIGEV_PAD_SIZE]; |
176 | compat_int_t _tid; | 171 | compat_int_t _tid; |
177 | 172 | ||
178 | struct { | 173 | struct { |
179 | compat_uptr_t _function; | 174 | compat_uptr_t _function; |
180 | compat_uptr_t _attribute; | 175 | compat_uptr_t _attribute; |
181 | } _sigev_thread; | 176 | } _sigev_thread; |
182 | } _sigev_un; | 177 | } _sigev_un; |
183 | } compat_sigevent_t; | 178 | } compat_sigevent_t; |
184 | 179 | ||
185 | struct compat_ifmap { | 180 | struct compat_ifmap { |
186 | compat_ulong_t mem_start; | 181 | compat_ulong_t mem_start; |
187 | compat_ulong_t mem_end; | 182 | compat_ulong_t mem_end; |
188 | unsigned short base_addr; | 183 | unsigned short base_addr; |
189 | unsigned char irq; | 184 | unsigned char irq; |
190 | unsigned char dma; | 185 | unsigned char dma; |
191 | unsigned char port; | 186 | unsigned char port; |
192 | }; | 187 | }; |
193 | 188 | ||
194 | struct compat_if_settings { | 189 | struct compat_if_settings { |
195 | unsigned int type; /* Type of physical device or protocol */ | 190 | unsigned int type; /* Type of physical device or protocol */ |
196 | unsigned int size; /* Size of the data allocated by the caller */ | 191 | unsigned int size; /* Size of the data allocated by the caller */ |
197 | compat_uptr_t ifs_ifsu; /* union of pointers */ | 192 | compat_uptr_t ifs_ifsu; /* union of pointers */ |
198 | }; | 193 | }; |
199 | 194 | ||
200 | struct compat_ifreq { | 195 | struct compat_ifreq { |
201 | union { | 196 | union { |
202 | char ifrn_name[IFNAMSIZ]; /* if name, e.g. "en0" */ | 197 | char ifrn_name[IFNAMSIZ]; /* if name, e.g. "en0" */ |
203 | } ifr_ifrn; | 198 | } ifr_ifrn; |
204 | union { | 199 | union { |
205 | struct sockaddr ifru_addr; | 200 | struct sockaddr ifru_addr; |
206 | struct sockaddr ifru_dstaddr; | 201 | struct sockaddr ifru_dstaddr; |
207 | struct sockaddr ifru_broadaddr; | 202 | struct sockaddr ifru_broadaddr; |
208 | struct sockaddr ifru_netmask; | 203 | struct sockaddr ifru_netmask; |
209 | struct sockaddr ifru_hwaddr; | 204 | struct sockaddr ifru_hwaddr; |
210 | short ifru_flags; | 205 | short ifru_flags; |
211 | compat_int_t ifru_ivalue; | 206 | compat_int_t ifru_ivalue; |
212 | compat_int_t ifru_mtu; | 207 | compat_int_t ifru_mtu; |
213 | struct compat_ifmap ifru_map; | 208 | struct compat_ifmap ifru_map; |
214 | char ifru_slave[IFNAMSIZ]; /* Just fits the size */ | 209 | char ifru_slave[IFNAMSIZ]; /* Just fits the size */ |
215 | char ifru_newname[IFNAMSIZ]; | 210 | char ifru_newname[IFNAMSIZ]; |
216 | compat_caddr_t ifru_data; | 211 | compat_caddr_t ifru_data; |
217 | struct compat_if_settings ifru_settings; | 212 | struct compat_if_settings ifru_settings; |
218 | } ifr_ifru; | 213 | } ifr_ifru; |
219 | }; | 214 | }; |
220 | 215 | ||
221 | struct compat_ifconf { | 216 | struct compat_ifconf { |
222 | compat_int_t ifc_len; /* size of buffer */ | 217 | compat_int_t ifc_len; /* size of buffer */ |
223 | compat_caddr_t ifcbuf; | 218 | compat_caddr_t ifcbuf; |
224 | }; | 219 | }; |
225 | 220 | ||
226 | struct compat_robust_list { | 221 | struct compat_robust_list { |
227 | compat_uptr_t next; | 222 | compat_uptr_t next; |
228 | }; | 223 | }; |
229 | 224 | ||
230 | struct compat_robust_list_head { | 225 | struct compat_robust_list_head { |
231 | struct compat_robust_list list; | 226 | struct compat_robust_list list; |
232 | compat_long_t futex_offset; | 227 | compat_long_t futex_offset; |
233 | compat_uptr_t list_op_pending; | 228 | compat_uptr_t list_op_pending; |
234 | }; | 229 | }; |
235 | 230 | ||
236 | struct compat_statfs; | 231 | struct compat_statfs; |
237 | struct compat_statfs64; | 232 | struct compat_statfs64; |
238 | struct compat_old_linux_dirent; | 233 | struct compat_old_linux_dirent; |
239 | struct compat_linux_dirent; | 234 | struct compat_linux_dirent; |
240 | struct linux_dirent64; | 235 | struct linux_dirent64; |
241 | struct compat_msghdr; | 236 | struct compat_msghdr; |
242 | struct compat_mmsghdr; | 237 | struct compat_mmsghdr; |
243 | struct compat_sysinfo; | 238 | struct compat_sysinfo; |
244 | struct compat_sysctl_args; | 239 | struct compat_sysctl_args; |
245 | struct compat_kexec_segment; | 240 | struct compat_kexec_segment; |
246 | struct compat_mq_attr; | 241 | struct compat_mq_attr; |
247 | struct compat_msgbuf; | 242 | struct compat_msgbuf; |
248 | 243 | ||
249 | extern void compat_exit_robust_list(struct task_struct *curr); | 244 | extern void compat_exit_robust_list(struct task_struct *curr); |
250 | 245 | ||
251 | asmlinkage long | 246 | asmlinkage long |
252 | compat_sys_set_robust_list(struct compat_robust_list_head __user *head, | 247 | compat_sys_set_robust_list(struct compat_robust_list_head __user *head, |
253 | compat_size_t len); | 248 | compat_size_t len); |
254 | asmlinkage long | 249 | asmlinkage long |
255 | compat_sys_get_robust_list(int pid, compat_uptr_t __user *head_ptr, | 250 | compat_sys_get_robust_list(int pid, compat_uptr_t __user *head_ptr, |
256 | compat_size_t __user *len_ptr); | 251 | compat_size_t __user *len_ptr); |
257 | 252 | ||
258 | #ifdef CONFIG_ARCH_WANT_OLD_COMPAT_IPC | 253 | #ifdef CONFIG_ARCH_WANT_OLD_COMPAT_IPC |
259 | long compat_sys_semctl(int first, int second, int third, void __user *uptr); | 254 | long compat_sys_semctl(int first, int second, int third, void __user *uptr); |
260 | long compat_sys_msgsnd(int first, int second, int third, void __user *uptr); | 255 | long compat_sys_msgsnd(int first, int second, int third, void __user *uptr); |
261 | long compat_sys_msgrcv(int first, int second, int msgtyp, int third, | 256 | long compat_sys_msgrcv(int first, int second, int msgtyp, int third, |
262 | int version, void __user *uptr); | 257 | int version, void __user *uptr); |
263 | long compat_sys_shmat(int first, int second, compat_uptr_t third, int version, | 258 | long compat_sys_shmat(int first, int second, compat_uptr_t third, int version, |
264 | void __user *uptr); | 259 | void __user *uptr); |
265 | #else | 260 | #else |
266 | long compat_sys_semctl(int semid, int semnum, int cmd, int arg); | 261 | long compat_sys_semctl(int semid, int semnum, int cmd, int arg); |
267 | long compat_sys_msgsnd(int msqid, struct compat_msgbuf __user *msgp, | 262 | long compat_sys_msgsnd(int msqid, struct compat_msgbuf __user *msgp, |
268 | compat_ssize_t msgsz, int msgflg); | 263 | compat_ssize_t msgsz, int msgflg); |
269 | long compat_sys_msgrcv(int msqid, struct compat_msgbuf __user *msgp, | 264 | long compat_sys_msgrcv(int msqid, struct compat_msgbuf __user *msgp, |
270 | compat_ssize_t msgsz, long msgtyp, int msgflg); | 265 | compat_ssize_t msgsz, long msgtyp, int msgflg); |
271 | long compat_sys_shmat(int shmid, compat_uptr_t shmaddr, int shmflg); | 266 | long compat_sys_shmat(int shmid, compat_uptr_t shmaddr, int shmflg); |
272 | #endif | 267 | #endif |
273 | long compat_sys_msgctl(int first, int second, void __user *uptr); | 268 | long compat_sys_msgctl(int first, int second, void __user *uptr); |
274 | long compat_sys_shmctl(int first, int second, void __user *uptr); | 269 | long compat_sys_shmctl(int first, int second, void __user *uptr); |
275 | long compat_sys_semtimedop(int semid, struct sembuf __user *tsems, | 270 | long compat_sys_semtimedop(int semid, struct sembuf __user *tsems, |
276 | unsigned nsems, const struct compat_timespec __user *timeout); | 271 | unsigned nsems, const struct compat_timespec __user *timeout); |
277 | asmlinkage long compat_sys_keyctl(u32 option, | 272 | asmlinkage long compat_sys_keyctl(u32 option, |
278 | u32 arg2, u32 arg3, u32 arg4, u32 arg5); | 273 | u32 arg2, u32 arg3, u32 arg4, u32 arg5); |
279 | asmlinkage long compat_sys_ustat(unsigned dev, struct compat_ustat __user *u32); | 274 | asmlinkage long compat_sys_ustat(unsigned dev, struct compat_ustat __user *u32); |
280 | 275 | ||
281 | asmlinkage ssize_t compat_sys_readv(unsigned long fd, | 276 | asmlinkage ssize_t compat_sys_readv(unsigned long fd, |
282 | const struct compat_iovec __user *vec, unsigned long vlen); | 277 | const struct compat_iovec __user *vec, unsigned long vlen); |
283 | asmlinkage ssize_t compat_sys_writev(unsigned long fd, | 278 | asmlinkage ssize_t compat_sys_writev(unsigned long fd, |
284 | const struct compat_iovec __user *vec, unsigned long vlen); | 279 | const struct compat_iovec __user *vec, unsigned long vlen); |
285 | asmlinkage ssize_t compat_sys_preadv(unsigned long fd, | 280 | asmlinkage ssize_t compat_sys_preadv(unsigned long fd, |
286 | const struct compat_iovec __user *vec, | 281 | const struct compat_iovec __user *vec, |
287 | unsigned long vlen, u32 pos_low, u32 pos_high); | 282 | unsigned long vlen, u32 pos_low, u32 pos_high); |
288 | asmlinkage ssize_t compat_sys_pwritev(unsigned long fd, | 283 | asmlinkage ssize_t compat_sys_pwritev(unsigned long fd, |
289 | const struct compat_iovec __user *vec, | 284 | const struct compat_iovec __user *vec, |
290 | unsigned long vlen, u32 pos_low, u32 pos_high); | 285 | unsigned long vlen, u32 pos_low, u32 pos_high); |
291 | 286 | ||
292 | int compat_do_execve(char *filename, compat_uptr_t __user *argv, | 287 | int compat_do_execve(char *filename, compat_uptr_t __user *argv, |
293 | compat_uptr_t __user *envp, struct pt_regs *regs); | 288 | compat_uptr_t __user *envp, struct pt_regs *regs); |
294 | 289 | ||
295 | asmlinkage long compat_sys_select(int n, compat_ulong_t __user *inp, | 290 | asmlinkage long compat_sys_select(int n, compat_ulong_t __user *inp, |
296 | compat_ulong_t __user *outp, compat_ulong_t __user *exp, | 291 | compat_ulong_t __user *outp, compat_ulong_t __user *exp, |
297 | struct compat_timeval __user *tvp); | 292 | struct compat_timeval __user *tvp); |
298 | 293 | ||
299 | asmlinkage long compat_sys_old_select(struct compat_sel_arg_struct __user *arg); | 294 | asmlinkage long compat_sys_old_select(struct compat_sel_arg_struct __user *arg); |
300 | 295 | ||
301 | asmlinkage long compat_sys_wait4(compat_pid_t pid, | 296 | asmlinkage long compat_sys_wait4(compat_pid_t pid, |
302 | compat_uint_t __user *stat_addr, int options, | 297 | compat_uint_t __user *stat_addr, int options, |
303 | struct compat_rusage __user *ru); | 298 | struct compat_rusage __user *ru); |
304 | 299 | ||
305 | #define BITS_PER_COMPAT_LONG (8*sizeof(compat_long_t)) | 300 | #define BITS_PER_COMPAT_LONG (8*sizeof(compat_long_t)) |
306 | 301 | ||
307 | #define BITS_TO_COMPAT_LONGS(bits) \ | 302 | #define BITS_TO_COMPAT_LONGS(bits) \ |
308 | (((bits)+BITS_PER_COMPAT_LONG-1)/BITS_PER_COMPAT_LONG) | 303 | (((bits)+BITS_PER_COMPAT_LONG-1)/BITS_PER_COMPAT_LONG) |
309 | 304 | ||
310 | long compat_get_bitmap(unsigned long *mask, const compat_ulong_t __user *umask, | 305 | long compat_get_bitmap(unsigned long *mask, const compat_ulong_t __user *umask, |
311 | unsigned long bitmap_size); | 306 | unsigned long bitmap_size); |
312 | long compat_put_bitmap(compat_ulong_t __user *umask, unsigned long *mask, | 307 | long compat_put_bitmap(compat_ulong_t __user *umask, unsigned long *mask, |
313 | unsigned long bitmap_size); | 308 | unsigned long bitmap_size); |
314 | int copy_siginfo_from_user32(siginfo_t *to, struct compat_siginfo __user *from); | 309 | int copy_siginfo_from_user32(siginfo_t *to, struct compat_siginfo __user *from); |
315 | int copy_siginfo_to_user32(struct compat_siginfo __user *to, siginfo_t *from); | 310 | int copy_siginfo_to_user32(struct compat_siginfo __user *to, siginfo_t *from); |
316 | int get_compat_sigevent(struct sigevent *event, | 311 | int get_compat_sigevent(struct sigevent *event, |
317 | const struct compat_sigevent __user *u_event); | 312 | const struct compat_sigevent __user *u_event); |
318 | long compat_sys_rt_tgsigqueueinfo(compat_pid_t tgid, compat_pid_t pid, int sig, | 313 | long compat_sys_rt_tgsigqueueinfo(compat_pid_t tgid, compat_pid_t pid, int sig, |
319 | struct compat_siginfo __user *uinfo); | 314 | struct compat_siginfo __user *uinfo); |
320 | 315 | ||
321 | static inline int compat_timeval_compare(struct compat_timeval *lhs, | 316 | static inline int compat_timeval_compare(struct compat_timeval *lhs, |
322 | struct compat_timeval *rhs) | 317 | struct compat_timeval *rhs) |
323 | { | 318 | { |
324 | if (lhs->tv_sec < rhs->tv_sec) | 319 | if (lhs->tv_sec < rhs->tv_sec) |
325 | return -1; | 320 | return -1; |
326 | if (lhs->tv_sec > rhs->tv_sec) | 321 | if (lhs->tv_sec > rhs->tv_sec) |
327 | return 1; | 322 | return 1; |
328 | return lhs->tv_usec - rhs->tv_usec; | 323 | return lhs->tv_usec - rhs->tv_usec; |
329 | } | 324 | } |
330 | 325 | ||
331 | static inline int compat_timespec_compare(struct compat_timespec *lhs, | 326 | static inline int compat_timespec_compare(struct compat_timespec *lhs, |
332 | struct compat_timespec *rhs) | 327 | struct compat_timespec *rhs) |
333 | { | 328 | { |
334 | if (lhs->tv_sec < rhs->tv_sec) | 329 | if (lhs->tv_sec < rhs->tv_sec) |
335 | return -1; | 330 | return -1; |
336 | if (lhs->tv_sec > rhs->tv_sec) | 331 | if (lhs->tv_sec > rhs->tv_sec) |
337 | return 1; | 332 | return 1; |
338 | return lhs->tv_nsec - rhs->tv_nsec; | 333 | return lhs->tv_nsec - rhs->tv_nsec; |
339 | } | 334 | } |
340 | 335 | ||
341 | extern int get_compat_itimerspec(struct itimerspec *dst, | 336 | extern int get_compat_itimerspec(struct itimerspec *dst, |
342 | const struct compat_itimerspec __user *src); | 337 | const struct compat_itimerspec __user *src); |
343 | extern int put_compat_itimerspec(struct compat_itimerspec __user *dst, | 338 | extern int put_compat_itimerspec(struct compat_itimerspec __user *dst, |
344 | const struct itimerspec *src); | 339 | const struct itimerspec *src); |
345 | 340 | ||
346 | asmlinkage long compat_sys_gettimeofday(struct compat_timeval __user *tv, | 341 | asmlinkage long compat_sys_gettimeofday(struct compat_timeval __user *tv, |
347 | struct timezone __user *tz); | 342 | struct timezone __user *tz); |
348 | asmlinkage long compat_sys_settimeofday(struct compat_timeval __user *tv, | 343 | asmlinkage long compat_sys_settimeofday(struct compat_timeval __user *tv, |
349 | struct timezone __user *tz); | 344 | struct timezone __user *tz); |
350 | 345 | ||
351 | asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp); | 346 | asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp); |
352 | 347 | ||
353 | extern int compat_printk(const char *fmt, ...); | 348 | extern int compat_printk(const char *fmt, ...); |
354 | extern void sigset_from_compat(sigset_t *set, compat_sigset_t *compat); | 349 | extern void sigset_from_compat(sigset_t *set, compat_sigset_t *compat); |
355 | 350 | ||
356 | asmlinkage long compat_sys_migrate_pages(compat_pid_t pid, | 351 | asmlinkage long compat_sys_migrate_pages(compat_pid_t pid, |
357 | compat_ulong_t maxnode, const compat_ulong_t __user *old_nodes, | 352 | compat_ulong_t maxnode, const compat_ulong_t __user *old_nodes, |
358 | const compat_ulong_t __user *new_nodes); | 353 | const compat_ulong_t __user *new_nodes); |
359 | 354 | ||
360 | extern int compat_ptrace_request(struct task_struct *child, | 355 | extern int compat_ptrace_request(struct task_struct *child, |
361 | compat_long_t request, | 356 | compat_long_t request, |
362 | compat_ulong_t addr, compat_ulong_t data); | 357 | compat_ulong_t addr, compat_ulong_t data); |
363 | 358 | ||
364 | extern long compat_arch_ptrace(struct task_struct *child, compat_long_t request, | 359 | extern long compat_arch_ptrace(struct task_struct *child, compat_long_t request, |
365 | compat_ulong_t addr, compat_ulong_t data); | 360 | compat_ulong_t addr, compat_ulong_t data); |
366 | asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid, | 361 | asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid, |
367 | compat_long_t addr, compat_long_t data); | 362 | compat_long_t addr, compat_long_t data); |
368 | 363 | ||
369 | /* | 364 | /* |
370 | * epoll (fs/eventpoll.c) compat bits follow ... | 365 | * epoll (fs/eventpoll.c) compat bits follow ... |
371 | */ | 366 | */ |
372 | struct epoll_event; | 367 | struct epoll_event; |
373 | #define compat_epoll_event epoll_event | 368 | #define compat_epoll_event epoll_event |
374 | asmlinkage long compat_sys_epoll_pwait(int epfd, | 369 | asmlinkage long compat_sys_epoll_pwait(int epfd, |
375 | struct compat_epoll_event __user *events, | 370 | struct compat_epoll_event __user *events, |
376 | int maxevents, int timeout, | 371 | int maxevents, int timeout, |
377 | const compat_sigset_t __user *sigmask, | 372 | const compat_sigset_t __user *sigmask, |
378 | compat_size_t sigsetsize); | 373 | compat_size_t sigsetsize); |
379 | 374 | ||
380 | asmlinkage long compat_sys_utime(const char __user *filename, | 375 | asmlinkage long compat_sys_utime(const char __user *filename, |
381 | struct compat_utimbuf __user *t); | 376 | struct compat_utimbuf __user *t); |
382 | asmlinkage long compat_sys_utimensat(unsigned int dfd, | 377 | asmlinkage long compat_sys_utimensat(unsigned int dfd, |
383 | const char __user *filename, | 378 | const char __user *filename, |
384 | struct compat_timespec __user *t, | 379 | struct compat_timespec __user *t, |
385 | int flags); | 380 | int flags); |
386 | 381 | ||
387 | asmlinkage long compat_sys_time(compat_time_t __user *tloc); | 382 | asmlinkage long compat_sys_time(compat_time_t __user *tloc); |
388 | asmlinkage long compat_sys_stime(compat_time_t __user *tptr); | 383 | asmlinkage long compat_sys_stime(compat_time_t __user *tptr); |
389 | asmlinkage long compat_sys_signalfd(int ufd, | 384 | asmlinkage long compat_sys_signalfd(int ufd, |
390 | const compat_sigset_t __user *sigmask, | 385 | const compat_sigset_t __user *sigmask, |
391 | compat_size_t sigsetsize); | 386 | compat_size_t sigsetsize); |
392 | asmlinkage long compat_sys_timerfd_settime(int ufd, int flags, | 387 | asmlinkage long compat_sys_timerfd_settime(int ufd, int flags, |
393 | const struct compat_itimerspec __user *utmr, | 388 | const struct compat_itimerspec __user *utmr, |
394 | struct compat_itimerspec __user *otmr); | 389 | struct compat_itimerspec __user *otmr); |
395 | asmlinkage long compat_sys_timerfd_gettime(int ufd, | 390 | asmlinkage long compat_sys_timerfd_gettime(int ufd, |
396 | struct compat_itimerspec __user *otmr); | 391 | struct compat_itimerspec __user *otmr); |
397 | 392 | ||
398 | asmlinkage long compat_sys_move_pages(pid_t pid, unsigned long nr_page, | 393 | asmlinkage long compat_sys_move_pages(pid_t pid, unsigned long nr_page, |
399 | __u32 __user *pages, | 394 | __u32 __user *pages, |
400 | const int __user *nodes, | 395 | const int __user *nodes, |
401 | int __user *status, | 396 | int __user *status, |
402 | int flags); | 397 | int flags); |
403 | asmlinkage long compat_sys_futimesat(unsigned int dfd, | 398 | asmlinkage long compat_sys_futimesat(unsigned int dfd, |
404 | const char __user *filename, | 399 | const char __user *filename, |
405 | struct compat_timeval __user *t); | 400 | struct compat_timeval __user *t); |
406 | asmlinkage long compat_sys_utimes(const char __user *filename, | 401 | asmlinkage long compat_sys_utimes(const char __user *filename, |
407 | struct compat_timeval __user *t); | 402 | struct compat_timeval __user *t); |
408 | asmlinkage long compat_sys_newstat(const char __user *filename, | 403 | asmlinkage long compat_sys_newstat(const char __user *filename, |
409 | struct compat_stat __user *statbuf); | 404 | struct compat_stat __user *statbuf); |
410 | asmlinkage long compat_sys_newlstat(const char __user *filename, | 405 | asmlinkage long compat_sys_newlstat(const char __user *filename, |
411 | struct compat_stat __user *statbuf); | 406 | struct compat_stat __user *statbuf); |
412 | asmlinkage long compat_sys_newfstatat(unsigned int dfd, | 407 | asmlinkage long compat_sys_newfstatat(unsigned int dfd, |
413 | const char __user *filename, | 408 | const char __user *filename, |
414 | struct compat_stat __user *statbuf, | 409 | struct compat_stat __user *statbuf, |
415 | int flag); | 410 | int flag); |
416 | asmlinkage long compat_sys_newfstat(unsigned int fd, | 411 | asmlinkage long compat_sys_newfstat(unsigned int fd, |
417 | struct compat_stat __user *statbuf); | 412 | struct compat_stat __user *statbuf); |
418 | asmlinkage long compat_sys_statfs(const char __user *pathname, | 413 | asmlinkage long compat_sys_statfs(const char __user *pathname, |
419 | struct compat_statfs __user *buf); | 414 | struct compat_statfs __user *buf); |
420 | asmlinkage long compat_sys_fstatfs(unsigned int fd, | 415 | asmlinkage long compat_sys_fstatfs(unsigned int fd, |
421 | struct compat_statfs __user *buf); | 416 | struct compat_statfs __user *buf); |
422 | asmlinkage long compat_sys_statfs64(const char __user *pathname, | 417 | asmlinkage long compat_sys_statfs64(const char __user *pathname, |
423 | compat_size_t sz, | 418 | compat_size_t sz, |
424 | struct compat_statfs64 __user *buf); | 419 | struct compat_statfs64 __user *buf); |
425 | asmlinkage long compat_sys_fstatfs64(unsigned int fd, compat_size_t sz, | 420 | asmlinkage long compat_sys_fstatfs64(unsigned int fd, compat_size_t sz, |
426 | struct compat_statfs64 __user *buf); | 421 | struct compat_statfs64 __user *buf); |
427 | asmlinkage long compat_sys_fcntl64(unsigned int fd, unsigned int cmd, | 422 | asmlinkage long compat_sys_fcntl64(unsigned int fd, unsigned int cmd, |
428 | unsigned long arg); | 423 | unsigned long arg); |
429 | asmlinkage long compat_sys_fcntl(unsigned int fd, unsigned int cmd, | 424 | asmlinkage long compat_sys_fcntl(unsigned int fd, unsigned int cmd, |
430 | unsigned long arg); | 425 | unsigned long arg); |
431 | asmlinkage long compat_sys_io_setup(unsigned nr_reqs, u32 __user *ctx32p); | 426 | asmlinkage long compat_sys_io_setup(unsigned nr_reqs, u32 __user *ctx32p); |
432 | asmlinkage long compat_sys_io_getevents(aio_context_t ctx_id, | 427 | asmlinkage long compat_sys_io_getevents(aio_context_t ctx_id, |
433 | unsigned long min_nr, | 428 | unsigned long min_nr, |
434 | unsigned long nr, | 429 | unsigned long nr, |
435 | struct io_event __user *events, | 430 | struct io_event __user *events, |
436 | struct compat_timespec __user *timeout); | 431 | struct compat_timespec __user *timeout); |
437 | asmlinkage long compat_sys_io_submit(aio_context_t ctx_id, int nr, | 432 | asmlinkage long compat_sys_io_submit(aio_context_t ctx_id, int nr, |
438 | u32 __user *iocb); | 433 | u32 __user *iocb); |
439 | asmlinkage long compat_sys_mount(const char __user *dev_name, | 434 | asmlinkage long compat_sys_mount(const char __user *dev_name, |
440 | const char __user *dir_name, | 435 | const char __user *dir_name, |
441 | const char __user *type, unsigned long flags, | 436 | const char __user *type, unsigned long flags, |
442 | const void __user *data); | 437 | const void __user *data); |
443 | asmlinkage long compat_sys_old_readdir(unsigned int fd, | 438 | asmlinkage long compat_sys_old_readdir(unsigned int fd, |
444 | struct compat_old_linux_dirent __user *, | 439 | struct compat_old_linux_dirent __user *, |
445 | unsigned int count); | 440 | unsigned int count); |
446 | asmlinkage long compat_sys_getdents(unsigned int fd, | 441 | asmlinkage long compat_sys_getdents(unsigned int fd, |
447 | struct compat_linux_dirent __user *dirent, | 442 | struct compat_linux_dirent __user *dirent, |
448 | unsigned int count); | 443 | unsigned int count); |
449 | asmlinkage long compat_sys_getdents64(unsigned int fd, | 444 | asmlinkage long compat_sys_getdents64(unsigned int fd, |
450 | struct linux_dirent64 __user *dirent, | 445 | struct linux_dirent64 __user *dirent, |
451 | unsigned int count); | 446 | unsigned int count); |
452 | asmlinkage long compat_sys_vmsplice(int fd, const struct compat_iovec __user *, | 447 | asmlinkage long compat_sys_vmsplice(int fd, const struct compat_iovec __user *, |
453 | unsigned int nr_segs, unsigned int flags); | 448 | unsigned int nr_segs, unsigned int flags); |
454 | asmlinkage long compat_sys_open(const char __user *filename, int flags, | 449 | asmlinkage long compat_sys_open(const char __user *filename, int flags, |
455 | umode_t mode); | 450 | umode_t mode); |
456 | asmlinkage long compat_sys_openat(unsigned int dfd, const char __user *filename, | 451 | asmlinkage long compat_sys_openat(unsigned int dfd, const char __user *filename, |
457 | int flags, umode_t mode); | 452 | int flags, umode_t mode); |
458 | asmlinkage long compat_sys_open_by_handle_at(int mountdirfd, | 453 | asmlinkage long compat_sys_open_by_handle_at(int mountdirfd, |
459 | struct file_handle __user *handle, | 454 | struct file_handle __user *handle, |
460 | int flags); | 455 | int flags); |
461 | asmlinkage long compat_sys_pselect6(int n, compat_ulong_t __user *inp, | 456 | asmlinkage long compat_sys_pselect6(int n, compat_ulong_t __user *inp, |
462 | compat_ulong_t __user *outp, | 457 | compat_ulong_t __user *outp, |
463 | compat_ulong_t __user *exp, | 458 | compat_ulong_t __user *exp, |
464 | struct compat_timespec __user *tsp, | 459 | struct compat_timespec __user *tsp, |
465 | void __user *sig); | 460 | void __user *sig); |
466 | asmlinkage long compat_sys_ppoll(struct pollfd __user *ufds, | 461 | asmlinkage long compat_sys_ppoll(struct pollfd __user *ufds, |
467 | unsigned int nfds, | 462 | unsigned int nfds, |
468 | struct compat_timespec __user *tsp, | 463 | struct compat_timespec __user *tsp, |
469 | const compat_sigset_t __user *sigmask, | 464 | const compat_sigset_t __user *sigmask, |
470 | compat_size_t sigsetsize); | 465 | compat_size_t sigsetsize); |
471 | asmlinkage long compat_sys_signalfd4(int ufd, | 466 | asmlinkage long compat_sys_signalfd4(int ufd, |
472 | const compat_sigset_t __user *sigmask, | 467 | const compat_sigset_t __user *sigmask, |
473 | compat_size_t sigsetsize, int flags); | 468 | compat_size_t sigsetsize, int flags); |
474 | asmlinkage long compat_sys_get_mempolicy(int __user *policy, | 469 | asmlinkage long compat_sys_get_mempolicy(int __user *policy, |
475 | compat_ulong_t __user *nmask, | 470 | compat_ulong_t __user *nmask, |
476 | compat_ulong_t maxnode, | 471 | compat_ulong_t maxnode, |
477 | compat_ulong_t addr, | 472 | compat_ulong_t addr, |
478 | compat_ulong_t flags); | 473 | compat_ulong_t flags); |
479 | asmlinkage long compat_sys_set_mempolicy(int mode, compat_ulong_t __user *nmask, | 474 | asmlinkage long compat_sys_set_mempolicy(int mode, compat_ulong_t __user *nmask, |
480 | compat_ulong_t maxnode); | 475 | compat_ulong_t maxnode); |
481 | asmlinkage long compat_sys_mbind(compat_ulong_t start, compat_ulong_t len, | 476 | asmlinkage long compat_sys_mbind(compat_ulong_t start, compat_ulong_t len, |
482 | compat_ulong_t mode, | 477 | compat_ulong_t mode, |
483 | compat_ulong_t __user *nmask, | 478 | compat_ulong_t __user *nmask, |
484 | compat_ulong_t maxnode, compat_ulong_t flags); | 479 | compat_ulong_t maxnode, compat_ulong_t flags); |
485 | 480 | ||
486 | asmlinkage long compat_sys_setsockopt(int fd, int level, int optname, | 481 | asmlinkage long compat_sys_setsockopt(int fd, int level, int optname, |
487 | char __user *optval, unsigned int optlen); | 482 | char __user *optval, unsigned int optlen); |
488 | asmlinkage long compat_sys_sendmsg(int fd, struct compat_msghdr __user *msg, | 483 | asmlinkage long compat_sys_sendmsg(int fd, struct compat_msghdr __user *msg, |
489 | unsigned flags); | 484 | unsigned flags); |
490 | asmlinkage long compat_sys_sendmmsg(int fd, struct compat_mmsghdr __user *mmsg, | 485 | asmlinkage long compat_sys_sendmmsg(int fd, struct compat_mmsghdr __user *mmsg, |
491 | unsigned vlen, unsigned int flags); | 486 | unsigned vlen, unsigned int flags); |
492 | asmlinkage long compat_sys_recvmsg(int fd, struct compat_msghdr __user *msg, | 487 | asmlinkage long compat_sys_recvmsg(int fd, struct compat_msghdr __user *msg, |
493 | unsigned int flags); | 488 | unsigned int flags); |
494 | asmlinkage long compat_sys_recv(int fd, void __user *buf, size_t len, | 489 | asmlinkage long compat_sys_recv(int fd, void __user *buf, size_t len, |
495 | unsigned flags); | 490 | unsigned flags); |
496 | asmlinkage long compat_sys_recvfrom(int fd, void __user *buf, size_t len, | 491 | asmlinkage long compat_sys_recvfrom(int fd, void __user *buf, size_t len, |
497 | unsigned flags, struct sockaddr __user *addr, | 492 | unsigned flags, struct sockaddr __user *addr, |
498 | int __user *addrlen); | 493 | int __user *addrlen); |
499 | asmlinkage long compat_sys_recvmmsg(int fd, struct compat_mmsghdr __user *mmsg, | 494 | asmlinkage long compat_sys_recvmmsg(int fd, struct compat_mmsghdr __user *mmsg, |
500 | unsigned vlen, unsigned int flags, | 495 | unsigned vlen, unsigned int flags, |
501 | struct compat_timespec __user *timeout); | 496 | struct compat_timespec __user *timeout); |
502 | asmlinkage long compat_sys_nanosleep(struct compat_timespec __user *rqtp, | 497 | asmlinkage long compat_sys_nanosleep(struct compat_timespec __user *rqtp, |
503 | struct compat_timespec __user *rmtp); | 498 | struct compat_timespec __user *rmtp); |
504 | asmlinkage long compat_sys_getitimer(int which, | 499 | asmlinkage long compat_sys_getitimer(int which, |
505 | struct compat_itimerval __user *it); | 500 | struct compat_itimerval __user *it); |
506 | asmlinkage long compat_sys_setitimer(int which, | 501 | asmlinkage long compat_sys_setitimer(int which, |
507 | struct compat_itimerval __user *in, | 502 | struct compat_itimerval __user *in, |
508 | struct compat_itimerval __user *out); | 503 | struct compat_itimerval __user *out); |
509 | asmlinkage long compat_sys_times(struct compat_tms __user *tbuf); | 504 | asmlinkage long compat_sys_times(struct compat_tms __user *tbuf); |
510 | asmlinkage long compat_sys_setrlimit(unsigned int resource, | 505 | asmlinkage long compat_sys_setrlimit(unsigned int resource, |
511 | struct compat_rlimit __user *rlim); | 506 | struct compat_rlimit __user *rlim); |
512 | asmlinkage long compat_sys_getrlimit(unsigned int resource, | 507 | asmlinkage long compat_sys_getrlimit(unsigned int resource, |
513 | struct compat_rlimit __user *rlim); | 508 | struct compat_rlimit __user *rlim); |
514 | asmlinkage long compat_sys_getrusage(int who, struct compat_rusage __user *ru); | 509 | asmlinkage long compat_sys_getrusage(int who, struct compat_rusage __user *ru); |
515 | asmlinkage long compat_sys_sched_setaffinity(compat_pid_t pid, | 510 | asmlinkage long compat_sys_sched_setaffinity(compat_pid_t pid, |
516 | unsigned int len, | 511 | unsigned int len, |
517 | compat_ulong_t __user *user_mask_ptr); | 512 | compat_ulong_t __user *user_mask_ptr); |
518 | asmlinkage long compat_sys_sched_getaffinity(compat_pid_t pid, | 513 | asmlinkage long compat_sys_sched_getaffinity(compat_pid_t pid, |
519 | unsigned int len, | 514 | unsigned int len, |
520 | compat_ulong_t __user *user_mask_ptr); | 515 | compat_ulong_t __user *user_mask_ptr); |
521 | asmlinkage long compat_sys_timer_create(clockid_t which_clock, | 516 | asmlinkage long compat_sys_timer_create(clockid_t which_clock, |
522 | struct compat_sigevent __user *timer_event_spec, | 517 | struct compat_sigevent __user *timer_event_spec, |
523 | timer_t __user *created_timer_id); | 518 | timer_t __user *created_timer_id); |
524 | asmlinkage long compat_sys_timer_settime(timer_t timer_id, int flags, | 519 | asmlinkage long compat_sys_timer_settime(timer_t timer_id, int flags, |
525 | struct compat_itimerspec __user *new, | 520 | struct compat_itimerspec __user *new, |
526 | struct compat_itimerspec __user *old); | 521 | struct compat_itimerspec __user *old); |
527 | asmlinkage long compat_sys_timer_gettime(timer_t timer_id, | 522 | asmlinkage long compat_sys_timer_gettime(timer_t timer_id, |
528 | struct compat_itimerspec __user *setting); | 523 | struct compat_itimerspec __user *setting); |
529 | asmlinkage long compat_sys_clock_settime(clockid_t which_clock, | 524 | asmlinkage long compat_sys_clock_settime(clockid_t which_clock, |
530 | struct compat_timespec __user *tp); | 525 | struct compat_timespec __user *tp); |
531 | asmlinkage long compat_sys_clock_gettime(clockid_t which_clock, | 526 | asmlinkage long compat_sys_clock_gettime(clockid_t which_clock, |
532 | struct compat_timespec __user *tp); | 527 | struct compat_timespec __user *tp); |
533 | asmlinkage long compat_sys_clock_adjtime(clockid_t which_clock, | 528 | asmlinkage long compat_sys_clock_adjtime(clockid_t which_clock, |
534 | struct compat_timex __user *tp); | 529 | struct compat_timex __user *tp); |
535 | asmlinkage long compat_sys_clock_getres(clockid_t which_clock, | 530 | asmlinkage long compat_sys_clock_getres(clockid_t which_clock, |
536 | struct compat_timespec __user *tp); | 531 | struct compat_timespec __user *tp); |
537 | asmlinkage long compat_sys_clock_nanosleep(clockid_t which_clock, int flags, | 532 | asmlinkage long compat_sys_clock_nanosleep(clockid_t which_clock, int flags, |
538 | struct compat_timespec __user *rqtp, | 533 | struct compat_timespec __user *rqtp, |
539 | struct compat_timespec __user *rmtp); | 534 | struct compat_timespec __user *rmtp); |
540 | asmlinkage long compat_sys_rt_sigtimedwait(compat_sigset_t __user *uthese, | 535 | asmlinkage long compat_sys_rt_sigtimedwait(compat_sigset_t __user *uthese, |
541 | struct compat_siginfo __user *uinfo, | 536 | struct compat_siginfo __user *uinfo, |
542 | struct compat_timespec __user *uts, compat_size_t sigsetsize); | 537 | struct compat_timespec __user *uts, compat_size_t sigsetsize); |
543 | asmlinkage long compat_sys_rt_sigsuspend(compat_sigset_t __user *unewset, | 538 | asmlinkage long compat_sys_rt_sigsuspend(compat_sigset_t __user *unewset, |
544 | compat_size_t sigsetsize); | 539 | compat_size_t sigsetsize); |
545 | asmlinkage long compat_sys_sysinfo(struct compat_sysinfo __user *info); | 540 | asmlinkage long compat_sys_sysinfo(struct compat_sysinfo __user *info); |
546 | asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd, | 541 | asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd, |
547 | unsigned long arg); | 542 | unsigned long arg); |
548 | asmlinkage long compat_sys_futex(u32 __user *uaddr, int op, u32 val, | 543 | asmlinkage long compat_sys_futex(u32 __user *uaddr, int op, u32 val, |
549 | struct compat_timespec __user *utime, u32 __user *uaddr2, | 544 | struct compat_timespec __user *utime, u32 __user *uaddr2, |
550 | u32 val3); | 545 | u32 val3); |
551 | asmlinkage long compat_sys_getsockopt(int fd, int level, int optname, | 546 | asmlinkage long compat_sys_getsockopt(int fd, int level, int optname, |
552 | char __user *optval, int __user *optlen); | 547 | char __user *optval, int __user *optlen); |
553 | asmlinkage long compat_sys_kexec_load(unsigned long entry, | 548 | asmlinkage long compat_sys_kexec_load(unsigned long entry, |
554 | unsigned long nr_segments, | 549 | unsigned long nr_segments, |
555 | struct compat_kexec_segment __user *, | 550 | struct compat_kexec_segment __user *, |
556 | unsigned long flags); | 551 | unsigned long flags); |
557 | asmlinkage long compat_sys_mq_getsetattr(mqd_t mqdes, | 552 | asmlinkage long compat_sys_mq_getsetattr(mqd_t mqdes, |
558 | const struct compat_mq_attr __user *u_mqstat, | 553 | const struct compat_mq_attr __user *u_mqstat, |
559 | struct compat_mq_attr __user *u_omqstat); | 554 | struct compat_mq_attr __user *u_omqstat); |
560 | asmlinkage long compat_sys_mq_notify(mqd_t mqdes, | 555 | asmlinkage long compat_sys_mq_notify(mqd_t mqdes, |
561 | const struct compat_sigevent __user *u_notification); | 556 | const struct compat_sigevent __user *u_notification); |
562 | asmlinkage long compat_sys_mq_open(const char __user *u_name, | 557 | asmlinkage long compat_sys_mq_open(const char __user *u_name, |
563 | int oflag, compat_mode_t mode, | 558 | int oflag, compat_mode_t mode, |
564 | struct compat_mq_attr __user *u_attr); | 559 | struct compat_mq_attr __user *u_attr); |
565 | asmlinkage long compat_sys_mq_timedsend(mqd_t mqdes, | 560 | asmlinkage long compat_sys_mq_timedsend(mqd_t mqdes, |
566 | const char __user *u_msg_ptr, | 561 | const char __user *u_msg_ptr, |
567 | size_t msg_len, unsigned int msg_prio, | 562 | size_t msg_len, unsigned int msg_prio, |
568 | const struct compat_timespec __user *u_abs_timeout); | 563 | const struct compat_timespec __user *u_abs_timeout); |
569 | asmlinkage ssize_t compat_sys_mq_timedreceive(mqd_t mqdes, | 564 | asmlinkage ssize_t compat_sys_mq_timedreceive(mqd_t mqdes, |
570 | char __user *u_msg_ptr, | 565 | char __user *u_msg_ptr, |
571 | size_t msg_len, unsigned int __user *u_msg_prio, | 566 | size_t msg_len, unsigned int __user *u_msg_prio, |
572 | const struct compat_timespec __user *u_abs_timeout); | 567 | const struct compat_timespec __user *u_abs_timeout); |
573 | asmlinkage long compat_sys_socketcall(int call, u32 __user *args); | 568 | asmlinkage long compat_sys_socketcall(int call, u32 __user *args); |
574 | asmlinkage long compat_sys_sysctl(struct compat_sysctl_args __user *args); | 569 | asmlinkage long compat_sys_sysctl(struct compat_sysctl_args __user *args); |
575 | 570 | ||
576 | extern ssize_t compat_rw_copy_check_uvector(int type, | 571 | extern ssize_t compat_rw_copy_check_uvector(int type, |
577 | const struct compat_iovec __user *uvector, | 572 | const struct compat_iovec __user *uvector, |
578 | unsigned long nr_segs, | 573 | unsigned long nr_segs, |
579 | unsigned long fast_segs, struct iovec *fast_pointer, | 574 | unsigned long fast_segs, struct iovec *fast_pointer, |
580 | struct iovec **ret_pointer); | 575 | struct iovec **ret_pointer); |
581 | 576 | ||
582 | extern void __user *compat_alloc_user_space(unsigned long len); | 577 | extern void __user *compat_alloc_user_space(unsigned long len); |
583 | 578 | ||
584 | asmlinkage ssize_t compat_sys_process_vm_readv(compat_pid_t pid, | 579 | asmlinkage ssize_t compat_sys_process_vm_readv(compat_pid_t pid, |
585 | const struct compat_iovec __user *lvec, | 580 | const struct compat_iovec __user *lvec, |
586 | unsigned long liovcnt, const struct compat_iovec __user *rvec, | 581 | unsigned long liovcnt, const struct compat_iovec __user *rvec, |
587 | unsigned long riovcnt, unsigned long flags); | 582 | unsigned long riovcnt, unsigned long flags); |
588 | asmlinkage ssize_t compat_sys_process_vm_writev(compat_pid_t pid, | 583 | asmlinkage ssize_t compat_sys_process_vm_writev(compat_pid_t pid, |
589 | const struct compat_iovec __user *lvec, | 584 | const struct compat_iovec __user *lvec, |
590 | unsigned long liovcnt, const struct compat_iovec __user *rvec, | 585 | unsigned long liovcnt, const struct compat_iovec __user *rvec, |
591 | unsigned long riovcnt, unsigned long flags); | 586 | unsigned long riovcnt, unsigned long flags); |
592 | 587 | ||
593 | asmlinkage long compat_sys_sendfile(int out_fd, int in_fd, | 588 | asmlinkage long compat_sys_sendfile(int out_fd, int in_fd, |
594 | compat_off_t __user *offset, compat_size_t count); | 589 | compat_off_t __user *offset, compat_size_t count); |
595 | 590 | ||
596 | #else | 591 | #else |
597 | 592 | ||
598 | #define is_compat_task() (0) | 593 | #define is_compat_task() (0) |
599 | 594 | ||
600 | #endif /* CONFIG_COMPAT */ | 595 | #endif /* CONFIG_COMPAT */ |
601 | #endif /* _LINUX_COMPAT_H */ | 596 | #endif /* _LINUX_COMPAT_H */ |
602 | 597 |