]> err.no Git - linux-2.6/blob - arch/um/sys-x86_64/signal.c
uml: throw out CHOOSE_MODE
[linux-2.6] / arch / um / sys-x86_64 / signal.c
1 /*
2  * Copyright (C) 2003 PathScale, Inc.
3  * Licensed under the GPL
4  */
5
6 #include "linux/stddef.h"
7 #include "linux/errno.h"
8 #include "linux/personality.h"
9 #include "linux/ptrace.h"
10 #include "asm/current.h"
11 #include "asm/uaccess.h"
12 #include "asm/sigcontext.h"
13 #include "asm/ptrace.h"
14 #include "asm/arch/ucontext.h"
15 #include "sysdep/ptrace.h"
16 #include "frame_kern.h"
17 #include "skas.h"
18
19 void copy_sc(union uml_pt_regs *regs, void *from)
20 {
21         struct sigcontext *sc = from;
22
23 #define GETREG(regs, regno, sc, regname) \
24        (regs)->skas.regs[(regno) / sizeof(unsigned long)] = (sc)->regname
25
26        GETREG(regs, R8, sc, r8);
27        GETREG(regs, R9, sc, r9);
28        GETREG(regs, R10, sc, r10);
29        GETREG(regs, R11, sc, r11);
30        GETREG(regs, R12, sc, r12);
31        GETREG(regs, R13, sc, r13);
32        GETREG(regs, R14, sc, r14);
33        GETREG(regs, R15, sc, r15);
34        GETREG(regs, RDI, sc, rdi);
35        GETREG(regs, RSI, sc, rsi);
36        GETREG(regs, RBP, sc, rbp);
37        GETREG(regs, RBX, sc, rbx);
38        GETREG(regs, RDX, sc, rdx);
39        GETREG(regs, RAX, sc, rax);
40        GETREG(regs, RCX, sc, rcx);
41        GETREG(regs, RSP, sc, rsp);
42        GETREG(regs, RIP, sc, rip);
43        GETREG(regs, EFLAGS, sc, eflags);
44        GETREG(regs, CS, sc, cs);
45
46 #undef GETREG
47 }
48
49 static int copy_sc_from_user_skas(struct pt_regs *regs,
50                                  struct sigcontext __user *from)
51 {
52        int err = 0;
53
54 #define GETREG(regs, regno, sc, regname) \
55        __get_user((regs)->regs.skas.regs[(regno) / sizeof(unsigned long)], \
56                   &(sc)->regname)
57
58        err |= GETREG(regs, R8, from, r8);
59        err |= GETREG(regs, R9, from, r9);
60        err |= GETREG(regs, R10, from, r10);
61        err |= GETREG(regs, R11, from, r11);
62        err |= GETREG(regs, R12, from, r12);
63        err |= GETREG(regs, R13, from, r13);
64        err |= GETREG(regs, R14, from, r14);
65        err |= GETREG(regs, R15, from, r15);
66        err |= GETREG(regs, RDI, from, rdi);
67        err |= GETREG(regs, RSI, from, rsi);
68        err |= GETREG(regs, RBP, from, rbp);
69        err |= GETREG(regs, RBX, from, rbx);
70        err |= GETREG(regs, RDX, from, rdx);
71        err |= GETREG(regs, RAX, from, rax);
72        err |= GETREG(regs, RCX, from, rcx);
73        err |= GETREG(regs, RSP, from, rsp);
74        err |= GETREG(regs, RIP, from, rip);
75        err |= GETREG(regs, EFLAGS, from, eflags);
76        err |= GETREG(regs, CS, from, cs);
77
78 #undef GETREG
79
80        return err;
81 }
82
83 int copy_sc_to_user_skas(struct sigcontext __user *to,
84                          struct _fpstate __user *to_fp,
85                          struct pt_regs *regs, unsigned long mask,
86                          unsigned long sp)
87 {
88         struct faultinfo * fi = &current->thread.arch.faultinfo;
89         int err = 0;
90
91         err |= __put_user(0, &to->gs);
92         err |= __put_user(0, &to->fs);
93
94 #define PUTREG(regs, regno, sc, regname) \
95        __put_user((regs)->regs.skas.regs[(regno) / sizeof(unsigned long)], \
96                   &(sc)->regname)
97
98         err |= PUTREG(regs, RDI, to, rdi);
99         err |= PUTREG(regs, RSI, to, rsi);
100         err |= PUTREG(regs, RBP, to, rbp);
101         /* Must use orignal RSP, which is passed in, rather than what's in
102          * the pt_regs, because that's already been updated to point at the
103          * signal frame.
104          */
105         err |= __put_user(sp, &to->rsp);
106         err |= PUTREG(regs, RBX, to, rbx);
107         err |= PUTREG(regs, RDX, to, rdx);
108         err |= PUTREG(regs, RCX, to, rcx);
109         err |= PUTREG(regs, RAX, to, rax);
110         err |= PUTREG(regs, R8, to, r8);
111         err |= PUTREG(regs, R9, to, r9);
112         err |= PUTREG(regs, R10, to, r10);
113         err |= PUTREG(regs, R11, to, r11);
114         err |= PUTREG(regs, R12, to, r12);
115         err |= PUTREG(regs, R13, to, r13);
116         err |= PUTREG(regs, R14, to, r14);
117         err |= PUTREG(regs, R15, to, r15);
118         err |= PUTREG(regs, CS, to, cs); /* XXX x86_64 doesn't do this */
119
120         err |= __put_user(fi->cr2, &to->cr2);
121         err |= __put_user(fi->error_code, &to->err);
122         err |= __put_user(fi->trap_no, &to->trapno);
123
124         err |= PUTREG(regs, RIP, to, rip);
125         err |= PUTREG(regs, EFLAGS, to, eflags);
126 #undef PUTREG
127
128         err |= __put_user(mask, &to->oldmask);
129
130         return(err);
131 }
132
133 static int copy_sc_from_user(struct pt_regs *to, void __user *from)
134 {
135        int ret;
136
137        ret = copy_sc_from_user_skas(to, from);
138        return(ret);
139 }
140
141 static int copy_sc_to_user(struct sigcontext __user *to,
142                            struct _fpstate __user *fp,
143                            struct pt_regs *from, unsigned long mask,
144                            unsigned long sp)
145 {
146        return copy_sc_to_user_skas(to, fp, from, mask, sp);
147 }
148
149 struct rt_sigframe
150 {
151        char __user *pretcode;
152        struct ucontext uc;
153        struct siginfo info;
154 };
155
156 #define round_down(m, n) (((m) / (n)) * (n))
157
158 int setup_signal_stack_si(unsigned long stack_top, int sig,
159                           struct k_sigaction *ka, struct pt_regs * regs,
160                           siginfo_t *info, sigset_t *set)
161 {
162         struct rt_sigframe __user *frame;
163         struct _fpstate __user *fp = NULL;
164         unsigned long save_sp = PT_REGS_RSP(regs);
165         int err = 0;
166         struct task_struct *me = current;
167
168         frame = (struct rt_sigframe __user *)
169                 round_down(stack_top - sizeof(struct rt_sigframe), 16);
170         /* Subtract 128 for a red zone and 8 for proper alignment */
171         frame = (struct rt_sigframe __user *) ((unsigned long) frame - 128 - 8);
172
173         if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate)))
174                 goto out;
175
176 #if 0 /* XXX */
177         if (save_i387(fp) < 0)
178                 err |= -1;
179 #endif
180         if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
181                 goto out;
182
183         if (ka->sa.sa_flags & SA_SIGINFO) {
184                 err |= copy_siginfo_to_user(&frame->info, info);
185                 if (err)
186                         goto out;
187         }
188
189         /* Update SP now because the page fault handler refuses to extend
190          * the stack if the faulting address is too far below the current
191          * SP, which frame now certainly is.  If there's an error, the original
192          * value is restored on the way out.
193          * When writing the sigcontext to the stack, we have to write the
194          * original value, so that's passed to copy_sc_to_user, which does
195          * the right thing with it.
196          */
197         PT_REGS_RSP(regs) = (unsigned long) frame;
198
199         /* Create the ucontext.  */
200         err |= __put_user(0, &frame->uc.uc_flags);
201         err |= __put_user(0, &frame->uc.uc_link);
202         err |= __put_user(me->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
203         err |= __put_user(sas_ss_flags(save_sp),
204                           &frame->uc.uc_stack.ss_flags);
205         err |= __put_user(me->sas_ss_size, &frame->uc.uc_stack.ss_size);
206         err |= copy_sc_to_user(&frame->uc.uc_mcontext, fp, regs, set->sig[0],
207                 save_sp);
208         err |= __put_user(fp, &frame->uc.uc_mcontext.fpstate);
209         if (sizeof(*set) == 16) {
210                 __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
211                 __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
212         }
213         else
214                 err |= __copy_to_user(&frame->uc.uc_sigmask, set,
215                                       sizeof(*set));
216
217         /* Set up to return from userspace.  If provided, use a stub
218            already in userspace.  */
219         /* x86-64 should always use SA_RESTORER. */
220         if (ka->sa.sa_flags & SA_RESTORER)
221                 err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
222         else
223                 /* could use a vstub here */
224                 goto restore_sp;
225
226         if (err)
227                 goto restore_sp;
228
229         /* Set up registers for signal handler */
230         {
231                 struct exec_domain *ed = current_thread_info()->exec_domain;
232                 if (unlikely(ed && ed->signal_invmap && sig < 32))
233                         sig = ed->signal_invmap[sig];
234         }
235
236         PT_REGS_RDI(regs) = sig;
237         /* In case the signal handler was declared without prototypes */
238         PT_REGS_RAX(regs) = 0;
239
240         /* This also works for non SA_SIGINFO handlers because they expect the
241            next argument after the signal number on the stack. */
242         PT_REGS_RSI(regs) = (unsigned long) &frame->info;
243         PT_REGS_RDX(regs) = (unsigned long) &frame->uc;
244         PT_REGS_RIP(regs) = (unsigned long) ka->sa.sa_handler;
245  out:
246         return err;
247
248 restore_sp:
249         PT_REGS_RSP(regs) = save_sp;
250         return err;
251 }
252
253 long sys_rt_sigreturn(struct pt_regs *regs)
254 {
255         unsigned long sp = PT_REGS_SP(&current->thread.regs);
256         struct rt_sigframe __user *frame =
257                 (struct rt_sigframe __user *)(sp - 8);
258         struct ucontext __user *uc = &frame->uc;
259         sigset_t set;
260
261         if(copy_from_user(&set, &uc->uc_sigmask, sizeof(set)))
262                 goto segfault;
263
264         sigdelsetmask(&set, ~_BLOCKABLE);
265
266         spin_lock_irq(&current->sighand->siglock);
267         current->blocked = set;
268         recalc_sigpending();
269         spin_unlock_irq(&current->sighand->siglock);
270
271         if(copy_sc_from_user(&current->thread.regs, &uc->uc_mcontext))
272                 goto segfault;
273
274         /* Avoid ERESTART handling */
275         PT_REGS_SYSCALL_NR(&current->thread.regs) = -1;
276         return(PT_REGS_SYSCALL_RET(&current->thread.regs));
277
278  segfault:
279         force_sig(SIGSEGV, current);
280         return 0;
281 }
282 /*
283  * Overrides for Emacs so that we follow Linus's tabbing style.
284  * Emacs will notice this stuff at the end of the file and automatically
285  * adjust the settings for this buffer only.  This must remain at the end
286  * of the file.
287  * ---------------------------------------------------------------------------
288  * Local variables:
289  * c-file-style: "linux"
290  * End:
291  */