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