1a545b48cSBrian Gerst // SPDX-License-Identifier: GPL-2.0
2a545b48cSBrian Gerst /*
3a545b48cSBrian Gerst * Copyright (C) 1991, 1992 Linus Torvalds
4a545b48cSBrian Gerst * Copyright (C) 2000, 2001, 2002 Andi Kleen SuSE Labs
5a545b48cSBrian Gerst */
6a545b48cSBrian Gerst
7a545b48cSBrian Gerst #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
8a545b48cSBrian Gerst
9a545b48cSBrian Gerst #include <linux/kernel.h>
10a545b48cSBrian Gerst #include <linux/errno.h>
11a545b48cSBrian Gerst #include <linux/unistd.h>
12a545b48cSBrian Gerst #include <linux/uaccess.h>
13a545b48cSBrian Gerst #include <linux/syscalls.h>
14a545b48cSBrian Gerst
15a545b48cSBrian Gerst #include <asm/ucontext.h>
16a545b48cSBrian Gerst #include <asm/fpu/signal.h>
17a545b48cSBrian Gerst #include <asm/sighandling.h>
18a545b48cSBrian Gerst
19a545b48cSBrian Gerst #include <asm/syscall.h>
20a545b48cSBrian Gerst #include <asm/sigframe.h>
21a545b48cSBrian Gerst #include <asm/signal.h>
22a545b48cSBrian Gerst
23a545b48cSBrian Gerst /*
24a545b48cSBrian Gerst * If regs->ss will cause an IRET fault, change it. Otherwise leave it
25a545b48cSBrian Gerst * alone. Using this generally makes no sense unless
26a545b48cSBrian Gerst * user_64bit_mode(regs) would return true.
27a545b48cSBrian Gerst */
force_valid_ss(struct pt_regs * regs)28a545b48cSBrian Gerst static void force_valid_ss(struct pt_regs *regs)
29a545b48cSBrian Gerst {
30a545b48cSBrian Gerst u32 ar;
31a545b48cSBrian Gerst asm volatile ("lar %[old_ss], %[ar]\n\t"
32a545b48cSBrian Gerst "jz 1f\n\t" /* If invalid: */
33a545b48cSBrian Gerst "xorl %[ar], %[ar]\n\t" /* set ar = 0 */
34a545b48cSBrian Gerst "1:"
35a545b48cSBrian Gerst : [ar] "=r" (ar)
36a545b48cSBrian Gerst : [old_ss] "rm" ((u16)regs->ss));
37a545b48cSBrian Gerst
38a545b48cSBrian Gerst /*
39a545b48cSBrian Gerst * For a valid 64-bit user context, we need DPL 3, type
40a545b48cSBrian Gerst * read-write data or read-write exp-down data, and S and P
41a545b48cSBrian Gerst * set. We can't use VERW because VERW doesn't check the
42a545b48cSBrian Gerst * P bit.
43a545b48cSBrian Gerst */
44a545b48cSBrian Gerst ar &= AR_DPL_MASK | AR_S | AR_P | AR_TYPE_MASK;
45a545b48cSBrian Gerst if (ar != (AR_DPL3 | AR_S | AR_P | AR_TYPE_RWDATA) &&
46a545b48cSBrian Gerst ar != (AR_DPL3 | AR_S | AR_P | AR_TYPE_RWDATA_EXPDOWN))
47a545b48cSBrian Gerst regs->ss = __USER_DS;
48a545b48cSBrian Gerst }
49a545b48cSBrian Gerst
restore_sigcontext(struct pt_regs * regs,struct sigcontext __user * usc,unsigned long uc_flags)50a545b48cSBrian Gerst static bool restore_sigcontext(struct pt_regs *regs,
51a545b48cSBrian Gerst struct sigcontext __user *usc,
52a545b48cSBrian Gerst unsigned long uc_flags)
53a545b48cSBrian Gerst {
54a545b48cSBrian Gerst struct sigcontext sc;
55a545b48cSBrian Gerst
56a545b48cSBrian Gerst /* Always make any pending restarted system calls return -EINTR */
57a545b48cSBrian Gerst current->restart_block.fn = do_no_restart_syscall;
58a545b48cSBrian Gerst
59a545b48cSBrian Gerst if (copy_from_user(&sc, usc, offsetof(struct sigcontext, reserved1)))
60a545b48cSBrian Gerst return false;
61a545b48cSBrian Gerst
62a545b48cSBrian Gerst regs->bx = sc.bx;
63a545b48cSBrian Gerst regs->cx = sc.cx;
64a545b48cSBrian Gerst regs->dx = sc.dx;
65a545b48cSBrian Gerst regs->si = sc.si;
66a545b48cSBrian Gerst regs->di = sc.di;
67a545b48cSBrian Gerst regs->bp = sc.bp;
68a545b48cSBrian Gerst regs->ax = sc.ax;
69a545b48cSBrian Gerst regs->sp = sc.sp;
70a545b48cSBrian Gerst regs->ip = sc.ip;
71a545b48cSBrian Gerst regs->r8 = sc.r8;
72a545b48cSBrian Gerst regs->r9 = sc.r9;
73a545b48cSBrian Gerst regs->r10 = sc.r10;
74a545b48cSBrian Gerst regs->r11 = sc.r11;
75a545b48cSBrian Gerst regs->r12 = sc.r12;
76a545b48cSBrian Gerst regs->r13 = sc.r13;
77a545b48cSBrian Gerst regs->r14 = sc.r14;
78a545b48cSBrian Gerst regs->r15 = sc.r15;
79a545b48cSBrian Gerst
80a545b48cSBrian Gerst /* Get CS/SS and force CPL3 */
81a545b48cSBrian Gerst regs->cs = sc.cs | 0x03;
82a545b48cSBrian Gerst regs->ss = sc.ss | 0x03;
83a545b48cSBrian Gerst
84a545b48cSBrian Gerst regs->flags = (regs->flags & ~FIX_EFLAGS) | (sc.flags & FIX_EFLAGS);
85a545b48cSBrian Gerst /* disable syscall checks */
86a545b48cSBrian Gerst regs->orig_ax = -1;
87a545b48cSBrian Gerst
88a545b48cSBrian Gerst /*
89a545b48cSBrian Gerst * Fix up SS if needed for the benefit of old DOSEMU and
90a545b48cSBrian Gerst * CRIU.
91a545b48cSBrian Gerst */
92a545b48cSBrian Gerst if (unlikely(!(uc_flags & UC_STRICT_RESTORE_SS) && user_64bit_mode(regs)))
93a545b48cSBrian Gerst force_valid_ss(regs);
94a545b48cSBrian Gerst
95a545b48cSBrian Gerst return fpu__restore_sig((void __user *)sc.fpstate, 0);
96a545b48cSBrian Gerst }
97a545b48cSBrian Gerst
98a545b48cSBrian Gerst static __always_inline int
__unsafe_setup_sigcontext(struct sigcontext __user * sc,void __user * fpstate,struct pt_regs * regs,unsigned long mask)99a545b48cSBrian Gerst __unsafe_setup_sigcontext(struct sigcontext __user *sc, void __user *fpstate,
100a545b48cSBrian Gerst struct pt_regs *regs, unsigned long mask)
101a545b48cSBrian Gerst {
102a545b48cSBrian Gerst unsafe_put_user(regs->di, &sc->di, Efault);
103a545b48cSBrian Gerst unsafe_put_user(regs->si, &sc->si, Efault);
104a545b48cSBrian Gerst unsafe_put_user(regs->bp, &sc->bp, Efault);
105a545b48cSBrian Gerst unsafe_put_user(regs->sp, &sc->sp, Efault);
106a545b48cSBrian Gerst unsafe_put_user(regs->bx, &sc->bx, Efault);
107a545b48cSBrian Gerst unsafe_put_user(regs->dx, &sc->dx, Efault);
108a545b48cSBrian Gerst unsafe_put_user(regs->cx, &sc->cx, Efault);
109a545b48cSBrian Gerst unsafe_put_user(regs->ax, &sc->ax, Efault);
110a545b48cSBrian Gerst unsafe_put_user(regs->r8, &sc->r8, Efault);
111a545b48cSBrian Gerst unsafe_put_user(regs->r9, &sc->r9, Efault);
112a545b48cSBrian Gerst unsafe_put_user(regs->r10, &sc->r10, Efault);
113a545b48cSBrian Gerst unsafe_put_user(regs->r11, &sc->r11, Efault);
114a545b48cSBrian Gerst unsafe_put_user(regs->r12, &sc->r12, Efault);
115a545b48cSBrian Gerst unsafe_put_user(regs->r13, &sc->r13, Efault);
116a545b48cSBrian Gerst unsafe_put_user(regs->r14, &sc->r14, Efault);
117a545b48cSBrian Gerst unsafe_put_user(regs->r15, &sc->r15, Efault);
118a545b48cSBrian Gerst
119a545b48cSBrian Gerst unsafe_put_user(current->thread.trap_nr, &sc->trapno, Efault);
120a545b48cSBrian Gerst unsafe_put_user(current->thread.error_code, &sc->err, Efault);
121a545b48cSBrian Gerst unsafe_put_user(regs->ip, &sc->ip, Efault);
122a545b48cSBrian Gerst unsafe_put_user(regs->flags, &sc->flags, Efault);
123a545b48cSBrian Gerst unsafe_put_user(regs->cs, &sc->cs, Efault);
124a545b48cSBrian Gerst unsafe_put_user(0, &sc->gs, Efault);
125a545b48cSBrian Gerst unsafe_put_user(0, &sc->fs, Efault);
126a545b48cSBrian Gerst unsafe_put_user(regs->ss, &sc->ss, Efault);
127a545b48cSBrian Gerst
128a545b48cSBrian Gerst unsafe_put_user(fpstate, (unsigned long __user *)&sc->fpstate, Efault);
129a545b48cSBrian Gerst
130a545b48cSBrian Gerst /* non-iBCS2 extensions.. */
131a545b48cSBrian Gerst unsafe_put_user(mask, &sc->oldmask, Efault);
132a545b48cSBrian Gerst unsafe_put_user(current->thread.cr2, &sc->cr2, Efault);
133a545b48cSBrian Gerst return 0;
134a545b48cSBrian Gerst Efault:
135a545b48cSBrian Gerst return -EFAULT;
136a545b48cSBrian Gerst }
137a545b48cSBrian Gerst
138a545b48cSBrian Gerst #define unsafe_put_sigcontext(sc, fp, regs, set, label) \
139a545b48cSBrian Gerst do { \
140a545b48cSBrian Gerst if (__unsafe_setup_sigcontext(sc, fp, regs, set->sig[0])) \
141a545b48cSBrian Gerst goto label; \
142a545b48cSBrian Gerst } while(0);
143a545b48cSBrian Gerst
144a545b48cSBrian Gerst #define unsafe_put_sigmask(set, frame, label) \
145a545b48cSBrian Gerst unsafe_put_user(*(__u64 *)(set), \
146a545b48cSBrian Gerst (__u64 __user *)&(frame)->uc.uc_sigmask, \
147a545b48cSBrian Gerst label)
148a545b48cSBrian Gerst
frame_uc_flags(struct pt_regs * regs)149a545b48cSBrian Gerst static unsigned long frame_uc_flags(struct pt_regs *regs)
150a545b48cSBrian Gerst {
151a545b48cSBrian Gerst unsigned long flags;
152a545b48cSBrian Gerst
153a545b48cSBrian Gerst if (boot_cpu_has(X86_FEATURE_XSAVE))
154a545b48cSBrian Gerst flags = UC_FP_XSTATE | UC_SIGCONTEXT_SS;
155a545b48cSBrian Gerst else
156a545b48cSBrian Gerst flags = UC_SIGCONTEXT_SS;
157a545b48cSBrian Gerst
158a545b48cSBrian Gerst if (likely(user_64bit_mode(regs)))
159a545b48cSBrian Gerst flags |= UC_STRICT_RESTORE_SS;
160a545b48cSBrian Gerst
161a545b48cSBrian Gerst return flags;
162a545b48cSBrian Gerst }
163a545b48cSBrian Gerst
x64_setup_rt_frame(struct ksignal * ksig,struct pt_regs * regs)164a545b48cSBrian Gerst int x64_setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs)
165a545b48cSBrian Gerst {
166a545b48cSBrian Gerst sigset_t *set = sigmask_to_save();
167a545b48cSBrian Gerst struct rt_sigframe __user *frame;
168a545b48cSBrian Gerst void __user *fp = NULL;
169a545b48cSBrian Gerst unsigned long uc_flags;
170a545b48cSBrian Gerst
171a545b48cSBrian Gerst /* x86-64 should always use SA_RESTORER. */
172a545b48cSBrian Gerst if (!(ksig->ka.sa.sa_flags & SA_RESTORER))
173a545b48cSBrian Gerst return -EFAULT;
174a545b48cSBrian Gerst
175a545b48cSBrian Gerst frame = get_sigframe(ksig, regs, sizeof(struct rt_sigframe), &fp);
176a545b48cSBrian Gerst uc_flags = frame_uc_flags(regs);
177a545b48cSBrian Gerst
178a545b48cSBrian Gerst if (!user_access_begin(frame, sizeof(*frame)))
179a545b48cSBrian Gerst return -EFAULT;
180a545b48cSBrian Gerst
181a545b48cSBrian Gerst /* Create the ucontext. */
182a545b48cSBrian Gerst unsafe_put_user(uc_flags, &frame->uc.uc_flags, Efault);
183a545b48cSBrian Gerst unsafe_put_user(0, &frame->uc.uc_link, Efault);
184a545b48cSBrian Gerst unsafe_save_altstack(&frame->uc.uc_stack, regs->sp, Efault);
185a545b48cSBrian Gerst
186a545b48cSBrian Gerst /* Set up to return from userspace. If provided, use a stub
187a545b48cSBrian Gerst already in userspace. */
188a545b48cSBrian Gerst unsafe_put_user(ksig->ka.sa.sa_restorer, &frame->pretcode, Efault);
189a545b48cSBrian Gerst unsafe_put_sigcontext(&frame->uc.uc_mcontext, fp, regs, set, Efault);
190a545b48cSBrian Gerst unsafe_put_sigmask(set, frame, Efault);
191a545b48cSBrian Gerst user_access_end();
192a545b48cSBrian Gerst
193a545b48cSBrian Gerst if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
194a545b48cSBrian Gerst if (copy_siginfo_to_user(&frame->info, &ksig->info))
195a545b48cSBrian Gerst return -EFAULT;
196a545b48cSBrian Gerst }
197a545b48cSBrian Gerst
1984cb2be4cSRick Edgecombe if (setup_signal_shadow_stack(ksig))
1994cb2be4cSRick Edgecombe return -EFAULT;
2004cb2be4cSRick Edgecombe
201a545b48cSBrian Gerst /* Set up registers for signal handler */
202a545b48cSBrian Gerst regs->di = ksig->sig;
203a545b48cSBrian Gerst /* In case the signal handler was declared without prototypes */
204a545b48cSBrian Gerst regs->ax = 0;
205a545b48cSBrian Gerst
206a545b48cSBrian Gerst /* This also works for non SA_SIGINFO handlers because they expect the
207a545b48cSBrian Gerst next argument after the signal number on the stack. */
208a545b48cSBrian Gerst regs->si = (unsigned long)&frame->info;
209a545b48cSBrian Gerst regs->dx = (unsigned long)&frame->uc;
210a545b48cSBrian Gerst regs->ip = (unsigned long) ksig->ka.sa.sa_handler;
211a545b48cSBrian Gerst
212a545b48cSBrian Gerst regs->sp = (unsigned long)frame;
213a545b48cSBrian Gerst
214a545b48cSBrian Gerst /*
215a545b48cSBrian Gerst * Set up the CS and SS registers to run signal handlers in
216a545b48cSBrian Gerst * 64-bit mode, even if the handler happens to be interrupting
217a545b48cSBrian Gerst * 32-bit or 16-bit code.
218a545b48cSBrian Gerst *
219a545b48cSBrian Gerst * SS is subtle. In 64-bit mode, we don't need any particular
220a545b48cSBrian Gerst * SS descriptor, but we do need SS to be valid. It's possible
221a545b48cSBrian Gerst * that the old SS is entirely bogus -- this can happen if the
222a545b48cSBrian Gerst * signal we're trying to deliver is #GP or #SS caused by a bad
223a545b48cSBrian Gerst * SS value. We also have a compatibility issue here: DOSEMU
224a545b48cSBrian Gerst * relies on the contents of the SS register indicating the
225a545b48cSBrian Gerst * SS value at the time of the signal, even though that code in
226a545b48cSBrian Gerst * DOSEMU predates sigreturn's ability to restore SS. (DOSEMU
227a545b48cSBrian Gerst * avoids relying on sigreturn to restore SS; instead it uses
228a545b48cSBrian Gerst * a trampoline.) So we do our best: if the old SS was valid,
229a545b48cSBrian Gerst * we keep it. Otherwise we replace it.
230a545b48cSBrian Gerst */
231a545b48cSBrian Gerst regs->cs = __USER_CS;
232a545b48cSBrian Gerst
233a545b48cSBrian Gerst if (unlikely(regs->ss != __USER_DS))
234a545b48cSBrian Gerst force_valid_ss(regs);
235a545b48cSBrian Gerst
236a545b48cSBrian Gerst return 0;
237a545b48cSBrian Gerst
238a545b48cSBrian Gerst Efault:
239a545b48cSBrian Gerst user_access_end();
240a545b48cSBrian Gerst return -EFAULT;
241a545b48cSBrian Gerst }
242a545b48cSBrian Gerst
243a545b48cSBrian Gerst /*
244a545b48cSBrian Gerst * Do a signal return; undo the signal stack.
245a545b48cSBrian Gerst */
SYSCALL_DEFINE0(rt_sigreturn)246a545b48cSBrian Gerst SYSCALL_DEFINE0(rt_sigreturn)
247a545b48cSBrian Gerst {
248a545b48cSBrian Gerst struct pt_regs *regs = current_pt_regs();
249a545b48cSBrian Gerst struct rt_sigframe __user *frame;
250a545b48cSBrian Gerst sigset_t set;
251a545b48cSBrian Gerst unsigned long uc_flags;
252a545b48cSBrian Gerst
253a545b48cSBrian Gerst frame = (struct rt_sigframe __user *)(regs->sp - sizeof(long));
254a545b48cSBrian Gerst if (!access_ok(frame, sizeof(*frame)))
255a545b48cSBrian Gerst goto badframe;
256a545b48cSBrian Gerst if (__get_user(*(__u64 *)&set, (__u64 __user *)&frame->uc.uc_sigmask))
257a545b48cSBrian Gerst goto badframe;
258a545b48cSBrian Gerst if (__get_user(uc_flags, &frame->uc.uc_flags))
259a545b48cSBrian Gerst goto badframe;
260a545b48cSBrian Gerst
261a545b48cSBrian Gerst set_current_blocked(&set);
262a545b48cSBrian Gerst
263*407abc7eSAruna Ramakrishna if (restore_altstack(&frame->uc.uc_stack))
264*407abc7eSAruna Ramakrishna goto badframe;
265*407abc7eSAruna Ramakrishna
266a545b48cSBrian Gerst if (!restore_sigcontext(regs, &frame->uc.uc_mcontext, uc_flags))
267a545b48cSBrian Gerst goto badframe;
268a545b48cSBrian Gerst
26905e36022SRick Edgecombe if (restore_signal_shadow_stack())
27005e36022SRick Edgecombe goto badframe;
27105e36022SRick Edgecombe
272a545b48cSBrian Gerst return regs->ax;
273a545b48cSBrian Gerst
274a545b48cSBrian Gerst badframe:
275a545b48cSBrian Gerst signal_fault(regs, frame, "rt_sigreturn");
276a545b48cSBrian Gerst return 0;
277a545b48cSBrian Gerst }
278a545b48cSBrian Gerst
279a545b48cSBrian Gerst #ifdef CONFIG_X86_X32_ABI
x32_copy_siginfo_to_user(struct compat_siginfo __user * to,const struct kernel_siginfo * from)280a545b48cSBrian Gerst static int x32_copy_siginfo_to_user(struct compat_siginfo __user *to,
281a545b48cSBrian Gerst const struct kernel_siginfo *from)
282a545b48cSBrian Gerst {
283a545b48cSBrian Gerst struct compat_siginfo new;
284a545b48cSBrian Gerst
285a545b48cSBrian Gerst copy_siginfo_to_external32(&new, from);
286a545b48cSBrian Gerst if (from->si_signo == SIGCHLD) {
287a545b48cSBrian Gerst new._sifields._sigchld_x32._utime = from->si_utime;
288a545b48cSBrian Gerst new._sifields._sigchld_x32._stime = from->si_stime;
289a545b48cSBrian Gerst }
290a545b48cSBrian Gerst if (copy_to_user(to, &new, sizeof(struct compat_siginfo)))
291a545b48cSBrian Gerst return -EFAULT;
292a545b48cSBrian Gerst return 0;
293a545b48cSBrian Gerst }
294a545b48cSBrian Gerst
copy_siginfo_to_user32(struct compat_siginfo __user * to,const struct kernel_siginfo * from)295a545b48cSBrian Gerst int copy_siginfo_to_user32(struct compat_siginfo __user *to,
296a545b48cSBrian Gerst const struct kernel_siginfo *from)
297a545b48cSBrian Gerst {
298a545b48cSBrian Gerst if (in_x32_syscall())
299a545b48cSBrian Gerst return x32_copy_siginfo_to_user(to, from);
300a545b48cSBrian Gerst return __copy_siginfo_to_user32(to, from);
301a545b48cSBrian Gerst }
302a545b48cSBrian Gerst
x32_setup_rt_frame(struct ksignal * ksig,struct pt_regs * regs)303a545b48cSBrian Gerst int x32_setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs)
304a545b48cSBrian Gerst {
305a545b48cSBrian Gerst compat_sigset_t *set = (compat_sigset_t *) sigmask_to_save();
306a545b48cSBrian Gerst struct rt_sigframe_x32 __user *frame;
307a545b48cSBrian Gerst unsigned long uc_flags;
308a545b48cSBrian Gerst void __user *restorer;
309a545b48cSBrian Gerst void __user *fp = NULL;
310a545b48cSBrian Gerst
311a545b48cSBrian Gerst if (!(ksig->ka.sa.sa_flags & SA_RESTORER))
312a545b48cSBrian Gerst return -EFAULT;
313a545b48cSBrian Gerst
314a545b48cSBrian Gerst frame = get_sigframe(ksig, regs, sizeof(*frame), &fp);
315a545b48cSBrian Gerst
316a545b48cSBrian Gerst uc_flags = frame_uc_flags(regs);
317a545b48cSBrian Gerst
318a545b48cSBrian Gerst if (!user_access_begin(frame, sizeof(*frame)))
319a545b48cSBrian Gerst return -EFAULT;
320a545b48cSBrian Gerst
321a545b48cSBrian Gerst /* Create the ucontext. */
322a545b48cSBrian Gerst unsafe_put_user(uc_flags, &frame->uc.uc_flags, Efault);
323a545b48cSBrian Gerst unsafe_put_user(0, &frame->uc.uc_link, Efault);
324a545b48cSBrian Gerst unsafe_compat_save_altstack(&frame->uc.uc_stack, regs->sp, Efault);
325a545b48cSBrian Gerst unsafe_put_user(0, &frame->uc.uc__pad0, Efault);
326a545b48cSBrian Gerst restorer = ksig->ka.sa.sa_restorer;
327a545b48cSBrian Gerst unsafe_put_user(restorer, (unsigned long __user *)&frame->pretcode, Efault);
328a545b48cSBrian Gerst unsafe_put_sigcontext(&frame->uc.uc_mcontext, fp, regs, set, Efault);
329a545b48cSBrian Gerst unsafe_put_sigmask(set, frame, Efault);
330a545b48cSBrian Gerst user_access_end();
331a545b48cSBrian Gerst
332a545b48cSBrian Gerst if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
333a545b48cSBrian Gerst if (x32_copy_siginfo_to_user(&frame->info, &ksig->info))
334a545b48cSBrian Gerst return -EFAULT;
335a545b48cSBrian Gerst }
336a545b48cSBrian Gerst
337a545b48cSBrian Gerst /* Set up registers for signal handler */
338a545b48cSBrian Gerst regs->sp = (unsigned long) frame;
339a545b48cSBrian Gerst regs->ip = (unsigned long) ksig->ka.sa.sa_handler;
340a545b48cSBrian Gerst
341a545b48cSBrian Gerst /* We use the x32 calling convention here... */
342a545b48cSBrian Gerst regs->di = ksig->sig;
343a545b48cSBrian Gerst regs->si = (unsigned long) &frame->info;
344a545b48cSBrian Gerst regs->dx = (unsigned long) &frame->uc;
345a545b48cSBrian Gerst
346a545b48cSBrian Gerst loadsegment(ds, __USER_DS);
347a545b48cSBrian Gerst loadsegment(es, __USER_DS);
348a545b48cSBrian Gerst
349a545b48cSBrian Gerst regs->cs = __USER_CS;
350a545b48cSBrian Gerst regs->ss = __USER_DS;
351a545b48cSBrian Gerst
352a545b48cSBrian Gerst return 0;
353a545b48cSBrian Gerst
354a545b48cSBrian Gerst Efault:
355a545b48cSBrian Gerst user_access_end();
356a545b48cSBrian Gerst return -EFAULT;
357a545b48cSBrian Gerst }
358a545b48cSBrian Gerst
COMPAT_SYSCALL_DEFINE0(x32_rt_sigreturn)359a545b48cSBrian Gerst COMPAT_SYSCALL_DEFINE0(x32_rt_sigreturn)
360a545b48cSBrian Gerst {
361a545b48cSBrian Gerst struct pt_regs *regs = current_pt_regs();
362a545b48cSBrian Gerst struct rt_sigframe_x32 __user *frame;
363a545b48cSBrian Gerst sigset_t set;
364a545b48cSBrian Gerst unsigned long uc_flags;
365a545b48cSBrian Gerst
366a545b48cSBrian Gerst frame = (struct rt_sigframe_x32 __user *)(regs->sp - 8);
367a545b48cSBrian Gerst
368a545b48cSBrian Gerst if (!access_ok(frame, sizeof(*frame)))
369a545b48cSBrian Gerst goto badframe;
370a545b48cSBrian Gerst if (__get_user(set.sig[0], (__u64 __user *)&frame->uc.uc_sigmask))
371a545b48cSBrian Gerst goto badframe;
372a545b48cSBrian Gerst if (__get_user(uc_flags, &frame->uc.uc_flags))
373a545b48cSBrian Gerst goto badframe;
374a545b48cSBrian Gerst
375a545b48cSBrian Gerst set_current_blocked(&set);
376a545b48cSBrian Gerst
377a545b48cSBrian Gerst if (!restore_sigcontext(regs, &frame->uc.uc_mcontext, uc_flags))
378a545b48cSBrian Gerst goto badframe;
379a545b48cSBrian Gerst
380a545b48cSBrian Gerst if (compat_restore_altstack(&frame->uc.uc_stack))
381a545b48cSBrian Gerst goto badframe;
382a545b48cSBrian Gerst
383a545b48cSBrian Gerst return regs->ax;
384a545b48cSBrian Gerst
385a545b48cSBrian Gerst badframe:
386a545b48cSBrian Gerst signal_fault(regs, frame, "x32 rt_sigreturn");
387a545b48cSBrian Gerst return 0;
388a545b48cSBrian Gerst }
389a545b48cSBrian Gerst #endif /* CONFIG_X86_X32_ABI */
390f6e2a56cSBrian Gerst
3916be9a8f1SBrian Gerst #ifdef CONFIG_COMPAT
sigaction_compat_abi(struct k_sigaction * act,struct k_sigaction * oact)3926be9a8f1SBrian Gerst void sigaction_compat_abi(struct k_sigaction *act, struct k_sigaction *oact)
3936be9a8f1SBrian Gerst {
3946be9a8f1SBrian Gerst if (!act)
3956be9a8f1SBrian Gerst return;
3966be9a8f1SBrian Gerst
3976be9a8f1SBrian Gerst if (in_ia32_syscall())
3986be9a8f1SBrian Gerst act->sa.sa_flags |= SA_IA32_ABI;
3996be9a8f1SBrian Gerst if (in_x32_syscall())
4006be9a8f1SBrian Gerst act->sa.sa_flags |= SA_X32_ABI;
4016be9a8f1SBrian Gerst }
4026be9a8f1SBrian Gerst #endif /* CONFIG_COMPAT */
4036be9a8f1SBrian Gerst
404f6e2a56cSBrian Gerst /*
405f6e2a56cSBrian Gerst * If adding a new si_code, there is probably new data in
406f6e2a56cSBrian Gerst * the siginfo. Make sure folks bumping the si_code
407f6e2a56cSBrian Gerst * limits also have to look at this code. Make sure any
408f6e2a56cSBrian Gerst * new fields are handled in copy_siginfo_to_user32()!
409f6e2a56cSBrian Gerst */
410f6e2a56cSBrian Gerst static_assert(NSIGILL == 11);
411f6e2a56cSBrian Gerst static_assert(NSIGFPE == 15);
412a5f6c2acSRick Edgecombe static_assert(NSIGSEGV == 10);
413f6e2a56cSBrian Gerst static_assert(NSIGBUS == 5);
414f6e2a56cSBrian Gerst static_assert(NSIGTRAP == 6);
415f6e2a56cSBrian Gerst static_assert(NSIGCHLD == 6);
416f6e2a56cSBrian Gerst static_assert(NSIGSYS == 2);
417f6e2a56cSBrian Gerst
418f6e2a56cSBrian Gerst /* This is part of the ABI and can never change in size: */
419f6e2a56cSBrian Gerst static_assert(sizeof(siginfo_t) == 128);
420f6e2a56cSBrian Gerst
421f6e2a56cSBrian Gerst /* This is a part of the ABI and can never change in alignment */
422f6e2a56cSBrian Gerst static_assert(__alignof__(siginfo_t) == 8);
423f6e2a56cSBrian Gerst
424f6e2a56cSBrian Gerst /*
425f6e2a56cSBrian Gerst * The offsets of all the (unioned) si_fields are fixed
426f6e2a56cSBrian Gerst * in the ABI, of course. Make sure none of them ever
427f6e2a56cSBrian Gerst * move and are always at the beginning:
428f6e2a56cSBrian Gerst */
429f6e2a56cSBrian Gerst static_assert(offsetof(siginfo_t, si_signo) == 0);
430f6e2a56cSBrian Gerst static_assert(offsetof(siginfo_t, si_errno) == 4);
431f6e2a56cSBrian Gerst static_assert(offsetof(siginfo_t, si_code) == 8);
432f6e2a56cSBrian Gerst
433f6e2a56cSBrian Gerst /*
434f6e2a56cSBrian Gerst * Ensure that the size of each si_field never changes.
435f6e2a56cSBrian Gerst * If it does, it is a sign that the
436f6e2a56cSBrian Gerst * copy_siginfo_to_user32() code below needs to updated
437f6e2a56cSBrian Gerst * along with the size in the CHECK_SI_SIZE().
438f6e2a56cSBrian Gerst *
439f6e2a56cSBrian Gerst * We repeat this check for both the generic and compat
440f6e2a56cSBrian Gerst * siginfos.
441f6e2a56cSBrian Gerst *
442f6e2a56cSBrian Gerst * Note: it is OK for these to grow as long as the whole
443f6e2a56cSBrian Gerst * structure stays within the padding size (checked
444f6e2a56cSBrian Gerst * above).
445f6e2a56cSBrian Gerst */
446f6e2a56cSBrian Gerst
447f6e2a56cSBrian Gerst #define CHECK_SI_OFFSET(name) \
448f6e2a56cSBrian Gerst static_assert(offsetof(siginfo_t, _sifields) == \
449f6e2a56cSBrian Gerst offsetof(siginfo_t, _sifields.name))
450f6e2a56cSBrian Gerst #define CHECK_SI_SIZE(name, size) \
451f6e2a56cSBrian Gerst static_assert(sizeof_field(siginfo_t, _sifields.name) == size)
452f6e2a56cSBrian Gerst
453f6e2a56cSBrian Gerst CHECK_SI_OFFSET(_kill);
454f6e2a56cSBrian Gerst CHECK_SI_SIZE (_kill, 2*sizeof(int));
455f6e2a56cSBrian Gerst static_assert(offsetof(siginfo_t, si_pid) == 0x10);
456f6e2a56cSBrian Gerst static_assert(offsetof(siginfo_t, si_uid) == 0x14);
457f6e2a56cSBrian Gerst
458f6e2a56cSBrian Gerst CHECK_SI_OFFSET(_timer);
459f6e2a56cSBrian Gerst CHECK_SI_SIZE (_timer, 6*sizeof(int));
460f6e2a56cSBrian Gerst static_assert(offsetof(siginfo_t, si_tid) == 0x10);
461f6e2a56cSBrian Gerst static_assert(offsetof(siginfo_t, si_overrun) == 0x14);
462f6e2a56cSBrian Gerst static_assert(offsetof(siginfo_t, si_value) == 0x18);
463f6e2a56cSBrian Gerst
464f6e2a56cSBrian Gerst CHECK_SI_OFFSET(_rt);
465f6e2a56cSBrian Gerst CHECK_SI_SIZE (_rt, 4*sizeof(int));
466f6e2a56cSBrian Gerst static_assert(offsetof(siginfo_t, si_pid) == 0x10);
467f6e2a56cSBrian Gerst static_assert(offsetof(siginfo_t, si_uid) == 0x14);
468f6e2a56cSBrian Gerst static_assert(offsetof(siginfo_t, si_value) == 0x18);
469f6e2a56cSBrian Gerst
470f6e2a56cSBrian Gerst CHECK_SI_OFFSET(_sigchld);
471f6e2a56cSBrian Gerst CHECK_SI_SIZE (_sigchld, 8*sizeof(int));
472f6e2a56cSBrian Gerst static_assert(offsetof(siginfo_t, si_pid) == 0x10);
473f6e2a56cSBrian Gerst static_assert(offsetof(siginfo_t, si_uid) == 0x14);
474f6e2a56cSBrian Gerst static_assert(offsetof(siginfo_t, si_status) == 0x18);
475f6e2a56cSBrian Gerst static_assert(offsetof(siginfo_t, si_utime) == 0x20);
476f6e2a56cSBrian Gerst static_assert(offsetof(siginfo_t, si_stime) == 0x28);
477f6e2a56cSBrian Gerst
478f6e2a56cSBrian Gerst #ifdef CONFIG_X86_X32_ABI
479f6e2a56cSBrian Gerst /* no _sigchld_x32 in the generic siginfo_t */
480f6e2a56cSBrian Gerst static_assert(sizeof_field(compat_siginfo_t, _sifields._sigchld_x32) ==
481f6e2a56cSBrian Gerst 7*sizeof(int));
482f6e2a56cSBrian Gerst static_assert(offsetof(compat_siginfo_t, _sifields) ==
483f6e2a56cSBrian Gerst offsetof(compat_siginfo_t, _sifields._sigchld_x32));
484f6e2a56cSBrian Gerst static_assert(offsetof(compat_siginfo_t, _sifields._sigchld_x32._utime) == 0x18);
485f6e2a56cSBrian Gerst static_assert(offsetof(compat_siginfo_t, _sifields._sigchld_x32._stime) == 0x20);
486f6e2a56cSBrian Gerst #endif
487f6e2a56cSBrian Gerst
488f6e2a56cSBrian Gerst CHECK_SI_OFFSET(_sigfault);
489f6e2a56cSBrian Gerst CHECK_SI_SIZE (_sigfault, 8*sizeof(int));
490f6e2a56cSBrian Gerst static_assert(offsetof(siginfo_t, si_addr) == 0x10);
491f6e2a56cSBrian Gerst
492f6e2a56cSBrian Gerst static_assert(offsetof(siginfo_t, si_trapno) == 0x18);
493f6e2a56cSBrian Gerst
494f6e2a56cSBrian Gerst static_assert(offsetof(siginfo_t, si_addr_lsb) == 0x18);
495f6e2a56cSBrian Gerst
496f6e2a56cSBrian Gerst static_assert(offsetof(siginfo_t, si_lower) == 0x20);
497f6e2a56cSBrian Gerst static_assert(offsetof(siginfo_t, si_upper) == 0x28);
498f6e2a56cSBrian Gerst
499f6e2a56cSBrian Gerst static_assert(offsetof(siginfo_t, si_pkey) == 0x20);
500f6e2a56cSBrian Gerst
501f6e2a56cSBrian Gerst static_assert(offsetof(siginfo_t, si_perf_data) == 0x18);
502f6e2a56cSBrian Gerst static_assert(offsetof(siginfo_t, si_perf_type) == 0x20);
503f6e2a56cSBrian Gerst static_assert(offsetof(siginfo_t, si_perf_flags) == 0x24);
504f6e2a56cSBrian Gerst
505f6e2a56cSBrian Gerst CHECK_SI_OFFSET(_sigpoll);
506f6e2a56cSBrian Gerst CHECK_SI_SIZE (_sigpoll, 4*sizeof(int));
507f6e2a56cSBrian Gerst static_assert(offsetof(siginfo_t, si_band) == 0x10);
508f6e2a56cSBrian Gerst static_assert(offsetof(siginfo_t, si_fd) == 0x18);
509f6e2a56cSBrian Gerst
510f6e2a56cSBrian Gerst CHECK_SI_OFFSET(_sigsys);
511f6e2a56cSBrian Gerst CHECK_SI_SIZE (_sigsys, 4*sizeof(int));
512f6e2a56cSBrian Gerst static_assert(offsetof(siginfo_t, si_call_addr) == 0x10);
513f6e2a56cSBrian Gerst static_assert(offsetof(siginfo_t, si_syscall) == 0x18);
514f6e2a56cSBrian Gerst static_assert(offsetof(siginfo_t, si_arch) == 0x1C);
515f6e2a56cSBrian Gerst
516f6e2a56cSBrian Gerst /* any new si_fields should be added here */
517