a9fe8d6f72c31eb3cb51404fe2714ea4b8292611
[safe/jmp/linux-2.6] / arch / um / sys-i386 / signal.c
1 /*
2  * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com)
3  * Licensed under the GPL
4  */
5
6 #include "linux/signal.h"
7 #include "linux/ptrace.h"
8 #include "asm/current.h"
9 #include "asm/ucontext.h"
10 #include "asm/uaccess.h"
11 #include "asm/unistd.h"
12 #include "frame_kern.h"
13 #include "sigcontext.h"
14 #include "registers.h"
15 #include "skas.h"
16
17 void copy_sc(union uml_pt_regs *regs, void *from)
18 {
19         struct sigcontext *sc = from;
20
21         REGS_GS(regs->skas.regs) = sc->gs;
22         REGS_FS(regs->skas.regs) = sc->fs;
23         REGS_ES(regs->skas.regs) = sc->es;
24         REGS_DS(regs->skas.regs) = sc->ds;
25         REGS_EDI(regs->skas.regs) = sc->edi;
26         REGS_ESI(regs->skas.regs) = sc->esi;
27         REGS_EBP(regs->skas.regs) = sc->ebp;
28         REGS_SP(regs->skas.regs) = sc->esp;
29         REGS_EBX(regs->skas.regs) = sc->ebx;
30         REGS_EDX(regs->skas.regs) = sc->edx;
31         REGS_ECX(regs->skas.regs) = sc->ecx;
32         REGS_EAX(regs->skas.regs) = sc->eax;
33         REGS_IP(regs->skas.regs) = sc->eip;
34         REGS_CS(regs->skas.regs) = sc->cs;
35         REGS_EFLAGS(regs->skas.regs) = sc->eflags;
36         REGS_SS(regs->skas.regs) = sc->ss;
37 }
38
39 static int copy_sc_from_user_skas(struct pt_regs *regs,
40                                   struct sigcontext __user *from)
41 {
42         struct sigcontext sc;
43         unsigned long fpregs[HOST_FP_SIZE];
44         int err;
45
46         err = copy_from_user(&sc, from, sizeof(sc));
47         err |= copy_from_user(fpregs, sc.fpstate, sizeof(fpregs));
48         if(err)
49                 return err;
50
51         copy_sc(&regs->regs, &sc);
52
53         err = restore_fp_registers(userspace_pid[0], fpregs);
54         if(err < 0) {
55                 printk("copy_sc_from_user_skas - PTRACE_SETFPREGS failed, "
56                        "errno = %d\n", -err);
57                 return err;
58         }
59
60         return 0;
61 }
62
63 int copy_sc_to_user_skas(struct sigcontext __user *to, struct _fpstate __user *to_fp,
64                          struct pt_regs *regs, unsigned long sp)
65 {
66         struct sigcontext sc;
67         unsigned long fpregs[HOST_FP_SIZE];
68         struct faultinfo * fi = &current->thread.arch.faultinfo;
69         int err;
70
71         sc.gs = REGS_GS(regs->regs.skas.regs);
72         sc.fs = REGS_FS(regs->regs.skas.regs);
73         sc.es = REGS_ES(regs->regs.skas.regs);
74         sc.ds = REGS_DS(regs->regs.skas.regs);
75         sc.edi = REGS_EDI(regs->regs.skas.regs);
76         sc.esi = REGS_ESI(regs->regs.skas.regs);
77         sc.ebp = REGS_EBP(regs->regs.skas.regs);
78         sc.esp = sp;
79         sc.ebx = REGS_EBX(regs->regs.skas.regs);
80         sc.edx = REGS_EDX(regs->regs.skas.regs);
81         sc.ecx = REGS_ECX(regs->regs.skas.regs);
82         sc.eax = REGS_EAX(regs->regs.skas.regs);
83         sc.eip = REGS_IP(regs->regs.skas.regs);
84         sc.cs = REGS_CS(regs->regs.skas.regs);
85         sc.eflags = REGS_EFLAGS(regs->regs.skas.regs);
86         sc.esp_at_signal = regs->regs.skas.regs[UESP];
87         sc.ss = regs->regs.skas.regs[SS];
88         sc.cr2 = fi->cr2;
89         sc.err = fi->error_code;
90         sc.trapno = fi->trap_no;
91
92         err = save_fp_registers(userspace_pid[0], fpregs);
93         if(err < 0){
94                 printk("copy_sc_to_user_skas - PTRACE_GETFPREGS failed, "
95                        "errno = %d\n", err);
96                 return 1;
97         }
98         to_fp = (to_fp ? to_fp : (struct _fpstate __user *) (to + 1));
99         sc.fpstate = to_fp;
100
101         if(err)
102                 return err;
103
104         return copy_to_user(to, &sc, sizeof(sc)) ||
105                copy_to_user(to_fp, fpregs, sizeof(fpregs));
106 }
107
108 static int copy_sc_from_user(struct pt_regs *to, void __user *from)
109 {
110         return copy_sc_from_user_skas(to, from);
111 }
112
113 static int copy_sc_to_user(struct sigcontext __user *to, struct _fpstate __user *fp,
114                            struct pt_regs *from, unsigned long sp)
115 {
116         return copy_sc_to_user_skas(to, fp, from, sp);
117 }
118
119 static int copy_ucontext_to_user(struct ucontext __user *uc, struct _fpstate __user *fp,
120                                  sigset_t *set, unsigned long sp)
121 {
122         int err = 0;
123
124         err |= put_user(current->sas_ss_sp, &uc->uc_stack.ss_sp);
125         err |= put_user(sas_ss_flags(sp), &uc->uc_stack.ss_flags);
126         err |= put_user(current->sas_ss_size, &uc->uc_stack.ss_size);
127         err |= copy_sc_to_user(&uc->uc_mcontext, fp, &current->thread.regs, sp);
128         err |= copy_to_user(&uc->uc_sigmask, set, sizeof(*set));
129         return err;
130 }
131
132 struct sigframe
133 {
134         char __user *pretcode;
135         int sig;
136         struct sigcontext sc;
137         struct _fpstate fpstate;
138         unsigned long extramask[_NSIG_WORDS-1];
139         char retcode[8];
140 };
141
142 struct rt_sigframe
143 {
144         char __user *pretcode;
145         int sig;
146         struct siginfo __user *pinfo;
147         void __user *puc;
148         struct siginfo info;
149         struct ucontext uc;
150         struct _fpstate fpstate;
151         char retcode[8];
152 };
153
154 int setup_signal_stack_sc(unsigned long stack_top, int sig,
155                           struct k_sigaction *ka, struct pt_regs *regs,
156                           sigset_t *mask)
157 {
158         struct sigframe __user *frame;
159         void __user *restorer;
160         unsigned long save_sp = PT_REGS_SP(regs);
161         int err = 0;
162
163         /* This is the same calculation as i386 - ((sp + 4) & 15) == 0 */
164         stack_top = ((stack_top + 4) & -16UL) - 4;
165         frame = (struct sigframe __user *) stack_top - 1;
166         if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
167                 return 1;
168
169         restorer = frame->retcode;
170         if(ka->sa.sa_flags & SA_RESTORER)
171                 restorer = ka->sa.sa_restorer;
172
173         /* Update SP now because the page fault handler refuses to extend
174          * the stack if the faulting address is too far below the current
175          * SP, which frame now certainly is.  If there's an error, the original
176          * value is restored on the way out.
177          * When writing the sigcontext to the stack, we have to write the
178          * original value, so that's passed to copy_sc_to_user, which does
179          * the right thing with it.
180          */
181         PT_REGS_SP(regs) = (unsigned long) frame;
182
183         err |= __put_user(restorer, &frame->pretcode);
184         err |= __put_user(sig, &frame->sig);
185         err |= copy_sc_to_user(&frame->sc, NULL, regs, save_sp);
186         err |= __put_user(mask->sig[0], &frame->sc.oldmask);
187         if (_NSIG_WORDS > 1)
188                 err |= __copy_to_user(&frame->extramask, &mask->sig[1],
189                                       sizeof(frame->extramask));
190
191         /*
192          * This is popl %eax ; movl $,%eax ; int $0x80
193          *
194          * WE DO NOT USE IT ANY MORE! It's only left here for historical
195          * reasons and because gdb uses it as a signature to notice
196          * signal handler stack frames.
197          */
198         err |= __put_user(0xb858, (short __user *)(frame->retcode+0));
199         err |= __put_user(__NR_sigreturn, (int __user *)(frame->retcode+2));
200         err |= __put_user(0x80cd, (short __user *)(frame->retcode+6));
201
202         if(err)
203                 goto err;
204
205         PT_REGS_SP(regs) = (unsigned long) frame;
206         PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler;
207         PT_REGS_EAX(regs) = (unsigned long) sig;
208         PT_REGS_EDX(regs) = (unsigned long) 0;
209         PT_REGS_ECX(regs) = (unsigned long) 0;
210
211         if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED))
212                 ptrace_notify(SIGTRAP);
213         return 0;
214
215 err:
216         PT_REGS_SP(regs) = save_sp;
217         return err;
218 }
219
220 int setup_signal_stack_si(unsigned long stack_top, int sig,
221                           struct k_sigaction *ka, struct pt_regs *regs,
222                           siginfo_t *info, sigset_t *mask)
223 {
224         struct rt_sigframe __user *frame;
225         void __user *restorer;
226         unsigned long save_sp = PT_REGS_SP(regs);
227         int err = 0;
228
229         stack_top &= -8UL;
230         frame = (struct rt_sigframe __user *) stack_top - 1;
231         if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
232                 return 1;
233
234         restorer = frame->retcode;
235         if(ka->sa.sa_flags & SA_RESTORER)
236                 restorer = ka->sa.sa_restorer;
237
238         /* See comment above about why this is here */
239         PT_REGS_SP(regs) = (unsigned long) frame;
240
241         err |= __put_user(restorer, &frame->pretcode);
242         err |= __put_user(sig, &frame->sig);
243         err |= __put_user(&frame->info, &frame->pinfo);
244         err |= __put_user(&frame->uc, &frame->puc);
245         err |= copy_siginfo_to_user(&frame->info, info);
246         err |= copy_ucontext_to_user(&frame->uc, &frame->fpstate, mask,
247                                      save_sp);
248
249         /*
250          * This is movl $,%eax ; int $0x80
251          *
252          * WE DO NOT USE IT ANY MORE! It's only left here for historical
253          * reasons and because gdb uses it as a signature to notice
254          * signal handler stack frames.
255          */
256         err |= __put_user(0xb8, (char __user *)(frame->retcode+0));
257         err |= __put_user(__NR_rt_sigreturn, (int __user *)(frame->retcode+1));
258         err |= __put_user(0x80cd, (short __user *)(frame->retcode+5));
259
260         if(err)
261                 goto err;
262
263         PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler;
264         PT_REGS_EAX(regs) = (unsigned long) sig;
265         PT_REGS_EDX(regs) = (unsigned long) &frame->info;
266         PT_REGS_ECX(regs) = (unsigned long) &frame->uc;
267
268         if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED))
269                 ptrace_notify(SIGTRAP);
270         return 0;
271
272 err:
273         PT_REGS_SP(regs) = save_sp;
274         return err;
275 }
276
277 long sys_sigreturn(struct pt_regs regs)
278 {
279         unsigned long sp = PT_REGS_SP(&current->thread.regs);
280         struct sigframe __user *frame = (struct sigframe __user *)(sp - 8);
281         sigset_t set;
282         struct sigcontext __user *sc = &frame->sc;
283         unsigned long __user *oldmask = &sc->oldmask;
284         unsigned long __user *extramask = frame->extramask;
285         int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
286
287         if(copy_from_user(&set.sig[0], oldmask, sizeof(set.sig[0])) ||
288            copy_from_user(&set.sig[1], extramask, sig_size))
289                 goto segfault;
290
291         sigdelsetmask(&set, ~_BLOCKABLE);
292
293         spin_lock_irq(&current->sighand->siglock);
294         current->blocked = set;
295         recalc_sigpending();
296         spin_unlock_irq(&current->sighand->siglock);
297
298         if(copy_sc_from_user(&current->thread.regs, sc))
299                 goto segfault;
300
301         /* Avoid ERESTART handling */
302         PT_REGS_SYSCALL_NR(&current->thread.regs) = -1;
303         return PT_REGS_SYSCALL_RET(&current->thread.regs);
304
305  segfault:
306         force_sig(SIGSEGV, current);
307         return 0;
308 }
309
310 long sys_rt_sigreturn(struct pt_regs regs)
311 {
312         unsigned long sp = PT_REGS_SP(&current->thread.regs);
313         struct rt_sigframe __user *frame = (struct rt_sigframe __user *) (sp - 4);
314         sigset_t set;
315         struct ucontext __user *uc = &frame->uc;
316         int sig_size = _NSIG_WORDS * sizeof(unsigned long);
317
318         if(copy_from_user(&set, &uc->uc_sigmask, sig_size))
319                 goto segfault;
320
321         sigdelsetmask(&set, ~_BLOCKABLE);
322
323         spin_lock_irq(&current->sighand->siglock);
324         current->blocked = set;
325         recalc_sigpending();
326         spin_unlock_irq(&current->sighand->siglock);
327
328         if(copy_sc_from_user(&current->thread.regs, &uc->uc_mcontext))
329                 goto segfault;
330
331         /* Avoid ERESTART handling */
332         PT_REGS_SYSCALL_NR(&current->thread.regs) = -1;
333         return PT_REGS_SYSCALL_RET(&current->thread.regs);
334
335  segfault:
336         force_sig(SIGSEGV, current);
337         return 0;
338 }