diff options
Diffstat (limited to 'arch/um/sys-i386/signal.c')
-rw-r--r-- | arch/um/sys-i386/signal.c | 62 |
1 files changed, 30 insertions, 32 deletions
diff --git a/arch/um/sys-i386/signal.c b/arch/um/sys-i386/signal.c index c64d48734e3a..c82e5f562ec6 100644 --- a/arch/um/sys-i386/signal.c +++ b/arch/um/sys-i386/signal.c | |||
@@ -1,17 +1,13 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com) | 2 | * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) |
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include "linux/signal.h" | ||
7 | #include "linux/ptrace.h" | 6 | #include "linux/ptrace.h" |
8 | #include "asm/current.h" | ||
9 | #include "asm/ucontext.h" | ||
10 | #include "asm/uaccess.h" | ||
11 | #include "asm/unistd.h" | 7 | #include "asm/unistd.h" |
8 | #include "asm/uaccess.h" | ||
9 | #include "asm/ucontext.h" | ||
12 | #include "frame_kern.h" | 10 | #include "frame_kern.h" |
13 | #include "sigcontext.h" | ||
14 | #include "registers.h" | ||
15 | #include "skas.h" | 11 | #include "skas.h" |
16 | 12 | ||
17 | void copy_sc(struct uml_pt_regs *regs, void *from) | 13 | void copy_sc(struct uml_pt_regs *regs, void *from) |
@@ -39,21 +35,21 @@ void copy_sc(struct uml_pt_regs *regs, void *from) | |||
39 | static int copy_sc_from_user(struct pt_regs *regs, | 35 | static int copy_sc_from_user(struct pt_regs *regs, |
40 | struct sigcontext __user *from) | 36 | struct sigcontext __user *from) |
41 | { | 37 | { |
42 | struct sigcontext sc; | 38 | struct sigcontext sc; |
43 | unsigned long fpregs[HOST_FP_SIZE]; | 39 | unsigned long fpregs[HOST_FP_SIZE]; |
44 | int err; | 40 | int err; |
45 | 41 | ||
46 | err = copy_from_user(&sc, from, sizeof(sc)); | 42 | err = copy_from_user(&sc, from, sizeof(sc)); |
47 | err |= copy_from_user(fpregs, sc.fpstate, sizeof(fpregs)); | 43 | err |= copy_from_user(fpregs, sc.fpstate, sizeof(fpregs)); |
48 | if(err) | 44 | if (err) |
49 | return err; | 45 | return err; |
50 | 46 | ||
51 | copy_sc(®s->regs, &sc); | 47 | copy_sc(®s->regs, &sc); |
52 | 48 | ||
53 | err = restore_fp_registers(userspace_pid[0], fpregs); | 49 | err = restore_fp_registers(userspace_pid[0], fpregs); |
54 | if(err < 0) { | 50 | if (err < 0) { |
55 | printk("copy_sc_from_user_skas - PTRACE_SETFPREGS failed, " | 51 | printk(KERN_ERR "copy_sc_from_user_skas - PTRACE_SETFPREGS " |
56 | "errno = %d\n", -err); | 52 | "failed, errno = %d\n", -err); |
57 | return err; | 53 | return err; |
58 | } | 54 | } |
59 | 55 | ||
@@ -64,7 +60,7 @@ static int copy_sc_to_user(struct sigcontext __user *to, | |||
64 | struct _fpstate __user *to_fp, struct pt_regs *regs, | 60 | struct _fpstate __user *to_fp, struct pt_regs *regs, |
65 | unsigned long sp) | 61 | unsigned long sp) |
66 | { | 62 | { |
67 | struct sigcontext sc; | 63 | struct sigcontext sc; |
68 | unsigned long fpregs[HOST_FP_SIZE]; | 64 | unsigned long fpregs[HOST_FP_SIZE]; |
69 | struct faultinfo * fi = ¤t->thread.arch.faultinfo; | 65 | struct faultinfo * fi = ¤t->thread.arch.faultinfo; |
70 | int err; | 66 | int err; |
@@ -86,28 +82,29 @@ static int copy_sc_to_user(struct sigcontext __user *to, | |||
86 | sc.eflags = REGS_EFLAGS(regs->regs.regs); | 82 | sc.eflags = REGS_EFLAGS(regs->regs.regs); |
87 | sc.esp_at_signal = regs->regs.regs[UESP]; | 83 | sc.esp_at_signal = regs->regs.regs[UESP]; |
88 | sc.ss = regs->regs.regs[SS]; | 84 | sc.ss = regs->regs.regs[SS]; |
89 | sc.cr2 = fi->cr2; | 85 | sc.cr2 = fi->cr2; |
90 | sc.err = fi->error_code; | 86 | sc.err = fi->error_code; |
91 | sc.trapno = fi->trap_no; | 87 | sc.trapno = fi->trap_no; |
92 | 88 | ||
93 | err = save_fp_registers(userspace_pid[0], fpregs); | 89 | err = save_fp_registers(userspace_pid[0], fpregs); |
94 | if(err < 0){ | 90 | if (err < 0) { |
95 | printk("copy_sc_to_user_skas - PTRACE_GETFPREGS failed, " | 91 | printk(KERN_ERR "copy_sc_to_user_skas - PTRACE_GETFPREGS " |
96 | "errno = %d\n", err); | 92 | "failed, errno = %d\n", err); |
97 | return 1; | 93 | return 1; |
98 | } | 94 | } |
99 | to_fp = (to_fp ? to_fp : (struct _fpstate __user *) (to + 1)); | 95 | to_fp = (to_fp ? to_fp : (struct _fpstate __user *) (to + 1)); |
100 | sc.fpstate = to_fp; | 96 | sc.fpstate = to_fp; |
101 | 97 | ||
102 | if(err) | 98 | if (err) |
103 | return err; | 99 | return err; |
104 | 100 | ||
105 | return copy_to_user(to, &sc, sizeof(sc)) || | 101 | return copy_to_user(to, &sc, sizeof(sc)) || |
106 | copy_to_user(to_fp, fpregs, sizeof(fpregs)); | 102 | copy_to_user(to_fp, fpregs, sizeof(fpregs)); |
107 | } | 103 | } |
108 | 104 | ||
109 | static int copy_ucontext_to_user(struct ucontext __user *uc, struct _fpstate __user *fp, | 105 | static int copy_ucontext_to_user(struct ucontext __user *uc, |
110 | sigset_t *set, unsigned long sp) | 106 | struct _fpstate __user *fp, sigset_t *set, |
107 | unsigned long sp) | ||
111 | { | 108 | { |
112 | int err = 0; | 109 | int err = 0; |
113 | 110 | ||
@@ -157,7 +154,7 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig, | |||
157 | return 1; | 154 | return 1; |
158 | 155 | ||
159 | restorer = frame->retcode; | 156 | restorer = frame->retcode; |
160 | if(ka->sa.sa_flags & SA_RESTORER) | 157 | if (ka->sa.sa_flags & SA_RESTORER) |
161 | restorer = ka->sa.sa_restorer; | 158 | restorer = ka->sa.sa_restorer; |
162 | 159 | ||
163 | /* Update SP now because the page fault handler refuses to extend | 160 | /* Update SP now because the page fault handler refuses to extend |
@@ -189,7 +186,7 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig, | |||
189 | err |= __put_user(__NR_sigreturn, (int __user *)(frame->retcode+2)); | 186 | err |= __put_user(__NR_sigreturn, (int __user *)(frame->retcode+2)); |
190 | err |= __put_user(0x80cd, (short __user *)(frame->retcode+6)); | 187 | err |= __put_user(0x80cd, (short __user *)(frame->retcode+6)); |
191 | 188 | ||
192 | if(err) | 189 | if (err) |
193 | goto err; | 190 | goto err; |
194 | 191 | ||
195 | PT_REGS_SP(regs) = (unsigned long) frame; | 192 | PT_REGS_SP(regs) = (unsigned long) frame; |
@@ -222,7 +219,7 @@ int setup_signal_stack_si(unsigned long stack_top, int sig, | |||
222 | return 1; | 219 | return 1; |
223 | 220 | ||
224 | restorer = frame->retcode; | 221 | restorer = frame->retcode; |
225 | if(ka->sa.sa_flags & SA_RESTORER) | 222 | if (ka->sa.sa_flags & SA_RESTORER) |
226 | restorer = ka->sa.sa_restorer; | 223 | restorer = ka->sa.sa_restorer; |
227 | 224 | ||
228 | /* See comment above about why this is here */ | 225 | /* See comment above about why this is here */ |
@@ -247,7 +244,7 @@ int setup_signal_stack_si(unsigned long stack_top, int sig, | |||
247 | err |= __put_user(__NR_rt_sigreturn, (int __user *)(frame->retcode+1)); | 244 | err |= __put_user(__NR_rt_sigreturn, (int __user *)(frame->retcode+1)); |
248 | err |= __put_user(0x80cd, (short __user *)(frame->retcode+5)); | 245 | err |= __put_user(0x80cd, (short __user *)(frame->retcode+5)); |
249 | 246 | ||
250 | if(err) | 247 | if (err) |
251 | goto err; | 248 | goto err; |
252 | 249 | ||
253 | PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler; | 250 | PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler; |
@@ -274,8 +271,8 @@ long sys_sigreturn(struct pt_regs regs) | |||
274 | unsigned long __user *extramask = frame->extramask; | 271 | unsigned long __user *extramask = frame->extramask; |
275 | int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long); | 272 | int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long); |
276 | 273 | ||
277 | if(copy_from_user(&set.sig[0], oldmask, sizeof(set.sig[0])) || | 274 | if (copy_from_user(&set.sig[0], oldmask, sizeof(set.sig[0])) || |
278 | copy_from_user(&set.sig[1], extramask, sig_size)) | 275 | copy_from_user(&set.sig[1], extramask, sig_size)) |
279 | goto segfault; | 276 | goto segfault; |
280 | 277 | ||
281 | sigdelsetmask(&set, ~_BLOCKABLE); | 278 | sigdelsetmask(&set, ~_BLOCKABLE); |
@@ -285,7 +282,7 @@ long sys_sigreturn(struct pt_regs regs) | |||
285 | recalc_sigpending(); | 282 | recalc_sigpending(); |
286 | spin_unlock_irq(¤t->sighand->siglock); | 283 | spin_unlock_irq(¤t->sighand->siglock); |
287 | 284 | ||
288 | if(copy_sc_from_user(¤t->thread.regs, sc)) | 285 | if (copy_sc_from_user(¤t->thread.regs, sc)) |
289 | goto segfault; | 286 | goto segfault; |
290 | 287 | ||
291 | /* Avoid ERESTART handling */ | 288 | /* Avoid ERESTART handling */ |
@@ -300,12 +297,13 @@ long sys_sigreturn(struct pt_regs regs) | |||
300 | long sys_rt_sigreturn(struct pt_regs regs) | 297 | long sys_rt_sigreturn(struct pt_regs regs) |
301 | { | 298 | { |
302 | unsigned long sp = PT_REGS_SP(¤t->thread.regs); | 299 | unsigned long sp = PT_REGS_SP(¤t->thread.regs); |
303 | struct rt_sigframe __user *frame = (struct rt_sigframe __user *) (sp - 4); | 300 | struct rt_sigframe __user *frame = |
301 | (struct rt_sigframe __user *) (sp - 4); | ||
304 | sigset_t set; | 302 | sigset_t set; |
305 | struct ucontext __user *uc = &frame->uc; | 303 | struct ucontext __user *uc = &frame->uc; |
306 | int sig_size = _NSIG_WORDS * sizeof(unsigned long); | 304 | int sig_size = _NSIG_WORDS * sizeof(unsigned long); |
307 | 305 | ||
308 | if(copy_from_user(&set, &uc->uc_sigmask, sig_size)) | 306 | if (copy_from_user(&set, &uc->uc_sigmask, sig_size)) |
309 | goto segfault; | 307 | goto segfault; |
310 | 308 | ||
311 | sigdelsetmask(&set, ~_BLOCKABLE); | 309 | sigdelsetmask(&set, ~_BLOCKABLE); |
@@ -315,7 +313,7 @@ long sys_rt_sigreturn(struct pt_regs regs) | |||
315 | recalc_sigpending(); | 313 | recalc_sigpending(); |
316 | spin_unlock_irq(¤t->sighand->siglock); | 314 | spin_unlock_irq(¤t->sighand->siglock); |
317 | 315 | ||
318 | if(copy_sc_from_user(¤t->thread.regs, &uc->uc_mcontext)) | 316 | if (copy_sc_from_user(¤t->thread.regs, &uc->uc_mcontext)) |
319 | goto segfault; | 317 | goto segfault; |
320 | 318 | ||
321 | /* Avoid ERESTART handling */ | 319 | /* Avoid ERESTART handling */ |