]>
git.proxmox.com Git - mirror_ubuntu-eoan-kernel.git/blob - arch/s390/kernel/compat_signal.c
1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright IBM Corp. 2000, 2006
4 * Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
5 * Gerhard Tonn (ton@de.ibm.com)
7 * Copyright (C) 1991, 1992 Linus Torvalds
9 * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson
12 #include <linux/compat.h>
13 #include <linux/sched.h>
14 #include <linux/sched/task_stack.h>
16 #include <linux/smp.h>
17 #include <linux/kernel.h>
18 #include <linux/signal.h>
19 #include <linux/errno.h>
20 #include <linux/wait.h>
21 #include <linux/ptrace.h>
22 #include <linux/unistd.h>
23 #include <linux/stddef.h>
24 #include <linux/tty.h>
25 #include <linux/personality.h>
26 #include <linux/binfmts.h>
27 #include <asm/ucontext.h>
28 #include <linux/uaccess.h>
29 #include <asm/lowcore.h>
30 #include <asm/switch_to.h>
31 #include "compat_linux.h"
32 #include "compat_ptrace.h"
37 __u8 callee_used_stack
[__SIGNAL_FRAMESIZE32
];
38 struct sigcontext32 sc
;
41 _sigregs_ext32 sregs_ext
;
42 __u16 svc_insn
; /* Offset of svc_insn is NOT fixed! */
47 __u8 callee_used_stack
[__SIGNAL_FRAMESIZE32
];
49 compat_siginfo_t info
;
53 /* Store registers needed to create the signal frame */
54 static void store_sigregs(void)
56 save_access_regs(current
->thread
.acrs
);
60 /* Load registers after signal return */
61 static void load_sigregs(void)
63 restore_access_regs(current
->thread
.acrs
);
66 static int save_sigregs32(struct pt_regs
*regs
, _sigregs32 __user
*sregs
)
68 _sigregs32 user_sregs
;
71 user_sregs
.regs
.psw
.mask
= (__u32
)(regs
->psw
.mask
>> 32);
72 user_sregs
.regs
.psw
.mask
&= PSW32_MASK_USER
| PSW32_MASK_RI
;
73 user_sregs
.regs
.psw
.mask
|= PSW32_USER_BITS
;
74 user_sregs
.regs
.psw
.addr
= (__u32
) regs
->psw
.addr
|
75 (__u32
)(regs
->psw
.mask
& PSW_MASK_BA
);
76 for (i
= 0; i
< NUM_GPRS
; i
++)
77 user_sregs
.regs
.gprs
[i
] = (__u32
) regs
->gprs
[i
];
78 memcpy(&user_sregs
.regs
.acrs
, current
->thread
.acrs
,
79 sizeof(user_sregs
.regs
.acrs
));
80 fpregs_store((_s390_fp_regs
*) &user_sregs
.fpregs
, ¤t
->thread
.fpu
);
81 if (__copy_to_user(sregs
, &user_sregs
, sizeof(_sigregs32
)))
86 static int restore_sigregs32(struct pt_regs
*regs
,_sigregs32 __user
*sregs
)
88 _sigregs32 user_sregs
;
91 /* Alwys make any pending restarted system call return -EINTR */
92 current
->restart_block
.fn
= do_no_restart_syscall
;
94 if (__copy_from_user(&user_sregs
, &sregs
->regs
, sizeof(user_sregs
)))
97 if (!is_ri_task(current
) && (user_sregs
.regs
.psw
.mask
& PSW32_MASK_RI
))
100 /* Test the floating-point-control word. */
101 if (test_fp_ctl(user_sregs
.fpregs
.fpc
))
104 /* Use regs->psw.mask instead of PSW_USER_BITS to preserve PER bit. */
105 regs
->psw
.mask
= (regs
->psw
.mask
& ~(PSW_MASK_USER
| PSW_MASK_RI
)) |
106 (__u64
)(user_sregs
.regs
.psw
.mask
& PSW32_MASK_USER
) << 32 |
107 (__u64
)(user_sregs
.regs
.psw
.mask
& PSW32_MASK_RI
) << 32 |
108 (__u64
)(user_sregs
.regs
.psw
.addr
& PSW32_ADDR_AMODE
);
109 /* Check for invalid user address space control. */
110 if ((regs
->psw
.mask
& PSW_MASK_ASC
) == PSW_ASC_HOME
)
111 regs
->psw
.mask
= PSW_ASC_PRIMARY
|
112 (regs
->psw
.mask
& ~PSW_MASK_ASC
);
113 regs
->psw
.addr
= (__u64
)(user_sregs
.regs
.psw
.addr
& PSW32_ADDR_INSN
);
114 for (i
= 0; i
< NUM_GPRS
; i
++)
115 regs
->gprs
[i
] = (__u64
) user_sregs
.regs
.gprs
[i
];
116 memcpy(¤t
->thread
.acrs
, &user_sregs
.regs
.acrs
,
117 sizeof(current
->thread
.acrs
));
118 fpregs_load((_s390_fp_regs
*) &user_sregs
.fpregs
, ¤t
->thread
.fpu
);
120 clear_pt_regs_flag(regs
, PIF_SYSCALL
); /* No longer in a system call */
124 static int save_sigregs_ext32(struct pt_regs
*regs
,
125 _sigregs_ext32 __user
*sregs_ext
)
127 __u32 gprs_high
[NUM_GPRS
];
128 __u64 vxrs
[__NUM_VXRS_LOW
];
131 /* Save high gprs to signal stack */
132 for (i
= 0; i
< NUM_GPRS
; i
++)
133 gprs_high
[i
] = regs
->gprs
[i
] >> 32;
134 if (__copy_to_user(&sregs_ext
->gprs_high
, &gprs_high
,
135 sizeof(sregs_ext
->gprs_high
)))
138 /* Save vector registers to signal stack */
139 if (MACHINE_HAS_VX
) {
140 for (i
= 0; i
< __NUM_VXRS_LOW
; i
++)
141 vxrs
[i
] = *((__u64
*)(current
->thread
.fpu
.vxrs
+ i
) + 1);
142 if (__copy_to_user(&sregs_ext
->vxrs_low
, vxrs
,
143 sizeof(sregs_ext
->vxrs_low
)) ||
144 __copy_to_user(&sregs_ext
->vxrs_high
,
145 current
->thread
.fpu
.vxrs
+ __NUM_VXRS_LOW
,
146 sizeof(sregs_ext
->vxrs_high
)))
152 static int restore_sigregs_ext32(struct pt_regs
*regs
,
153 _sigregs_ext32 __user
*sregs_ext
)
155 __u32 gprs_high
[NUM_GPRS
];
156 __u64 vxrs
[__NUM_VXRS_LOW
];
159 /* Restore high gprs from signal stack */
160 if (__copy_from_user(&gprs_high
, &sregs_ext
->gprs_high
,
161 sizeof(sregs_ext
->gprs_high
)))
163 for (i
= 0; i
< NUM_GPRS
; i
++)
164 *(__u32
*)®s
->gprs
[i
] = gprs_high
[i
];
166 /* Restore vector registers from signal stack */
167 if (MACHINE_HAS_VX
) {
168 if (__copy_from_user(vxrs
, &sregs_ext
->vxrs_low
,
169 sizeof(sregs_ext
->vxrs_low
)) ||
170 __copy_from_user(current
->thread
.fpu
.vxrs
+ __NUM_VXRS_LOW
,
171 &sregs_ext
->vxrs_high
,
172 sizeof(sregs_ext
->vxrs_high
)))
174 for (i
= 0; i
< __NUM_VXRS_LOW
; i
++)
175 *((__u64
*)(current
->thread
.fpu
.vxrs
+ i
) + 1) = vxrs
[i
];
180 COMPAT_SYSCALL_DEFINE0(sigreturn
)
182 struct pt_regs
*regs
= task_pt_regs(current
);
183 sigframe32 __user
*frame
= (sigframe32 __user
*)regs
->gprs
[15];
186 if (get_compat_sigset(&set
, (compat_sigset_t __user
*)frame
->sc
.oldmask
))
188 set_current_blocked(&set
);
190 if (restore_sigregs32(regs
, &frame
->sregs
))
192 if (restore_sigregs_ext32(regs
, &frame
->sregs_ext
))
195 return regs
->gprs
[2];
197 force_sig(SIGSEGV
, current
);
201 COMPAT_SYSCALL_DEFINE0(rt_sigreturn
)
203 struct pt_regs
*regs
= task_pt_regs(current
);
204 rt_sigframe32 __user
*frame
= (rt_sigframe32 __user
*)regs
->gprs
[15];
207 if (get_compat_sigset(&set
, &frame
->uc
.uc_sigmask
))
209 set_current_blocked(&set
);
210 if (compat_restore_altstack(&frame
->uc
.uc_stack
))
213 if (restore_sigregs32(regs
, &frame
->uc
.uc_mcontext
))
215 if (restore_sigregs_ext32(regs
, &frame
->uc
.uc_mcontext_ext
))
218 return regs
->gprs
[2];
220 force_sig(SIGSEGV
, current
);
225 * Set up a signal frame.
230 * Determine which stack to use..
232 static inline void __user
*
233 get_sigframe(struct k_sigaction
*ka
, struct pt_regs
* regs
, size_t frame_size
)
237 /* Default to using normal stack */
238 sp
= (unsigned long) A(regs
->gprs
[15]);
240 /* Overflow on alternate signal stack gives SIGSEGV. */
241 if (on_sig_stack(sp
) && !on_sig_stack((sp
- frame_size
) & -8UL))
242 return (void __user
*) -1UL;
244 /* This is the X/Open sanctioned signal stack switching. */
245 if (ka
->sa
.sa_flags
& SA_ONSTACK
) {
246 if (! sas_ss_flags(sp
))
247 sp
= current
->sas_ss_sp
+ current
->sas_ss_size
;
250 return (void __user
*)((sp
- frame_size
) & -8ul);
253 static int setup_frame32(struct ksignal
*ksig
, sigset_t
*set
,
254 struct pt_regs
*regs
)
257 sigframe32 __user
*frame
;
258 unsigned long restorer
;
262 * gprs_high are always present for 31-bit compat tasks.
263 * The space for vector registers is only allocated if
264 * the machine supports it
266 frame_size
= sizeof(*frame
) - sizeof(frame
->sregs_ext
.__reserved
);
268 frame_size
-= sizeof(frame
->sregs_ext
.vxrs_low
) +
269 sizeof(frame
->sregs_ext
.vxrs_high
);
270 frame
= get_sigframe(&ksig
->ka
, regs
, frame_size
);
271 if (frame
== (void __user
*) -1UL)
274 /* Set up backchain. */
275 if (__put_user(regs
->gprs
[15], (unsigned int __user
*) frame
))
278 /* Create struct sigcontext32 on the signal stack */
279 if (put_compat_sigset((compat_sigset_t __user
*)frame
->sc
.oldmask
,
280 set
, sizeof(compat_sigset_t
)))
282 if (__put_user(ptr_to_compat(&frame
->sregs
), &frame
->sc
.sregs
))
285 /* Store registers needed to create the signal frame */
288 /* Create _sigregs32 on the signal stack */
289 if (save_sigregs32(regs
, &frame
->sregs
))
292 /* Place signal number on stack to allow backtrace from handler. */
293 if (__put_user(regs
->gprs
[2], (int __force __user
*) &frame
->signo
))
296 /* Create _sigregs_ext32 on the signal stack */
297 if (save_sigregs_ext32(regs
, &frame
->sregs_ext
))
300 /* Set up to return from userspace. If provided, use a stub
301 already in userspace. */
302 if (ksig
->ka
.sa
.sa_flags
& SA_RESTORER
) {
303 restorer
= (unsigned long __force
)
304 ksig
->ka
.sa
.sa_restorer
| PSW32_ADDR_AMODE
;
306 /* Signal frames without vectors registers are short ! */
307 __u16 __user
*svc
= (void __user
*) frame
+ frame_size
- 2;
308 if (__put_user(S390_SYSCALL_OPCODE
| __NR_sigreturn
, svc
))
310 restorer
= (unsigned long __force
) svc
| PSW32_ADDR_AMODE
;
313 /* Set up registers for signal handler */
314 regs
->gprs
[14] = restorer
;
315 regs
->gprs
[15] = (__force __u64
) frame
;
316 /* Force 31 bit amode and default user address space control. */
317 regs
->psw
.mask
= PSW_MASK_BA
|
318 (PSW_USER_BITS
& PSW_MASK_ASC
) |
319 (regs
->psw
.mask
& ~PSW_MASK_ASC
);
320 regs
->psw
.addr
= (__force __u64
) ksig
->ka
.sa
.sa_handler
;
323 regs
->gprs
[3] = (__force __u64
) &frame
->sc
;
325 /* We forgot to include these in the sigcontext.
326 To avoid breaking binary compatibility, they are passed as args. */
327 if (sig
== SIGSEGV
|| sig
== SIGBUS
|| sig
== SIGILL
||
328 sig
== SIGTRAP
|| sig
== SIGFPE
) {
329 /* set extra registers only for synchronous signals */
330 regs
->gprs
[4] = regs
->int_code
& 127;
331 regs
->gprs
[5] = regs
->int_parm_long
;
332 regs
->gprs
[6] = current
->thread
.last_break
;
338 static int setup_rt_frame32(struct ksignal
*ksig
, sigset_t
*set
,
339 struct pt_regs
*regs
)
341 rt_sigframe32 __user
*frame
;
342 unsigned long restorer
;
346 frame_size
= sizeof(*frame
) -
347 sizeof(frame
->uc
.uc_mcontext_ext
.__reserved
);
349 * gprs_high are always present for 31-bit compat tasks.
350 * The space for vector registers is only allocated if
351 * the machine supports it
353 uc_flags
= UC_GPRS_HIGH
;
354 if (MACHINE_HAS_VX
) {
357 frame_size
-= sizeof(frame
->uc
.uc_mcontext_ext
.vxrs_low
) +
358 sizeof(frame
->uc
.uc_mcontext_ext
.vxrs_high
);
359 frame
= get_sigframe(&ksig
->ka
, regs
, frame_size
);
360 if (frame
== (void __user
*) -1UL)
363 /* Set up backchain. */
364 if (__put_user(regs
->gprs
[15], (unsigned int __force __user
*) frame
))
367 /* Set up to return from userspace. If provided, use a stub
368 already in userspace. */
369 if (ksig
->ka
.sa
.sa_flags
& SA_RESTORER
) {
370 restorer
= (unsigned long __force
)
371 ksig
->ka
.sa
.sa_restorer
| PSW32_ADDR_AMODE
;
373 __u16 __user
*svc
= &frame
->svc_insn
;
374 if (__put_user(S390_SYSCALL_OPCODE
| __NR_rt_sigreturn
, svc
))
376 restorer
= (unsigned long __force
) svc
| PSW32_ADDR_AMODE
;
379 /* Create siginfo on the signal stack */
380 if (copy_siginfo_to_user32(&frame
->info
, &ksig
->info
))
383 /* Store registers needed to create the signal frame */
386 /* Create ucontext on the signal stack. */
387 if (__put_user(uc_flags
, &frame
->uc
.uc_flags
) ||
388 __put_user(0, &frame
->uc
.uc_link
) ||
389 __compat_save_altstack(&frame
->uc
.uc_stack
, regs
->gprs
[15]) ||
390 save_sigregs32(regs
, &frame
->uc
.uc_mcontext
) ||
391 put_compat_sigset(&frame
->uc
.uc_sigmask
, set
, sizeof(compat_sigset_t
)) ||
392 save_sigregs_ext32(regs
, &frame
->uc
.uc_mcontext_ext
))
395 /* Set up registers for signal handler */
396 regs
->gprs
[14] = restorer
;
397 regs
->gprs
[15] = (__force __u64
) frame
;
398 /* Force 31 bit amode and default user address space control. */
399 regs
->psw
.mask
= PSW_MASK_BA
|
400 (PSW_USER_BITS
& PSW_MASK_ASC
) |
401 (regs
->psw
.mask
& ~PSW_MASK_ASC
);
402 regs
->psw
.addr
= (__u64 __force
) ksig
->ka
.sa
.sa_handler
;
404 regs
->gprs
[2] = ksig
->sig
;
405 regs
->gprs
[3] = (__force __u64
) &frame
->info
;
406 regs
->gprs
[4] = (__force __u64
) &frame
->uc
;
407 regs
->gprs
[5] = current
->thread
.last_break
;
412 * OK, we're invoking a handler
415 void handle_signal32(struct ksignal
*ksig
, sigset_t
*oldset
,
416 struct pt_regs
*regs
)
420 /* Set up the stack frame */
421 if (ksig
->ka
.sa
.sa_flags
& SA_SIGINFO
)
422 ret
= setup_rt_frame32(ksig
, oldset
, regs
);
424 ret
= setup_frame32(ksig
, oldset
, regs
);
426 signal_setup_done(ret
, ksig
, test_thread_flag(TIF_SINGLE_STEP
));