]>
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 __user
*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 __user
*to
, struct _fpstate __user
*to_fp
,
61 struct pt_regs
*regs
, unsigned long sp
)
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
);
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 __user
*) (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 __user
*from
,
119 struct _fpstate
*to_fp
;
120 struct _fpstate __user
*from_fp
;
126 err
= copy_from_user(to
, from
, sizeof(*to
));
127 from_fp
= to
->fpstate
;
131 err
|= copy_from_user(to_fp
, from_fp
, fpsize
);
135 int copy_sc_to_user_tt(struct sigcontext __user
*to
, struct _fpstate __user
*fp
,
136 struct sigcontext
*from
, int fpsize
, unsigned long sp
)
138 struct _fpstate __user
*to_fp
;
139 struct _fpstate
*from_fp
;
142 to_fp
= (fp
? fp
: (struct _fpstate __user
*) (to
+ 1));
143 from_fp
= from
->fpstate
;
144 err
= copy_to_user(to
, from
, sizeof(*to
));
146 /* The SP in the sigcontext is the updated one for the signal
147 * delivery. The sp passed in is the original, and this needs
148 * to be restored, so we stick it in separately.
150 err
|= copy_to_user(&SC_SP(to
), &sp
, sizeof(sp
));
153 err
|= copy_to_user(&to
->fpstate
, &to_fp
, sizeof(to
->fpstate
));
154 err
|= copy_to_user(to_fp
, from_fp
, fpsize
);
160 static int copy_sc_from_user(struct pt_regs
*to
, void __user
*from
)
164 ret
= CHOOSE_MODE(copy_sc_from_user_tt(UPT_SC(&to
->regs
), from
,
165 sizeof(struct _fpstate
)),
166 copy_sc_from_user_skas(to
, from
));
170 static int copy_sc_to_user(struct sigcontext __user
*to
, struct _fpstate __user
*fp
,
171 struct pt_regs
*from
, unsigned long sp
)
173 return(CHOOSE_MODE(copy_sc_to_user_tt(to
, fp
, UPT_SC(&from
->regs
),
175 copy_sc_to_user_skas(to
, fp
, from
, sp
)));
178 static int copy_ucontext_to_user(struct ucontext __user
*uc
, struct _fpstate __user
*fp
,
179 sigset_t
*set
, unsigned long sp
)
183 err
|= put_user(current
->sas_ss_sp
, &uc
->uc_stack
.ss_sp
);
184 err
|= put_user(sas_ss_flags(sp
), &uc
->uc_stack
.ss_flags
);
185 err
|= put_user(current
->sas_ss_size
, &uc
->uc_stack
.ss_size
);
186 err
|= copy_sc_to_user(&uc
->uc_mcontext
, fp
, ¤t
->thread
.regs
, sp
);
187 err
|= copy_to_user(&uc
->uc_sigmask
, set
, sizeof(*set
));
193 char __user
*pretcode
;
195 struct sigcontext sc
;
196 struct _fpstate fpstate
;
197 unsigned long extramask
[_NSIG_WORDS
-1];
203 char __user
*pretcode
;
205 struct siginfo __user
*pinfo
;
209 struct _fpstate fpstate
;
213 int setup_signal_stack_sc(unsigned long stack_top
, int sig
,
214 struct k_sigaction
*ka
, struct pt_regs
*regs
,
217 struct sigframe __user
*frame
;
218 void __user
*restorer
;
219 unsigned long save_sp
= PT_REGS_SP(regs
);
223 frame
= (struct sigframe __user
*) stack_top
- 1;
224 if (!access_ok(VERIFY_WRITE
, frame
, sizeof(*frame
)))
227 restorer
= frame
->retcode
;
228 if(ka
->sa
.sa_flags
& SA_RESTORER
)
229 restorer
= ka
->sa
.sa_restorer
;
231 /* Update SP now because the page fault handler refuses to extend
232 * the stack if the faulting address is too far below the current
233 * SP, which frame now certainly is. If there's an error, the original
234 * value is restored on the way out.
235 * When writing the sigcontext to the stack, we have to write the
236 * original value, so that's passed to copy_sc_to_user, which does
237 * the right thing with it.
239 PT_REGS_SP(regs
) = (unsigned long) frame
;
241 err
|= __put_user(restorer
, &frame
->pretcode
);
242 err
|= __put_user(sig
, &frame
->sig
);
243 err
|= copy_sc_to_user(&frame
->sc
, NULL
, regs
, save_sp
);
244 err
|= __put_user(mask
->sig
[0], &frame
->sc
.oldmask
);
246 err
|= __copy_to_user(&frame
->extramask
, &mask
->sig
[1],
247 sizeof(frame
->extramask
));
250 * This is popl %eax ; movl $,%eax ; int $0x80
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.
256 err
|= __put_user(0xb858, (short __user
*)(frame
->retcode
+0));
257 err
|= __put_user(__NR_sigreturn
, (int __user
*)(frame
->retcode
+2));
258 err
|= __put_user(0x80cd, (short __user
*)(frame
->retcode
+6));
263 PT_REGS_SP(regs
) = (unsigned long) frame
;
264 PT_REGS_IP(regs
) = (unsigned long) ka
->sa
.sa_handler
;
265 PT_REGS_EAX(regs
) = (unsigned long) sig
;
266 PT_REGS_EDX(regs
) = (unsigned long) 0;
267 PT_REGS_ECX(regs
) = (unsigned long) 0;
269 if ((current
->ptrace
& PT_DTRACE
) && (current
->ptrace
& PT_PTRACED
))
270 ptrace_notify(SIGTRAP
);
274 PT_REGS_SP(regs
) = save_sp
;
278 int setup_signal_stack_si(unsigned long stack_top
, int sig
,
279 struct k_sigaction
*ka
, struct pt_regs
*regs
,
280 siginfo_t
*info
, sigset_t
*mask
)
282 struct rt_sigframe __user
*frame
;
283 void __user
*restorer
;
284 unsigned long save_sp
= PT_REGS_SP(regs
);
288 frame
= (struct rt_sigframe __user
*) stack_top
- 1;
289 if (!access_ok(VERIFY_WRITE
, frame
, sizeof(*frame
)))
292 restorer
= frame
->retcode
;
293 if(ka
->sa
.sa_flags
& SA_RESTORER
)
294 restorer
= ka
->sa
.sa_restorer
;
296 /* See comment above about why this is here */
297 PT_REGS_SP(regs
) = (unsigned long) frame
;
299 err
|= __put_user(restorer
, &frame
->pretcode
);
300 err
|= __put_user(sig
, &frame
->sig
);
301 err
|= __put_user(&frame
->info
, &frame
->pinfo
);
302 err
|= __put_user(&frame
->uc
, &frame
->puc
);
303 err
|= copy_siginfo_to_user(&frame
->info
, info
);
304 err
|= copy_ucontext_to_user(&frame
->uc
, &frame
->fpstate
, mask
,
308 * This is movl $,%eax ; int $0x80
310 * WE DO NOT USE IT ANY MORE! It's only left here for historical
311 * reasons and because gdb uses it as a signature to notice
312 * signal handler stack frames.
314 err
|= __put_user(0xb8, (char __user
*)(frame
->retcode
+0));
315 err
|= __put_user(__NR_rt_sigreturn
, (int __user
*)(frame
->retcode
+1));
316 err
|= __put_user(0x80cd, (short __user
*)(frame
->retcode
+5));
321 PT_REGS_IP(regs
) = (unsigned long) ka
->sa
.sa_handler
;
322 PT_REGS_EAX(regs
) = (unsigned long) sig
;
323 PT_REGS_EDX(regs
) = (unsigned long) &frame
->info
;
324 PT_REGS_ECX(regs
) = (unsigned long) &frame
->uc
;
326 if ((current
->ptrace
& PT_DTRACE
) && (current
->ptrace
& PT_PTRACED
))
327 ptrace_notify(SIGTRAP
);
331 PT_REGS_SP(regs
) = save_sp
;
335 long sys_sigreturn(struct pt_regs regs
)
337 unsigned long sp
= PT_REGS_SP(¤t
->thread
.regs
);
338 struct sigframe __user
*frame
= (struct sigframe __user
*)(sp
- 8);
340 struct sigcontext __user
*sc
= &frame
->sc
;
341 unsigned long __user
*oldmask
= &sc
->oldmask
;
342 unsigned long __user
*extramask
= frame
->extramask
;
343 int sig_size
= (_NSIG_WORDS
- 1) * sizeof(unsigned long);
345 if(copy_from_user(&set
.sig
[0], oldmask
, sizeof(set
.sig
[0])) ||
346 copy_from_user(&set
.sig
[1], extramask
, sig_size
))
349 sigdelsetmask(&set
, ~_BLOCKABLE
);
351 spin_lock_irq(¤t
->sighand
->siglock
);
352 current
->blocked
= set
;
354 spin_unlock_irq(¤t
->sighand
->siglock
);
356 if(copy_sc_from_user(¤t
->thread
.regs
, sc
))
359 /* Avoid ERESTART handling */
360 PT_REGS_SYSCALL_NR(¤t
->thread
.regs
) = -1;
361 return(PT_REGS_SYSCALL_RET(¤t
->thread
.regs
));
364 force_sig(SIGSEGV
, current
);
368 long sys_rt_sigreturn(struct pt_regs regs
)
370 unsigned long sp
= PT_REGS_SP(¤t
->thread
.regs
);
371 struct rt_sigframe __user
*frame
= (struct rt_sigframe __user
*) (sp
- 4);
373 struct ucontext __user
*uc
= &frame
->uc
;
374 int sig_size
= _NSIG_WORDS
* sizeof(unsigned long);
376 if(copy_from_user(&set
, &uc
->uc_sigmask
, sig_size
))
379 sigdelsetmask(&set
, ~_BLOCKABLE
);
381 spin_lock_irq(¤t
->sighand
->siglock
);
382 current
->blocked
= set
;
384 spin_unlock_irq(¤t
->sighand
->siglock
);
386 if(copy_sc_from_user(¤t
->thread
.regs
, &uc
->uc_mcontext
))
389 /* Avoid ERESTART handling */
390 PT_REGS_SYSCALL_NR(¤t
->thread
.regs
) = -1;
391 return(PT_REGS_SYSCALL_RET(¤t
->thread
.regs
));
394 force_sig(SIGSEGV
, current
);
399 * Overrides for Emacs so that we follow Linus's tabbing style.
400 * Emacs will notice this stuff at the end of the file and automatically
401 * adjust the settings for this buffer only. This must remain at the end
403 * ---------------------------------------------------------------------------
405 * c-file-style: "linux"