Loading arch/alpha/kernel/entry.S +3 −4 Original line number Diff line number Diff line Loading @@ -391,11 +391,10 @@ $work_resched: bne $2, $work_resched $work_notifysig: mov $sp, $17 mov $sp, $16 br $1, do_switch_stack mov $5, $21 mov $sp, $18 mov $31, $16 mov $sp, $17 mov $5, $18 jsr $26, do_notify_resume bsr $1, undo_switch_stack br restore_all Loading arch/alpha/kernel/signal.c +63 −47 Original line number Diff line number Diff line Loading @@ -32,7 +32,7 @@ #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) asmlinkage void ret_from_sys_call(void); static int do_signal(sigset_t *, struct pt_regs *, struct switch_stack *, static void do_signal(struct pt_regs *, struct switch_stack *, unsigned long, unsigned long); Loading Loading @@ -146,11 +146,9 @@ sys_rt_sigaction(int sig, const struct sigaction __user *act, asmlinkage int do_sigsuspend(old_sigset_t mask, struct pt_regs *regs, struct switch_stack *sw) { sigset_t oldset; mask &= _BLOCKABLE; spin_lock_irq(¤t->sighand->siglock); oldset = current->blocked; current->saved_sigmask = current->blocked; siginitset(¤t->blocked, mask); recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); Loading @@ -160,19 +158,17 @@ do_sigsuspend(old_sigset_t mask, struct pt_regs *regs, struct switch_stack *sw) regs->r0 = EINTR; regs->r19 = 1; while (1) { current->state = TASK_INTERRUPTIBLE; schedule(); if (do_signal(&oldset, regs, sw, 0, 0)) return -EINTR; } set_thread_flag(TIF_RESTORE_SIGMASK); return -ERESTARTNOHAND; } asmlinkage int do_rt_sigsuspend(sigset_t __user *uset, size_t sigsetsize, struct pt_regs *regs, struct switch_stack *sw) { sigset_t oldset, set; sigset_t set; /* XXX: Don't preclude handling different sized sigset_t's. */ if (sigsetsize != sizeof(sigset_t)) Loading @@ -182,7 +178,7 @@ do_rt_sigsuspend(sigset_t __user *uset, size_t sigsetsize, sigdelsetmask(&set, ~_BLOCKABLE); spin_lock_irq(¤t->sighand->siglock); oldset = current->blocked; current->saved_sigmask = current->blocked; current->blocked = set; recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); Loading @@ -192,12 +188,10 @@ do_rt_sigsuspend(sigset_t __user *uset, size_t sigsetsize, regs->r0 = EINTR; regs->r19 = 1; while (1) { current->state = TASK_INTERRUPTIBLE; schedule(); if (do_signal(&oldset, regs, sw, 0, 0)) return -EINTR; } set_thread_flag(TIF_RESTORE_SIGMASK); return -ERESTARTNOHAND; } asmlinkage int Loading Loading @@ -436,7 +430,7 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, return err; } static void static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, struct pt_regs *regs, struct switch_stack * sw) { Loading Loading @@ -481,13 +475,14 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, current->comm, current->pid, frame, regs->pc, regs->r26); #endif return; return 0; give_sigsegv: force_sigsegv(sig, current); return -EFAULT; } static void static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set, struct pt_regs *regs, struct switch_stack * sw) { Loading Loading @@ -543,28 +538,29 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, current->comm, current->pid, frame, regs->pc, regs->r26); #endif return; return 0; give_sigsegv: force_sigsegv(sig, current); return -EFAULT; } /* * OK, we're invoking a handler. */ static inline void static inline int handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *oldset, struct pt_regs * regs, struct switch_stack *sw) { int ret; if (ka->sa.sa_flags & SA_SIGINFO) setup_rt_frame(sig, ka, info, oldset, regs, sw); ret = setup_rt_frame(sig, ka, info, oldset, regs, sw); else setup_frame(sig, ka, oldset, regs, sw); if (ka->sa.sa_flags & SA_RESETHAND) ka->sa.sa_handler = SIG_DFL; ret = setup_frame(sig, ka, oldset, regs, sw); if (ret == 0) { spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); if (!(ka->sa.sa_flags & SA_NODEFER)) Loading @@ -573,6 +569,9 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, spin_unlock_irq(¤t->sighand->siglock); } return ret; } static inline void syscall_restart(unsigned long r0, unsigned long r19, struct pt_regs *regs, struct k_sigaction *ka) Loading Loading @@ -611,30 +610,42 @@ syscall_restart(unsigned long r0, unsigned long r19, * restart. "r0" is also used as an indicator whether we can restart at * all (if we get here from anything but a syscall return, it will be 0) */ static int do_signal(sigset_t *oldset, struct pt_regs * regs, struct switch_stack * sw, static void do_signal(struct pt_regs * regs, struct switch_stack * sw, unsigned long r0, unsigned long r19) { siginfo_t info; int signr; unsigned long single_stepping = ptrace_cancel_bpt(current); struct k_sigaction ka; sigset_t *oldset; if (!oldset) if (test_thread_flag(TIF_RESTORE_SIGMASK)) oldset = ¤t->saved_sigmask; else oldset = ¤t->blocked; /* This lets the debugger run, ... */ signr = get_signal_to_deliver(&info, &ka, regs, NULL); /* ... so re-check the single stepping. */ single_stepping |= ptrace_cancel_bpt(current); if (signr > 0) { /* Whee! Actually deliver the signal. */ if (r0) syscall_restart(r0, r19, regs, &ka); handle_signal(signr, &ka, &info, oldset, regs, sw); if (r0) syscall_restart(r0, r19, regs, &ka); if (handle_signal(signr, &ka, &info, oldset, regs, sw) == 0) { /* A signal was successfully delivered, and the saved sigmask was stored on the signal frame, and will be restored by sigreturn. So we can simply clear the restore sigmask flag. */ if (test_thread_flag(TIF_RESTORE_SIGMASK)) clear_thread_flag(TIF_RESTORE_SIGMASK); } if (single_stepping) ptrace_set_bpt(current); /* re-set bpt */ return 1; return; } if (r0) { Loading @@ -654,17 +665,22 @@ do_signal(sigset_t *oldset, struct pt_regs * regs, struct switch_stack * sw, break; } } /* If there's no signal to deliver, we just restore the saved mask. */ if (test_thread_flag(TIF_RESTORE_SIGMASK)) { clear_thread_flag(TIF_RESTORE_SIGMASK); sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } if (single_stepping) ptrace_set_bpt(current); /* re-set breakpoint */ return 0; } void do_notify_resume(sigset_t *oldset, struct pt_regs *regs, struct switch_stack *sw, unsigned long r0, unsigned long r19, unsigned long thread_info_flags) do_notify_resume(struct pt_regs *regs, struct switch_stack *sw, unsigned long thread_info_flags, unsigned long r0, unsigned long r19) { if (thread_info_flags & _TIF_SIGPENDING) do_signal(oldset, regs, sw, r0, r19); if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) do_signal(regs, sw, r0, r19); } arch/alpha/kernel/systbls.S +32 −0 Original line number Diff line number Diff line Loading @@ -465,6 +465,38 @@ sys_call_table: .quad sys_inotify_init .quad sys_inotify_add_watch /* 445 */ .quad sys_inotify_rm_watch .quad sys_fdatasync .quad sys_kexec_load .quad sys_migrate_pages .quad sys_openat /* 450 */ .quad sys_mkdirat .quad sys_mknodat .quad sys_fchownat .quad sys_futimesat .quad sys_fstatat64 /* 455 */ .quad sys_unlinkat .quad sys_renameat .quad sys_linkat .quad sys_symlinkat .quad sys_readlinkat /* 460 */ .quad sys_fchmodat .quad sys_faccessat .quad sys_pselect6 .quad sys_ppoll .quad sys_unshare /* 465 */ .quad sys_set_robust_list .quad sys_get_robust_list .quad sys_splice .quad sys_sync_file_range .quad sys_tee /* 470 */ .quad sys_vmsplice .quad sys_move_pages .quad sys_getcpu .quad sys_epoll_pwait .quad sys_utimensat /* 475 */ .quad sys_signalfd .quad sys_timerfd .quad sys_eventfd .size sys_call_table, . - sys_call_table .type sys_call_table, @object Loading include/asm-alpha/thread_info.h +2 −0 Original line number Diff line number Diff line Loading @@ -76,12 +76,14 @@ register struct thread_info *__current_thread_info __asm__("$8"); #define TIF_UAC_NOFIX 7 #define TIF_UAC_SIGBUS 8 #define TIF_MEMDIE 9 #define TIF_RESTORE_SIGMASK 10 /* restore signal mask in do_signal */ #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) #define _TIF_SIGPENDING (1<<TIF_SIGPENDING) #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) #define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK) /* Work to do on interrupt/exception return. */ #define _TIF_WORK_MASK (_TIF_NOTIFY_RESUME \ Loading include/asm-alpha/unistd.h +47 −1 Original line number Diff line number Diff line Loading @@ -233,6 +233,20 @@ #define __NR_osf_memcntl 260 /* not implemented */ #define __NR_osf_fdatasync 261 /* not implemented */ /* * Ignore legacy syscalls that we don't use. */ #define __IGNORE_alarm #define __IGNORE_creat #define __IGNORE_getegid #define __IGNORE_geteuid #define __IGNORE_getgid #define __IGNORE_getpid #define __IGNORE_getppid #define __IGNORE_getuid #define __IGNORE_pause #define __IGNORE_time #define __IGNORE_utime /* * Linux-specific system calls begin at 300 Loading Loading @@ -387,10 +401,42 @@ #define __NR_inotify_init 444 #define __NR_inotify_add_watch 445 #define __NR_inotify_rm_watch 446 #define __NR_fdatasync 447 #define __NR_kexec_load 448 #define __NR_migrate_pages 449 #define __NR_openat 450 #define __NR_mkdirat 451 #define __NR_mknodat 452 #define __NR_fchownat 453 #define __NR_futimesat 454 #define __NR_fstatat64 455 #define __NR_unlinkat 456 #define __NR_renameat 457 #define __NR_linkat 458 #define __NR_symlinkat 459 #define __NR_readlinkat 460 #define __NR_fchmodat 461 #define __NR_faccessat 462 #define __NR_pselect6 463 #define __NR_ppoll 464 #define __NR_unshare 465 #define __NR_set_robust_list 466 #define __NR_get_robust_list 467 #define __NR_splice 468 #define __NR_sync_file_range 469 #define __NR_tee 470 #define __NR_vmsplice 471 #define __NR_move_pages 472 #define __NR_getcpu 473 #define __NR_epoll_pwait 474 #define __NR_utimensat 475 #define __NR_signalfd 476 #define __NR_timerfd 477 #define __NR_eventfd 478 #ifdef __KERNEL__ #define NR_SYSCALLS 447 #define NR_SYSCALLS 479 #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR Loading Loading
arch/alpha/kernel/entry.S +3 −4 Original line number Diff line number Diff line Loading @@ -391,11 +391,10 @@ $work_resched: bne $2, $work_resched $work_notifysig: mov $sp, $17 mov $sp, $16 br $1, do_switch_stack mov $5, $21 mov $sp, $18 mov $31, $16 mov $sp, $17 mov $5, $18 jsr $26, do_notify_resume bsr $1, undo_switch_stack br restore_all Loading
arch/alpha/kernel/signal.c +63 −47 Original line number Diff line number Diff line Loading @@ -32,7 +32,7 @@ #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) asmlinkage void ret_from_sys_call(void); static int do_signal(sigset_t *, struct pt_regs *, struct switch_stack *, static void do_signal(struct pt_regs *, struct switch_stack *, unsigned long, unsigned long); Loading Loading @@ -146,11 +146,9 @@ sys_rt_sigaction(int sig, const struct sigaction __user *act, asmlinkage int do_sigsuspend(old_sigset_t mask, struct pt_regs *regs, struct switch_stack *sw) { sigset_t oldset; mask &= _BLOCKABLE; spin_lock_irq(¤t->sighand->siglock); oldset = current->blocked; current->saved_sigmask = current->blocked; siginitset(¤t->blocked, mask); recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); Loading @@ -160,19 +158,17 @@ do_sigsuspend(old_sigset_t mask, struct pt_regs *regs, struct switch_stack *sw) regs->r0 = EINTR; regs->r19 = 1; while (1) { current->state = TASK_INTERRUPTIBLE; schedule(); if (do_signal(&oldset, regs, sw, 0, 0)) return -EINTR; } set_thread_flag(TIF_RESTORE_SIGMASK); return -ERESTARTNOHAND; } asmlinkage int do_rt_sigsuspend(sigset_t __user *uset, size_t sigsetsize, struct pt_regs *regs, struct switch_stack *sw) { sigset_t oldset, set; sigset_t set; /* XXX: Don't preclude handling different sized sigset_t's. */ if (sigsetsize != sizeof(sigset_t)) Loading @@ -182,7 +178,7 @@ do_rt_sigsuspend(sigset_t __user *uset, size_t sigsetsize, sigdelsetmask(&set, ~_BLOCKABLE); spin_lock_irq(¤t->sighand->siglock); oldset = current->blocked; current->saved_sigmask = current->blocked; current->blocked = set; recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); Loading @@ -192,12 +188,10 @@ do_rt_sigsuspend(sigset_t __user *uset, size_t sigsetsize, regs->r0 = EINTR; regs->r19 = 1; while (1) { current->state = TASK_INTERRUPTIBLE; schedule(); if (do_signal(&oldset, regs, sw, 0, 0)) return -EINTR; } set_thread_flag(TIF_RESTORE_SIGMASK); return -ERESTARTNOHAND; } asmlinkage int Loading Loading @@ -436,7 +430,7 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, return err; } static void static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, struct pt_regs *regs, struct switch_stack * sw) { Loading Loading @@ -481,13 +475,14 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, current->comm, current->pid, frame, regs->pc, regs->r26); #endif return; return 0; give_sigsegv: force_sigsegv(sig, current); return -EFAULT; } static void static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set, struct pt_regs *regs, struct switch_stack * sw) { Loading Loading @@ -543,28 +538,29 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, current->comm, current->pid, frame, regs->pc, regs->r26); #endif return; return 0; give_sigsegv: force_sigsegv(sig, current); return -EFAULT; } /* * OK, we're invoking a handler. */ static inline void static inline int handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *oldset, struct pt_regs * regs, struct switch_stack *sw) { int ret; if (ka->sa.sa_flags & SA_SIGINFO) setup_rt_frame(sig, ka, info, oldset, regs, sw); ret = setup_rt_frame(sig, ka, info, oldset, regs, sw); else setup_frame(sig, ka, oldset, regs, sw); if (ka->sa.sa_flags & SA_RESETHAND) ka->sa.sa_handler = SIG_DFL; ret = setup_frame(sig, ka, oldset, regs, sw); if (ret == 0) { spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); if (!(ka->sa.sa_flags & SA_NODEFER)) Loading @@ -573,6 +569,9 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, spin_unlock_irq(¤t->sighand->siglock); } return ret; } static inline void syscall_restart(unsigned long r0, unsigned long r19, struct pt_regs *regs, struct k_sigaction *ka) Loading Loading @@ -611,30 +610,42 @@ syscall_restart(unsigned long r0, unsigned long r19, * restart. "r0" is also used as an indicator whether we can restart at * all (if we get here from anything but a syscall return, it will be 0) */ static int do_signal(sigset_t *oldset, struct pt_regs * regs, struct switch_stack * sw, static void do_signal(struct pt_regs * regs, struct switch_stack * sw, unsigned long r0, unsigned long r19) { siginfo_t info; int signr; unsigned long single_stepping = ptrace_cancel_bpt(current); struct k_sigaction ka; sigset_t *oldset; if (!oldset) if (test_thread_flag(TIF_RESTORE_SIGMASK)) oldset = ¤t->saved_sigmask; else oldset = ¤t->blocked; /* This lets the debugger run, ... */ signr = get_signal_to_deliver(&info, &ka, regs, NULL); /* ... so re-check the single stepping. */ single_stepping |= ptrace_cancel_bpt(current); if (signr > 0) { /* Whee! Actually deliver the signal. */ if (r0) syscall_restart(r0, r19, regs, &ka); handle_signal(signr, &ka, &info, oldset, regs, sw); if (r0) syscall_restart(r0, r19, regs, &ka); if (handle_signal(signr, &ka, &info, oldset, regs, sw) == 0) { /* A signal was successfully delivered, and the saved sigmask was stored on the signal frame, and will be restored by sigreturn. So we can simply clear the restore sigmask flag. */ if (test_thread_flag(TIF_RESTORE_SIGMASK)) clear_thread_flag(TIF_RESTORE_SIGMASK); } if (single_stepping) ptrace_set_bpt(current); /* re-set bpt */ return 1; return; } if (r0) { Loading @@ -654,17 +665,22 @@ do_signal(sigset_t *oldset, struct pt_regs * regs, struct switch_stack * sw, break; } } /* If there's no signal to deliver, we just restore the saved mask. */ if (test_thread_flag(TIF_RESTORE_SIGMASK)) { clear_thread_flag(TIF_RESTORE_SIGMASK); sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } if (single_stepping) ptrace_set_bpt(current); /* re-set breakpoint */ return 0; } void do_notify_resume(sigset_t *oldset, struct pt_regs *regs, struct switch_stack *sw, unsigned long r0, unsigned long r19, unsigned long thread_info_flags) do_notify_resume(struct pt_regs *regs, struct switch_stack *sw, unsigned long thread_info_flags, unsigned long r0, unsigned long r19) { if (thread_info_flags & _TIF_SIGPENDING) do_signal(oldset, regs, sw, r0, r19); if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) do_signal(regs, sw, r0, r19); }
arch/alpha/kernel/systbls.S +32 −0 Original line number Diff line number Diff line Loading @@ -465,6 +465,38 @@ sys_call_table: .quad sys_inotify_init .quad sys_inotify_add_watch /* 445 */ .quad sys_inotify_rm_watch .quad sys_fdatasync .quad sys_kexec_load .quad sys_migrate_pages .quad sys_openat /* 450 */ .quad sys_mkdirat .quad sys_mknodat .quad sys_fchownat .quad sys_futimesat .quad sys_fstatat64 /* 455 */ .quad sys_unlinkat .quad sys_renameat .quad sys_linkat .quad sys_symlinkat .quad sys_readlinkat /* 460 */ .quad sys_fchmodat .quad sys_faccessat .quad sys_pselect6 .quad sys_ppoll .quad sys_unshare /* 465 */ .quad sys_set_robust_list .quad sys_get_robust_list .quad sys_splice .quad sys_sync_file_range .quad sys_tee /* 470 */ .quad sys_vmsplice .quad sys_move_pages .quad sys_getcpu .quad sys_epoll_pwait .quad sys_utimensat /* 475 */ .quad sys_signalfd .quad sys_timerfd .quad sys_eventfd .size sys_call_table, . - sys_call_table .type sys_call_table, @object Loading
include/asm-alpha/thread_info.h +2 −0 Original line number Diff line number Diff line Loading @@ -76,12 +76,14 @@ register struct thread_info *__current_thread_info __asm__("$8"); #define TIF_UAC_NOFIX 7 #define TIF_UAC_SIGBUS 8 #define TIF_MEMDIE 9 #define TIF_RESTORE_SIGMASK 10 /* restore signal mask in do_signal */ #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) #define _TIF_SIGPENDING (1<<TIF_SIGPENDING) #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) #define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK) /* Work to do on interrupt/exception return. */ #define _TIF_WORK_MASK (_TIF_NOTIFY_RESUME \ Loading
include/asm-alpha/unistd.h +47 −1 Original line number Diff line number Diff line Loading @@ -233,6 +233,20 @@ #define __NR_osf_memcntl 260 /* not implemented */ #define __NR_osf_fdatasync 261 /* not implemented */ /* * Ignore legacy syscalls that we don't use. */ #define __IGNORE_alarm #define __IGNORE_creat #define __IGNORE_getegid #define __IGNORE_geteuid #define __IGNORE_getgid #define __IGNORE_getpid #define __IGNORE_getppid #define __IGNORE_getuid #define __IGNORE_pause #define __IGNORE_time #define __IGNORE_utime /* * Linux-specific system calls begin at 300 Loading Loading @@ -387,10 +401,42 @@ #define __NR_inotify_init 444 #define __NR_inotify_add_watch 445 #define __NR_inotify_rm_watch 446 #define __NR_fdatasync 447 #define __NR_kexec_load 448 #define __NR_migrate_pages 449 #define __NR_openat 450 #define __NR_mkdirat 451 #define __NR_mknodat 452 #define __NR_fchownat 453 #define __NR_futimesat 454 #define __NR_fstatat64 455 #define __NR_unlinkat 456 #define __NR_renameat 457 #define __NR_linkat 458 #define __NR_symlinkat 459 #define __NR_readlinkat 460 #define __NR_fchmodat 461 #define __NR_faccessat 462 #define __NR_pselect6 463 #define __NR_ppoll 464 #define __NR_unshare 465 #define __NR_set_robust_list 466 #define __NR_get_robust_list 467 #define __NR_splice 468 #define __NR_sync_file_range 469 #define __NR_tee 470 #define __NR_vmsplice 471 #define __NR_move_pages 472 #define __NR_getcpu 473 #define __NR_epoll_pwait 474 #define __NR_utimensat 475 #define __NR_signalfd 476 #define __NR_timerfd 477 #define __NR_eventfd 478 #ifdef __KERNEL__ #define NR_SYSCALLS 447 #define NR_SYSCALLS 479 #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR Loading