]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blame - arch/s390/kernel/compat_signal.c
s390: fix save and restore of the floating-point-control register
[mirror_ubuntu-zesty-kernel.git] / arch / s390 / kernel / compat_signal.c
CommitLineData
1da177e4 1/*
a53c8fab 2 * Copyright IBM Corp. 2000, 2006
1da177e4
LT
3 * Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
4 * Gerhard Tonn (ton@de.ibm.com)
5 *
6 * Copyright (C) 1991, 1992 Linus Torvalds
7 *
8 * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson
9 */
10
1da177e4
LT
11#include <linux/compat.h>
12#include <linux/sched.h>
13#include <linux/mm.h>
14#include <linux/smp.h>
1da177e4
LT
15#include <linux/kernel.h>
16#include <linux/signal.h>
17#include <linux/errno.h>
18#include <linux/wait.h>
19#include <linux/ptrace.h>
20#include <linux/unistd.h>
21#include <linux/stddef.h>
22#include <linux/tty.h>
23#include <linux/personality.h>
24#include <linux/binfmts.h>
25#include <asm/ucontext.h>
26#include <asm/uaccess.h>
27#include <asm/lowcore.h>
a0616cde 28#include <asm/switch_to.h>
1da177e4
LT
29#include "compat_linux.h"
30#include "compat_ptrace.h"
a806170e 31#include "entry.h"
1da177e4 32
1da177e4
LT
33typedef struct
34{
35 __u8 callee_used_stack[__SIGNAL_FRAMESIZE32];
36 struct sigcontext32 sc;
37 _sigregs32 sregs;
38 int signo;
ea2a4d3a 39 __u32 gprs_high[NUM_GPRS];
1da177e4
LT
40 __u8 retcode[S390_SYSCALL_SIZE];
41} sigframe32;
42
43typedef struct
44{
45 __u8 callee_used_stack[__SIGNAL_FRAMESIZE32];
46 __u8 retcode[S390_SYSCALL_SIZE];
47 compat_siginfo_t info;
48 struct ucontext32 uc;
ea2a4d3a 49 __u32 gprs_high[NUM_GPRS];
1da177e4
LT
50} rt_sigframe32;
51
1da177e4
LT
52int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
53{
54 int err;
55
1da177e4
LT
56 /* If you change siginfo_t structure, please be sure
57 this code is fixed accordingly.
58 It should never copy any pad contained in the structure
59 to avoid security leaks, but must copy the generic
60 3 ints plus the relevant union member.
61 This routine must convert siginfo from 64bit to 32bit as well
62 at the same time. */
63 err = __put_user(from->si_signo, &to->si_signo);
64 err |= __put_user(from->si_errno, &to->si_errno);
65 err |= __put_user((short)from->si_code, &to->si_code);
66 if (from->si_code < 0)
67 err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
68 else {
69 switch (from->si_code >> 16) {
70 case __SI_RT >> 16: /* This is not generated by the kernel as of now. */
71 case __SI_MESGQ >> 16:
72 err |= __put_user(from->si_int, &to->si_int);
73 /* fallthrough */
74 case __SI_KILL >> 16:
75 err |= __put_user(from->si_pid, &to->si_pid);
76 err |= __put_user(from->si_uid, &to->si_uid);
77 break;
78 case __SI_CHLD >> 16:
79 err |= __put_user(from->si_pid, &to->si_pid);
80 err |= __put_user(from->si_uid, &to->si_uid);
81 err |= __put_user(from->si_utime, &to->si_utime);
82 err |= __put_user(from->si_stime, &to->si_stime);
83 err |= __put_user(from->si_status, &to->si_status);
84 break;
85 case __SI_FAULT >> 16:
86 err |= __put_user((unsigned long) from->si_addr,
87 &to->si_addr);
88 break;
89 case __SI_POLL >> 16:
90 err |= __put_user(from->si_band, &to->si_band);
91 err |= __put_user(from->si_fd, &to->si_fd);
92 break;
93 case __SI_TIMER >> 16:
94 err |= __put_user(from->si_tid, &to->si_tid);
95 err |= __put_user(from->si_overrun, &to->si_overrun);
96 err |= __put_user(from->si_int, &to->si_int);
97 break;
98 default:
99 break;
100 }
101 }
0ebfd313 102 return err ? -EFAULT : 0;
1da177e4
LT
103}
104
105int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
106{
107 int err;
108 u32 tmp;
109
1da177e4
LT
110 err = __get_user(to->si_signo, &from->si_signo);
111 err |= __get_user(to->si_errno, &from->si_errno);
112 err |= __get_user(to->si_code, &from->si_code);
113
114 if (to->si_code < 0)
115 err |= __copy_from_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
116 else {
117 switch (to->si_code >> 16) {
118 case __SI_RT >> 16: /* This is not generated by the kernel as of now. */
119 case __SI_MESGQ >> 16:
120 err |= __get_user(to->si_int, &from->si_int);
121 /* fallthrough */
122 case __SI_KILL >> 16:
123 err |= __get_user(to->si_pid, &from->si_pid);
124 err |= __get_user(to->si_uid, &from->si_uid);
125 break;
126 case __SI_CHLD >> 16:
127 err |= __get_user(to->si_pid, &from->si_pid);
128 err |= __get_user(to->si_uid, &from->si_uid);
129 err |= __get_user(to->si_utime, &from->si_utime);
130 err |= __get_user(to->si_stime, &from->si_stime);
131 err |= __get_user(to->si_status, &from->si_status);
132 break;
133 case __SI_FAULT >> 16:
134 err |= __get_user(tmp, &from->si_addr);
3c52e49d
MS
135 to->si_addr = (void __force __user *)
136 (u64) (tmp & PSW32_ADDR_INSN);
1da177e4
LT
137 break;
138 case __SI_POLL >> 16:
139 err |= __get_user(to->si_band, &from->si_band);
140 err |= __get_user(to->si_fd, &from->si_fd);
141 break;
142 case __SI_TIMER >> 16:
143 err |= __get_user(to->si_tid, &from->si_tid);
144 err |= __get_user(to->si_overrun, &from->si_overrun);
145 err |= __get_user(to->si_int, &from->si_int);
146 break;
147 default:
148 break;
149 }
150 }
0ebfd313 151 return err ? -EFAULT : 0;
1da177e4
LT
152}
153
1da177e4
LT
154static int save_sigregs32(struct pt_regs *regs, _sigregs32 __user *sregs)
155{
4725c860
MS
156 _sigregs32 user_sregs;
157 int i;
1da177e4 158
4725c860 159 user_sregs.regs.psw.mask = psw32_user_bits |
b50511e4 160 ((__u32)(regs->psw.mask >> 32) & PSW32_MASK_USER);
4725c860 161 user_sregs.regs.psw.addr = (__u32) regs->psw.addr |
d4e81b35 162 (__u32)(regs->psw.mask & PSW_MASK_BA);
1da177e4 163 for (i = 0; i < NUM_GPRS; i++)
4725c860 164 user_sregs.regs.gprs[i] = (__u32) regs->gprs[i];
1da177e4 165 save_access_regs(current->thread.acrs);
4725c860
MS
166 memcpy(&user_sregs.regs.acrs, current->thread.acrs,
167 sizeof(user_sregs.regs.acrs));
168 save_fp_ctl(&current->thread.fp_regs.fpc);
169 save_fp_regs(current->thread.fp_regs.fprs);
170 memcpy(&user_sregs.fpregs, &current->thread.fp_regs,
171 sizeof(user_sregs.fpregs));
172 if (__copy_to_user(sregs, &user_sregs, sizeof(_sigregs32)))
f8544ec4
HC
173 return -EFAULT;
174 return 0;
1da177e4
LT
175}
176
177static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs)
178{
4725c860
MS
179 _sigregs32 user_sregs;
180 int i;
1da177e4
LT
181
182 /* Alwys make any pending restarted system call return -EINTR */
183 current_thread_info()->restart_block.fn = do_no_restart_syscall;
184
4725c860 185 if (__copy_from_user(&user_sregs, &sregs->regs, sizeof(user_sregs)))
f8544ec4 186 return -EFAULT;
4725c860
MS
187
188 /* Loading the floating-point-control word can fail. Do that first. */
189 if (restore_fp_ctl(&user_sregs.fpregs.fpc))
190 return -EINVAL;
191
192 /* Use regs->psw.mask instead of PSW_USER_BITS to preserve PER bit. */
b50511e4 193 regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) |
4725c860
MS
194 (__u64)(user_sregs.regs.psw.mask & PSW32_MASK_USER) << 32 |
195 (__u64)(user_sregs.regs.psw.addr & PSW32_ADDR_AMODE);
fa968ee2 196 /* Check for invalid user address space control. */
e258d719
MS
197 if ((regs->psw.mask & PSW_MASK_ASC) == PSW_ASC_HOME)
198 regs->psw.mask = PSW_ASC_PRIMARY |
fa968ee2 199 (regs->psw.mask & ~PSW_MASK_ASC);
4725c860 200 regs->psw.addr = (__u64)(user_sregs.regs.psw.addr & PSW32_ADDR_INSN);
1da177e4 201 for (i = 0; i < NUM_GPRS; i++)
4725c860
MS
202 regs->gprs[i] = (__u64) user_sregs.regs.gprs[i];
203 memcpy(&current->thread.acrs, &user_sregs.regs.acrs,
204 sizeof(current->thread.acrs));
1da177e4
LT
205 restore_access_regs(current->thread.acrs);
206
4725c860
MS
207 memcpy(&current->thread.fp_regs, &user_sregs.fpregs,
208 sizeof(current->thread.fp_regs));
1da177e4 209
4725c860 210 restore_fp_regs(current->thread.fp_regs.fprs);
b6ef5bb3 211 clear_thread_flag(TIF_SYSCALL); /* No longer in a system call */
1da177e4
LT
212 return 0;
213}
214
ea2a4d3a
HC
215static int save_sigregs_gprs_high(struct pt_regs *regs, __u32 __user *uregs)
216{
217 __u32 gprs_high[NUM_GPRS];
218 int i;
219
220 for (i = 0; i < NUM_GPRS; i++)
221 gprs_high[i] = regs->gprs[i] >> 32;
f8544ec4
HC
222 if (__copy_to_user(uregs, &gprs_high, sizeof(gprs_high)))
223 return -EFAULT;
224 return 0;
ea2a4d3a
HC
225}
226
227static int restore_sigregs_gprs_high(struct pt_regs *regs, __u32 __user *uregs)
228{
229 __u32 gprs_high[NUM_GPRS];
f8544ec4 230 int i;
ea2a4d3a 231
f8544ec4
HC
232 if (__copy_from_user(&gprs_high, uregs, sizeof(gprs_high)))
233 return -EFAULT;
ea2a4d3a
HC
234 for (i = 0; i < NUM_GPRS; i++)
235 *(__u32 *)&regs->gprs[i] = gprs_high[i];
236 return 0;
237}
238
03ff9a23 239asmlinkage long sys32_sigreturn(void)
1da177e4 240{
03ff9a23 241 struct pt_regs *regs = task_pt_regs(current);
1da177e4
LT
242 sigframe32 __user *frame = (sigframe32 __user *)regs->gprs[15];
243 sigset_t set;
244
1da177e4
LT
245 if (__copy_from_user(&set.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE32))
246 goto badframe;
391c62fe 247 set_current_blocked(&set);
1da177e4
LT
248 if (restore_sigregs32(regs, &frame->sregs))
249 goto badframe;
ea2a4d3a
HC
250 if (restore_sigregs_gprs_high(regs, frame->gprs_high))
251 goto badframe;
1da177e4 252 return regs->gprs[2];
1da177e4
LT
253badframe:
254 force_sig(SIGSEGV, current);
255 return 0;
256}
257
03ff9a23 258asmlinkage long sys32_rt_sigreturn(void)
1da177e4 259{
03ff9a23 260 struct pt_regs *regs = task_pt_regs(current);
1da177e4
LT
261 rt_sigframe32 __user *frame = (rt_sigframe32 __user *)regs->gprs[15];
262 sigset_t set;
1da177e4 263
1da177e4
LT
264 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
265 goto badframe;
391c62fe 266 set_current_blocked(&set);
1da177e4
LT
267 if (restore_sigregs32(regs, &frame->uc.uc_mcontext))
268 goto badframe;
ea2a4d3a
HC
269 if (restore_sigregs_gprs_high(regs, frame->gprs_high))
270 goto badframe;
e214125a 271 if (compat_restore_altstack(&frame->uc.uc_stack))
1da177e4 272 goto badframe;
1da177e4 273 return regs->gprs[2];
1da177e4 274badframe:
03ff9a23
MS
275 force_sig(SIGSEGV, current);
276 return 0;
1da177e4
LT
277}
278
279/*
280 * Set up a signal frame.
281 */
282
283
284/*
285 * Determine which stack to use..
286 */
287static inline void __user *
288get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
289{
290 unsigned long sp;
291
292 /* Default to using normal stack */
293 sp = (unsigned long) A(regs->gprs[15]);
294
de553438
HC
295 /* Overflow on alternate signal stack gives SIGSEGV. */
296 if (on_sig_stack(sp) && !on_sig_stack((sp - frame_size) & -8UL))
297 return (void __user *) -1UL;
298
1da177e4
LT
299 /* This is the X/Open sanctioned signal stack switching. */
300 if (ka->sa.sa_flags & SA_ONSTACK) {
28f22378 301 if (! sas_ss_flags(sp))
1da177e4
LT
302 sp = current->sas_ss_sp + current->sas_ss_size;
303 }
304
1da177e4
LT
305 return (void __user *)((sp - frame_size) & -8ul);
306}
307
308static inline int map_signal(int sig)
309{
310 if (current_thread_info()->exec_domain
311 && current_thread_info()->exec_domain->signal_invmap
312 && sig < 32)
313 return current_thread_info()->exec_domain->signal_invmap[sig];
314 else
315 return sig;
316}
317
54dfe5dd 318static int setup_frame32(int sig, struct k_sigaction *ka,
1da177e4
LT
319 sigset_t *set, struct pt_regs * regs)
320{
321 sigframe32 __user *frame = get_sigframe(ka, regs, sizeof(sigframe32));
1da177e4 322
de553438
HC
323 if (frame == (void __user *) -1UL)
324 goto give_sigsegv;
325
1da177e4
LT
326 if (__copy_to_user(&frame->sc.oldmask, &set->sig, _SIGMASK_COPY_SIZE32))
327 goto give_sigsegv;
328
329 if (save_sigregs32(regs, &frame->sregs))
330 goto give_sigsegv;
ea2a4d3a
HC
331 if (save_sigregs_gprs_high(regs, frame->gprs_high))
332 goto give_sigsegv;
1da177e4
LT
333 if (__put_user((unsigned long) &frame->sregs, &frame->sc.sregs))
334 goto give_sigsegv;
335
336 /* Set up to return from userspace. If provided, use a stub
337 already in userspace. */
338 if (ka->sa.sa_flags & SA_RESTORER) {
5b512beb 339 regs->gprs[14] = (__u64 __force) ka->sa.sa_restorer | PSW32_ADDR_AMODE;
1da177e4 340 } else {
5b512beb 341 regs->gprs[14] = (__u64 __force) frame->retcode | PSW32_ADDR_AMODE;
1da177e4 342 if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn,
3c52e49d 343 (u16 __force __user *)(frame->retcode)))
1da177e4
LT
344 goto give_sigsegv;
345 }
346
347 /* Set up backchain. */
348 if (__put_user(regs->gprs[15], (unsigned int __user *) frame))
349 goto give_sigsegv;
350
351 /* Set up registers for signal handler */
3c52e49d 352 regs->gprs[15] = (__force __u64) frame;
fa968ee2
MS
353 /* Force 31 bit amode and default user address space control. */
354 regs->psw.mask = PSW_MASK_BA |
e258d719 355 (PSW_USER_BITS & PSW_MASK_ASC) |
fa968ee2 356 (regs->psw.mask & ~PSW_MASK_ASC);
3c52e49d 357 regs->psw.addr = (__force __u64) ka->sa.sa_handler;
1da177e4
LT
358
359 regs->gprs[2] = map_signal(sig);
3c52e49d 360 regs->gprs[3] = (__force __u64) &frame->sc;
1da177e4
LT
361
362 /* We forgot to include these in the sigcontext.
363 To avoid breaking binary compatibility, they are passed as args. */
aa33c8cb
MS
364 if (sig == SIGSEGV || sig == SIGBUS || sig == SIGILL ||
365 sig == SIGTRAP || sig == SIGFPE) {
366 /* set extra registers only for synchronous signals */
367 regs->gprs[4] = regs->int_code & 127;
368 regs->gprs[5] = regs->int_parm_long;
bd9e034e 369 regs->gprs[6] = task_thread_info(current)->last_break;
aa33c8cb 370 }
1da177e4
LT
371
372 /* Place signal number on stack to allow backtrace from handler. */
3c52e49d 373 if (__put_user(regs->gprs[2], (int __force __user *) &frame->signo))
1da177e4 374 goto give_sigsegv;
54dfe5dd 375 return 0;
1da177e4
LT
376
377give_sigsegv:
378 force_sigsegv(sig, current);
54dfe5dd 379 return -EFAULT;
1da177e4
LT
380}
381
54dfe5dd 382static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info,
1da177e4
LT
383 sigset_t *set, struct pt_regs * regs)
384{
385 int err = 0;
386 rt_sigframe32 __user *frame = get_sigframe(ka, regs, sizeof(rt_sigframe32));
1da177e4 387
de553438
HC
388 if (frame == (void __user *) -1UL)
389 goto give_sigsegv;
390
1da177e4
LT
391 if (copy_siginfo_to_user32(&frame->info, info))
392 goto give_sigsegv;
393
394 /* Create the ucontext. */
ea2a4d3a 395 err |= __put_user(UC_EXTENDED, &frame->uc.uc_flags);
1da177e4 396 err |= __put_user(0, &frame->uc.uc_link);
e214125a 397 err |= __compat_save_altstack(&frame->uc.uc_stack, regs->gprs[15]);
1da177e4 398 err |= save_sigregs32(regs, &frame->uc.uc_mcontext);
ea2a4d3a 399 err |= save_sigregs_gprs_high(regs, frame->gprs_high);
1da177e4
LT
400 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
401 if (err)
402 goto give_sigsegv;
403
404 /* Set up to return from userspace. If provided, use a stub
405 already in userspace. */
406 if (ka->sa.sa_flags & SA_RESTORER) {
5b512beb 407 regs->gprs[14] = (__u64 __force) ka->sa.sa_restorer | PSW32_ADDR_AMODE;
1da177e4 408 } else {
5b512beb 409 regs->gprs[14] = (__u64 __force) frame->retcode | PSW32_ADDR_AMODE;
1da177e4 410 err |= __put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn,
3c52e49d 411 (u16 __force __user *)(frame->retcode));
1da177e4
LT
412 }
413
414 /* Set up backchain. */
3c52e49d 415 if (__put_user(regs->gprs[15], (unsigned int __force __user *) frame))
1da177e4
LT
416 goto give_sigsegv;
417
418 /* Set up registers for signal handler */
3c52e49d 419 regs->gprs[15] = (__force __u64) frame;
fa968ee2
MS
420 /* Force 31 bit amode and default user address space control. */
421 regs->psw.mask = PSW_MASK_BA |
e258d719 422 (PSW_USER_BITS & PSW_MASK_ASC) |
fa968ee2 423 (regs->psw.mask & ~PSW_MASK_ASC);
5b512beb 424 regs->psw.addr = (__u64 __force) ka->sa.sa_handler;
1da177e4
LT
425
426 regs->gprs[2] = map_signal(sig);
3c52e49d
MS
427 regs->gprs[3] = (__force __u64) &frame->info;
428 regs->gprs[4] = (__force __u64) &frame->uc;
bd9e034e 429 regs->gprs[5] = task_thread_info(current)->last_break;
54dfe5dd 430 return 0;
1da177e4
LT
431
432give_sigsegv:
433 force_sigsegv(sig, current);
54dfe5dd 434 return -EFAULT;
1da177e4
LT
435}
436
437/*
438 * OK, we're invoking a handler
439 */
440
a610d6e6 441void handle_signal32(unsigned long sig, struct k_sigaction *ka,
391c62fe 442 siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
1da177e4 443{
54dfe5dd
HC
444 int ret;
445
1da177e4
LT
446 /* Set up the stack frame */
447 if (ka->sa.sa_flags & SA_SIGINFO)
54dfe5dd 448 ret = setup_rt_frame32(sig, ka, info, oldset, regs);
1da177e4 449 else
54dfe5dd 450 ret = setup_frame32(sig, ka, oldset, regs);
391c62fe 451 if (ret)
a610d6e6 452 return;
efee984c 453 signal_delivered(sig, info, ka, regs,
a610d6e6 454 test_thread_flag(TIF_SINGLE_STEP));
1da177e4
LT
455}
456