aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/signal_64.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/signal_64.c')
-rw-r--r--arch/x86/kernel/signal_64.c111
1 files changed, 44 insertions, 67 deletions
diff --git a/arch/x86/kernel/signal_64.c b/arch/x86/kernel/signal_64.c
index 2f1464050059..694aa888bb19 100644
--- a/arch/x86/kernel/signal_64.c
+++ b/arch/x86/kernel/signal_64.c
@@ -15,17 +15,20 @@
15#include <linux/errno.h> 15#include <linux/errno.h>
16#include <linux/wait.h> 16#include <linux/wait.h>
17#include <linux/ptrace.h> 17#include <linux/ptrace.h>
18#include <linux/tracehook.h>
18#include <linux/unistd.h> 19#include <linux/unistd.h>
19#include <linux/stddef.h> 20#include <linux/stddef.h>
20#include <linux/personality.h> 21#include <linux/personality.h>
21#include <linux/compiler.h> 22#include <linux/compiler.h>
23#include <linux/uaccess.h>
24
22#include <asm/processor.h> 25#include <asm/processor.h>
23#include <asm/ucontext.h> 26#include <asm/ucontext.h>
24#include <asm/uaccess.h>
25#include <asm/i387.h> 27#include <asm/i387.h>
26#include <asm/proto.h> 28#include <asm/proto.h>
27#include <asm/ia32_unistd.h> 29#include <asm/ia32_unistd.h>
28#include <asm/mce.h> 30#include <asm/mce.h>
31#include <asm/syscall.h>
29#include <asm/syscalls.h> 32#include <asm/syscalls.h>
30#include "sigframe.h" 33#include "sigframe.h"
31 34
@@ -42,11 +45,6 @@
42# define FIX_EFLAGS __FIX_EFLAGS 45# define FIX_EFLAGS __FIX_EFLAGS
43#endif 46#endif
44 47
45int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
46 sigset_t *set, struct pt_regs * regs);
47int ia32_setup_frame(int sig, struct k_sigaction *ka,
48 sigset_t *set, struct pt_regs * regs);
49
50asmlinkage long 48asmlinkage long
51sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, 49sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
52 struct pt_regs *regs) 50 struct pt_regs *regs)
@@ -129,7 +127,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
129 /* Always make any pending restarted system calls return -EINTR */ 127 /* Always make any pending restarted system calls return -EINTR */
130 current_thread_info()->restart_block.fn = do_no_restart_syscall; 128 current_thread_info()->restart_block.fn = do_no_restart_syscall;
131 129
132#define COPY(x) err |= __get_user(regs->x, &sc->x) 130#define COPY(x) (err |= __get_user(regs->x, &sc->x))
133 131
134 COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx); 132 COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
135 COPY(dx); COPY(cx); COPY(ip); 133 COPY(dx); COPY(cx); COPY(ip);
@@ -159,7 +157,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
159 } 157 }
160 158
161 { 159 {
162 struct _fpstate __user * buf; 160 struct _fpstate __user *buf;
163 err |= __get_user(buf, &sc->fpstate); 161 err |= __get_user(buf, &sc->fpstate);
164 162
165 if (buf) { 163 if (buf) {
@@ -199,7 +197,7 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
199 current->blocked = set; 197 current->blocked = set;
200 recalc_sigpending(); 198 recalc_sigpending();
201 spin_unlock_irq(&current->sighand->siglock); 199 spin_unlock_irq(&current->sighand->siglock);
202 200
203 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax)) 201 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax))
204 goto badframe; 202 goto badframe;
205 203
@@ -209,16 +207,17 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
209 return ax; 207 return ax;
210 208
211badframe: 209badframe:
212 signal_fault(regs,frame,"sigreturn"); 210 signal_fault(regs, frame, "sigreturn");
213 return 0; 211 return 0;
214} 212}
215 213
216/* 214/*
217 * Set up a signal frame. 215 * Set up a signal frame.
218 */ 216 */
219 217
220static inline int 218static inline int
221setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, unsigned long mask, struct task_struct *me) 219setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
220 unsigned long mask, struct task_struct *me)
222{ 221{
223 int err = 0; 222 int err = 0;
224 223
@@ -274,35 +273,35 @@ get_stack(struct k_sigaction *ka, struct pt_regs *regs, unsigned long size)
274} 273}
275 274
276static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 275static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
277 sigset_t *set, struct pt_regs * regs) 276 sigset_t *set, struct pt_regs *regs)
278{ 277{
279 struct rt_sigframe __user *frame; 278 struct rt_sigframe __user *frame;
280 struct _fpstate __user *fp = NULL; 279 struct _fpstate __user *fp = NULL;
281 int err = 0; 280 int err = 0;
282 struct task_struct *me = current; 281 struct task_struct *me = current;
283 282
284 if (used_math()) { 283 if (used_math()) {
285 fp = get_stack(ka, regs, sizeof(struct _fpstate)); 284 fp = get_stack(ka, regs, sizeof(struct _fpstate));
286 frame = (void __user *)round_down( 285 frame = (void __user *)round_down(
287 (unsigned long)fp - sizeof(struct rt_sigframe), 16) - 8; 286 (unsigned long)fp - sizeof(struct rt_sigframe), 16) - 8;
288 287
289 if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate))) 288 if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate)))
290 goto give_sigsegv; 289 goto give_sigsegv;
291 290
292 if (save_i387(fp) < 0) 291 if (save_i387(fp) < 0)
293 err |= -1; 292 err |= -1;
294 } else 293 } else
295 frame = get_stack(ka, regs, sizeof(struct rt_sigframe)) - 8; 294 frame = get_stack(ka, regs, sizeof(struct rt_sigframe)) - 8;
296 295
297 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 296 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
298 goto give_sigsegv; 297 goto give_sigsegv;
299 298
300 if (ka->sa.sa_flags & SA_SIGINFO) { 299 if (ka->sa.sa_flags & SA_SIGINFO) {
301 err |= copy_siginfo_to_user(&frame->info, info); 300 err |= copy_siginfo_to_user(&frame->info, info);
302 if (err) 301 if (err)
303 goto give_sigsegv; 302 goto give_sigsegv;
304 } 303 }
305 304
306 /* Create the ucontext. */ 305 /* Create the ucontext. */
307 err |= __put_user(0, &frame->uc.uc_flags); 306 err |= __put_user(0, &frame->uc.uc_flags);
308 err |= __put_user(0, &frame->uc.uc_link); 307 err |= __put_user(0, &frame->uc.uc_link);
@@ -312,9 +311,9 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
312 err |= __put_user(me->sas_ss_size, &frame->uc.uc_stack.ss_size); 311 err |= __put_user(me->sas_ss_size, &frame->uc.uc_stack.ss_size);
313 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0], me); 312 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0], me);
314 err |= __put_user(fp, &frame->uc.uc_mcontext.fpstate); 313 err |= __put_user(fp, &frame->uc.uc_mcontext.fpstate);
315 if (sizeof(*set) == 16) { 314 if (sizeof(*set) == 16) {
316 __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]); 315 __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
317 __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]); 316 __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
318 } else 317 } else
319 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); 318 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
320 319
@@ -325,7 +324,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
325 err |= __put_user(ka->sa.sa_restorer, &frame->pretcode); 324 err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
326 } else { 325 } else {
327 /* could use a vstub here */ 326 /* could use a vstub here */
328 goto give_sigsegv; 327 goto give_sigsegv;
329 } 328 }
330 329
331 if (err) 330 if (err)
@@ -333,7 +332,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
333 332
334 /* Set up registers for signal handler */ 333 /* Set up registers for signal handler */
335 regs->di = sig; 334 regs->di = sig;
336 /* In case the signal handler was declared without prototypes */ 335 /* In case the signal handler was declared without prototypes */
337 regs->ax = 0; 336 regs->ax = 0;
338 337
339 /* This also works for non SA_SIGINFO handlers because they expect the 338 /* This also works for non SA_SIGINFO handlers because they expect the
@@ -356,37 +355,8 @@ give_sigsegv:
356} 355}
357 356
358/* 357/*
359 * Return -1L or the syscall number that @regs is executing.
360 */
361static long current_syscall(struct pt_regs *regs)
362{
363 /*
364 * We always sign-extend a -1 value being set here,
365 * so this is always either -1L or a syscall number.
366 */
367 return regs->orig_ax;
368}
369
370/*
371 * Return a value that is -EFOO if the system call in @regs->orig_ax
372 * returned an error. This only works for @regs from @current.
373 */
374static long current_syscall_ret(struct pt_regs *regs)
375{
376#ifdef CONFIG_IA32_EMULATION
377 if (test_thread_flag(TIF_IA32))
378 /*
379 * Sign-extend the value so (int)-EFOO becomes (long)-EFOO
380 * and will match correctly in comparisons.
381 */
382 return (int) regs->ax;
383#endif
384 return regs->ax;
385}
386
387/*
388 * OK, we're invoking a handler 358 * OK, we're invoking a handler
389 */ 359 */
390 360
391static int 361static int
392handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, 362handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
@@ -395,9 +365,9 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
395 int ret; 365 int ret;
396 366
397 /* Are we from a system call? */ 367 /* Are we from a system call? */
398 if (current_syscall(regs) >= 0) { 368 if (syscall_get_nr(current, regs) >= 0) {
399 /* If so, check system call restarting.. */ 369 /* If so, check system call restarting.. */
400 switch (current_syscall_ret(regs)) { 370 switch (syscall_get_error(current, regs)) {
401 case -ERESTART_RESTARTBLOCK: 371 case -ERESTART_RESTARTBLOCK:
402 case -ERESTARTNOHAND: 372 case -ERESTARTNOHAND:
403 regs->ax = -EINTR; 373 regs->ax = -EINTR;
@@ -430,7 +400,7 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
430 ret = ia32_setup_rt_frame(sig, ka, info, oldset, regs); 400 ret = ia32_setup_rt_frame(sig, ka, info, oldset, regs);
431 else 401 else
432 ret = ia32_setup_frame(sig, ka, oldset, regs); 402 ret = ia32_setup_frame(sig, ka, oldset, regs);
433 } else 403 } else
434#endif 404#endif
435 ret = setup_rt_frame(sig, ka, info, oldset, regs); 405 ret = setup_rt_frame(sig, ka, info, oldset, regs);
436 406
@@ -454,15 +424,16 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
454 * handler too. 424 * handler too.
455 */ 425 */
456 regs->flags &= ~X86_EFLAGS_TF; 426 regs->flags &= ~X86_EFLAGS_TF;
457 if (test_thread_flag(TIF_SINGLESTEP))
458 ptrace_notify(SIGTRAP);
459 427
460 spin_lock_irq(&current->sighand->siglock); 428 spin_lock_irq(&current->sighand->siglock);
461 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 429 sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
462 if (!(ka->sa.sa_flags & SA_NODEFER)) 430 if (!(ka->sa.sa_flags & SA_NODEFER))
463 sigaddset(&current->blocked,sig); 431 sigaddset(&current->blocked, sig);
464 recalc_sigpending(); 432 recalc_sigpending();
465 spin_unlock_irq(&current->sighand->siglock); 433 spin_unlock_irq(&current->sighand->siglock);
434
435 tracehook_signal_handler(sig, info, ka, regs,
436 test_thread_flag(TIF_SINGLESTEP));
466 } 437 }
467 438
468 return ret; 439 return ret;
@@ -519,9 +490,9 @@ static void do_signal(struct pt_regs *regs)
519 } 490 }
520 491
521 /* Did we come from a system call? */ 492 /* Did we come from a system call? */
522 if (current_syscall(regs) >= 0) { 493 if (syscall_get_nr(current, regs) >= 0) {
523 /* Restart the system call - no handlers present */ 494 /* Restart the system call - no handlers present */
524 switch (current_syscall_ret(regs)) { 495 switch (syscall_get_error(current, regs)) {
525 case -ERESTARTNOHAND: 496 case -ERESTARTNOHAND:
526 case -ERESTARTSYS: 497 case -ERESTARTSYS:
527 case -ERESTARTNOINTR: 498 case -ERESTARTNOINTR:
@@ -559,17 +530,23 @@ void do_notify_resume(struct pt_regs *regs, void *unused,
559 /* deal with pending signal delivery */ 530 /* deal with pending signal delivery */
560 if (thread_info_flags & _TIF_SIGPENDING) 531 if (thread_info_flags & _TIF_SIGPENDING)
561 do_signal(regs); 532 do_signal(regs);
533
534 if (thread_info_flags & _TIF_NOTIFY_RESUME) {
535 clear_thread_flag(TIF_NOTIFY_RESUME);
536 tracehook_notify_resume(regs);
537 }
562} 538}
563 539
564void signal_fault(struct pt_regs *regs, void __user *frame, char *where) 540void signal_fault(struct pt_regs *regs, void __user *frame, char *where)
565{ 541{
566 struct task_struct *me = current; 542 struct task_struct *me = current;
567 if (show_unhandled_signals && printk_ratelimit()) { 543 if (show_unhandled_signals && printk_ratelimit()) {
568 printk("%s[%d] bad frame in %s frame:%p ip:%lx sp:%lx orax:%lx", 544 printk("%s[%d] bad frame in %s frame:%p ip:%lx sp:%lx orax:%lx",
569 me->comm,me->pid,where,frame,regs->ip,regs->sp,regs->orig_ax); 545 me->comm, me->pid, where, frame, regs->ip,
546 regs->sp, regs->orig_ax);
570 print_vma_addr(" in ", regs->ip); 547 print_vma_addr(" in ", regs->ip);
571 printk("\n"); 548 printk("\n");
572 } 549 }
573 550
574 force_sig(SIGSEGV, me); 551 force_sig(SIGSEGV, me);
575} 552}