]>
git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blob - arch/um/sys-i386/signal.c
2 * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com)
3 * Licensed under the GPL
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"
17 #ifdef CONFIG_MODE_SKAS
21 static int copy_sc_from_user_skas(struct pt_regs
*regs
,
22 struct sigcontext
*from
)
25 unsigned long fpregs
[HOST_FP_SIZE
];
28 err
= copy_from_user(&sc
, from
, sizeof(sc
));
29 err
|= copy_from_user(fpregs
, sc
.fpstate
, sizeof(fpregs
));
33 REGS_GS(regs
->regs
.skas
.regs
) = sc
.gs
;
34 REGS_FS(regs
->regs
.skas
.regs
) = sc
.fs
;
35 REGS_ES(regs
->regs
.skas
.regs
) = sc
.es
;
36 REGS_DS(regs
->regs
.skas
.regs
) = sc
.ds
;
37 REGS_EDI(regs
->regs
.skas
.regs
) = sc
.edi
;
38 REGS_ESI(regs
->regs
.skas
.regs
) = sc
.esi
;
39 REGS_EBP(regs
->regs
.skas
.regs
) = sc
.ebp
;
40 REGS_SP(regs
->regs
.skas
.regs
) = sc
.esp
;
41 REGS_EBX(regs
->regs
.skas
.regs
) = sc
.ebx
;
42 REGS_EDX(regs
->regs
.skas
.regs
) = sc
.edx
;
43 REGS_ECX(regs
->regs
.skas
.regs
) = sc
.ecx
;
44 REGS_EAX(regs
->regs
.skas
.regs
) = sc
.eax
;
45 REGS_IP(regs
->regs
.skas
.regs
) = sc
.eip
;
46 REGS_CS(regs
->regs
.skas
.regs
) = sc
.cs
;
47 REGS_EFLAGS(regs
->regs
.skas
.regs
) = sc
.eflags
;
48 REGS_SS(regs
->regs
.skas
.regs
) = sc
.ss
;
50 err
= restore_fp_registers(userspace_pid
[0], fpregs
);
52 printk("copy_sc_from_user_skas - PTRACE_SETFPREGS failed, "
60 int copy_sc_to_user_skas(struct sigcontext
*to
, struct _fpstate
*to_fp
,
64 unsigned long fpregs
[HOST_FP_SIZE
];
65 struct faultinfo
* fi
= ¤t
->thread
.arch
.faultinfo
;
68 sc
.gs
= REGS_GS(regs
->regs
.skas
.regs
);
69 sc
.fs
= REGS_FS(regs
->regs
.skas
.regs
);
70 sc
.es
= REGS_ES(regs
->regs
.skas
.regs
);
71 sc
.ds
= REGS_DS(regs
->regs
.skas
.regs
);
72 sc
.edi
= REGS_EDI(regs
->regs
.skas
.regs
);
73 sc
.esi
= REGS_ESI(regs
->regs
.skas
.regs
);
74 sc
.ebp
= REGS_EBP(regs
->regs
.skas
.regs
);
75 sc
.esp
= REGS_SP(regs
->regs
.skas
.regs
);
76 sc
.ebx
= REGS_EBX(regs
->regs
.skas
.regs
);
77 sc
.edx
= REGS_EDX(regs
->regs
.skas
.regs
);
78 sc
.ecx
= REGS_ECX(regs
->regs
.skas
.regs
);
79 sc
.eax
= REGS_EAX(regs
->regs
.skas
.regs
);
80 sc
.eip
= REGS_IP(regs
->regs
.skas
.regs
);
81 sc
.cs
= REGS_CS(regs
->regs
.skas
.regs
);
82 sc
.eflags
= REGS_EFLAGS(regs
->regs
.skas
.regs
);
83 sc
.esp_at_signal
= regs
->regs
.skas
.regs
[UESP
];
84 sc
.ss
= regs
->regs
.skas
.regs
[SS
];
86 sc
.err
= fi
->error_code
;
87 sc
.trapno
= fi
->trap_no
;
89 err
= save_fp_registers(userspace_pid
[0], fpregs
);
91 printk("copy_sc_to_user_skas - PTRACE_GETFPREGS failed, "
95 to_fp
= (to_fp
? to_fp
: (struct _fpstate
*) (to
+ 1));
101 return(copy_to_user(to
, &sc
, sizeof(sc
)) ||
102 copy_to_user(to_fp
, fpregs
, sizeof(fpregs
)));
106 #ifdef CONFIG_MODE_TT
108 /* These copy a sigcontext to/from userspace. They copy the fpstate pointer,
109 * blowing away the old, good one. So, that value is saved, and then restored
110 * after the sigcontext copy. In copy_from, the variable holding the saved
111 * fpstate pointer, and the sigcontext that it should be restored to are both
112 * in the kernel, so we can just restore using an assignment. In copy_to, the
113 * saved pointer is in the kernel, but the sigcontext is in userspace, so we
116 int copy_sc_from_user_tt(struct sigcontext
*to
, struct sigcontext
*from
,
119 struct _fpstate
*to_fp
, *from_fp
;
125 err
= copy_from_user(to
, from
, sizeof(*to
));
126 from_fp
= to
->fpstate
;
130 err
|= copy_from_user(to_fp
, from_fp
, fpsize
);
134 int copy_sc_to_user_tt(struct sigcontext
*to
, struct _fpstate
*fp
,
135 struct sigcontext
*from
, int fpsize
)
137 struct _fpstate
*to_fp
, *from_fp
;
140 to_fp
= (fp
? fp
: (struct _fpstate
*) (to
+ 1));
141 from_fp
= from
->fpstate
;
142 err
= copy_to_user(to
, from
, sizeof(*to
));
144 err
|= copy_to_user(&to
->fpstate
, &to_fp
, sizeof(to
->fpstate
));
145 err
|= copy_to_user(to_fp
, from_fp
, fpsize
);
151 static int copy_sc_from_user(struct pt_regs
*to
, void __user
*from
)
155 ret
= CHOOSE_MODE(copy_sc_from_user_tt(UPT_SC(&to
->regs
), from
,
156 sizeof(struct _fpstate
)),
157 copy_sc_from_user_skas(to
, from
));
161 static int copy_sc_to_user(struct sigcontext
*to
, struct _fpstate
*fp
,
162 struct pt_regs
*from
)
164 return(CHOOSE_MODE(copy_sc_to_user_tt(to
, fp
, UPT_SC(&from
->regs
),
166 copy_sc_to_user_skas(to
, fp
, from
)));
169 static int copy_ucontext_to_user(struct ucontext
*uc
, struct _fpstate
*fp
,
170 sigset_t
*set
, unsigned long sp
)
174 err
|= put_user(current
->sas_ss_sp
, &uc
->uc_stack
.ss_sp
);
175 err
|= put_user(sas_ss_flags(sp
), &uc
->uc_stack
.ss_flags
);
176 err
|= put_user(current
->sas_ss_size
, &uc
->uc_stack
.ss_size
);
177 err
|= copy_sc_to_user(&uc
->uc_mcontext
, fp
, ¤t
->thread
.regs
);
178 err
|= copy_to_user(&uc
->uc_sigmask
, set
, sizeof(*set
));
186 struct sigcontext sc
;
187 struct _fpstate fpstate
;
188 unsigned long extramask
[_NSIG_WORDS
-1];
196 struct siginfo
*pinfo
;
200 struct _fpstate fpstate
;
204 int setup_signal_stack_sc(unsigned long stack_top
, int sig
,
205 struct k_sigaction
*ka
, struct pt_regs
*regs
,
208 struct sigframe __user
*frame
;
213 frame
= (struct sigframe
*) stack_top
- 1;
214 if (!access_ok(VERIFY_WRITE
, frame
, sizeof(*frame
)))
217 restorer
= (void *) frame
->retcode
;
218 if(ka
->sa
.sa_flags
& SA_RESTORER
)
219 restorer
= ka
->sa
.sa_restorer
;
221 err
|= __put_user(restorer
, &frame
->pretcode
);
222 err
|= __put_user(sig
, &frame
->sig
);
223 err
|= copy_sc_to_user(&frame
->sc
, NULL
, regs
);
224 err
|= __put_user(mask
->sig
[0], &frame
->sc
.oldmask
);
226 err
|= __copy_to_user(&frame
->extramask
, &mask
->sig
[1],
227 sizeof(frame
->extramask
));
230 * This is popl %eax ; movl $,%eax ; int $0x80
232 * WE DO NOT USE IT ANY MORE! It's only left here for historical
233 * reasons and because gdb uses it as a signature to notice
234 * signal handler stack frames.
236 err
|= __put_user(0xb858, (short __user
*)(frame
->retcode
+0));
237 err
|= __put_user(__NR_sigreturn
, (int __user
*)(frame
->retcode
+2));
238 err
|= __put_user(0x80cd, (short __user
*)(frame
->retcode
+6));
243 PT_REGS_SP(regs
) = (unsigned long) frame
;
244 PT_REGS_IP(regs
) = (unsigned long) ka
->sa
.sa_handler
;
245 PT_REGS_EAX(regs
) = (unsigned long) sig
;
246 PT_REGS_EDX(regs
) = (unsigned long) 0;
247 PT_REGS_ECX(regs
) = (unsigned long) 0;
249 if ((current
->ptrace
& PT_DTRACE
) && (current
->ptrace
& PT_PTRACED
))
250 ptrace_notify(SIGTRAP
);
254 int setup_signal_stack_si(unsigned long stack_top
, int sig
,
255 struct k_sigaction
*ka
, struct pt_regs
*regs
,
256 siginfo_t
*info
, sigset_t
*mask
)
258 struct rt_sigframe __user
*frame
;
263 frame
= (struct rt_sigframe
*) stack_top
- 1;
264 if (!access_ok(VERIFY_WRITE
, frame
, sizeof(*frame
)))
267 restorer
= (void *) frame
->retcode
;
268 if(ka
->sa
.sa_flags
& SA_RESTORER
)
269 restorer
= ka
->sa
.sa_restorer
;
271 err
|= __put_user(restorer
, &frame
->pretcode
);
272 err
|= __put_user(sig
, &frame
->sig
);
273 err
|= __put_user(&frame
->info
, &frame
->pinfo
);
274 err
|= __put_user(&frame
->uc
, &frame
->puc
);
275 err
|= copy_siginfo_to_user(&frame
->info
, info
);
276 err
|= copy_ucontext_to_user(&frame
->uc
, &frame
->fpstate
, mask
,
280 * This is movl $,%eax ; int $0x80
282 * WE DO NOT USE IT ANY MORE! It's only left here for historical
283 * reasons and because gdb uses it as a signature to notice
284 * signal handler stack frames.
286 err
|= __put_user(0xb8, (char __user
*)(frame
->retcode
+0));
287 err
|= __put_user(__NR_rt_sigreturn
, (int __user
*)(frame
->retcode
+1));
288 err
|= __put_user(0x80cd, (short __user
*)(frame
->retcode
+5));
293 PT_REGS_SP(regs
) = (unsigned long) frame
;
294 PT_REGS_IP(regs
) = (unsigned long) ka
->sa
.sa_handler
;
295 PT_REGS_EAX(regs
) = (unsigned long) sig
;
296 PT_REGS_EDX(regs
) = (unsigned long) &frame
->info
;
297 PT_REGS_ECX(regs
) = (unsigned long) &frame
->uc
;
299 if ((current
->ptrace
& PT_DTRACE
) && (current
->ptrace
& PT_PTRACED
))
300 ptrace_notify(SIGTRAP
);
304 long sys_sigreturn(struct pt_regs regs
)
306 unsigned long sp
= PT_REGS_SP(¤t
->thread
.regs
);
307 struct sigframe __user
*frame
= (struct sigframe
*)(sp
- 8);
309 struct sigcontext __user
*sc
= &frame
->sc
;
310 unsigned long __user
*oldmask
= &sc
->oldmask
;
311 unsigned long __user
*extramask
= frame
->extramask
;
312 int sig_size
= (_NSIG_WORDS
- 1) * sizeof(unsigned long);
314 if(copy_from_user(&set
.sig
[0], oldmask
, sizeof(set
.sig
[0])) ||
315 copy_from_user(&set
.sig
[1], extramask
, sig_size
))
318 sigdelsetmask(&set
, ~_BLOCKABLE
);
320 spin_lock_irq(¤t
->sighand
->siglock
);
321 current
->blocked
= set
;
323 spin_unlock_irq(¤t
->sighand
->siglock
);
325 if(copy_sc_from_user(¤t
->thread
.regs
, sc
))
328 /* Avoid ERESTART handling */
329 PT_REGS_SYSCALL_NR(¤t
->thread
.regs
) = -1;
330 return(PT_REGS_SYSCALL_RET(¤t
->thread
.regs
));
333 force_sig(SIGSEGV
, current
);
337 long sys_rt_sigreturn(struct pt_regs regs
)
339 unsigned long __user sp
= PT_REGS_SP(¤t
->thread
.regs
);
340 struct rt_sigframe __user
*frame
= (struct rt_sigframe
*) (sp
- 4);
342 struct ucontext __user
*uc
= &frame
->uc
;
343 int sig_size
= _NSIG_WORDS
* sizeof(unsigned long);
345 if(copy_from_user(&set
, &uc
->uc_sigmask
, sig_size
))
348 sigdelsetmask(&set
, ~_BLOCKABLE
);
350 spin_lock_irq(¤t
->sighand
->siglock
);
351 current
->blocked
= set
;
353 spin_unlock_irq(¤t
->sighand
->siglock
);
355 if(copy_sc_from_user(¤t
->thread
.regs
, &uc
->uc_mcontext
))
358 /* Avoid ERESTART handling */
359 PT_REGS_SYSCALL_NR(¤t
->thread
.regs
) = -1;
360 return(PT_REGS_SYSCALL_RET(¤t
->thread
.regs
));
363 force_sig(SIGSEGV
, current
);
368 * Overrides for Emacs so that we follow Linus's tabbing style.
369 * Emacs will notice this stuff at the end of the file and automatically
370 * adjust the settings for this buffer only. This must remain at the end
372 * ---------------------------------------------------------------------------
374 * c-file-style: "linux"