Loading arch/arm/include/asm/thread_info.h +5 −3 Original line number Diff line number Diff line Loading @@ -148,6 +148,7 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *, #define TIF_NOTIFY_RESUME 2 /* callback before returning to user */ #define TIF_SYSCALL_TRACE 8 #define TIF_SYSCALL_AUDIT 9 #define TIF_SYSCALL_RESTARTSYS 10 #define TIF_POLLING_NRFLAG 16 #define TIF_USING_IWMMXT 17 #define TIF_MEMDIE 18 /* is terminating due to OOM killer */ Loading @@ -162,16 +163,17 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *, #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) #define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT) #define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) #define _TIF_SECCOMP (1 << TIF_SECCOMP) #define _TIF_SYSCALL_RESTARTSYS (1 << TIF_SYSCALL_RESTARTSYS) /* Checks for any syscall work in entry-common.S */ #define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT) #define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \ _TIF_SYSCALL_RESTARTSYS) /* * Change these and you break ASM code in entry-common.S */ #define _TIF_WORK_MASK 0x000000ff #define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | _TIF_NOTIFY_RESUME) #endif /* __KERNEL__ */ #endif /* __ASM_ARM_THREAD_INFO_H */ arch/arm/kernel/entry-common.S +6 −2 Original line number Diff line number Diff line Loading @@ -53,9 +53,13 @@ fast_work_pending: work_pending: tst r1, #_TIF_NEED_RESCHED bne work_resched tst r1, #_TIF_SIGPENDING|_TIF_NOTIFY_RESUME beq no_work_pending /* * TIF_SIGPENDING or TIF_NOTIFY_RESUME must've been set if we got here */ ldr r2, [sp, #S_PSR] mov r0, sp @ 'regs' tst r2, #15 @ are we returning to user mode? bne no_work_pending @ no? just leave, then... mov r2, why @ 'syscall' tst r1, #_TIF_SIGPENDING @ delivering a signal? movne why, #0 @ prevent further restarts Loading arch/arm/kernel/ptrace.c +3 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include <linux/regset.h> #include <linux/audit.h> #include <linux/tracehook.h> #include <linux/unistd.h> #include <asm/pgtable.h> #include <asm/traps.h> Loading Loading @@ -917,6 +918,8 @@ asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno) audit_syscall_entry(AUDIT_ARCH_ARM, scno, regs->ARM_r0, regs->ARM_r1, regs->ARM_r2, regs->ARM_r3); if (why == 0 && test_and_clear_thread_flag(TIF_SYSCALL_RESTARTSYS)) scno = __NR_restart_syscall - __NR_SYSCALL_BASE; if (!test_thread_flag(TIF_SYSCALL_TRACE)) return scno; Loading arch/arm/kernel/signal.c +18 −67 Original line number Diff line number Diff line Loading @@ -29,7 +29,6 @@ */ #define SWI_SYS_SIGRETURN (0xef000000|(__NR_sigreturn)|(__NR_OABI_SYSCALL_BASE)) #define SWI_SYS_RT_SIGRETURN (0xef000000|(__NR_rt_sigreturn)|(__NR_OABI_SYSCALL_BASE)) #define SWI_SYS_RESTART (0xef000000|__NR_restart_syscall|__NR_OABI_SYSCALL_BASE) /* * With EABI, the syscall number has to be loaded into r7. Loading @@ -49,18 +48,6 @@ const unsigned long sigreturn_codes[7] = { MOV_R7_NR_RT_SIGRETURN, SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN, }; /* * Either we support OABI only, or we have EABI with the OABI * compat layer enabled. In the later case we don't know if * user space is EABI or not, and if not we must not clobber r7. * Always using the OABI syscall solves that issue and works for * all those cases. */ const unsigned long syscall_restart_code[2] = { SWI_SYS_RESTART, /* swi __NR_restart_syscall */ 0xe49df004, /* ldr pc, [sp], #4 */ }; /* * atomically swap in the new signal mask, and wait for a signal. */ Loading Loading @@ -91,10 +78,10 @@ sys_sigaction(int sig, const struct old_sigaction __user *act, old_sigset_t mask; if (!access_ok(VERIFY_READ, act, sizeof(*act)) || __get_user(new_ka.sa.sa_handler, &act->sa_handler) || __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) || __get_user(new_ka.sa.sa_flags, &act->sa_flags) || __get_user(mask, &act->sa_mask)) return -EFAULT; __get_user(new_ka.sa.sa_flags, &act->sa_flags); __get_user(mask, &act->sa_mask); siginitset(&new_ka.sa.sa_mask, mask); } Loading @@ -103,10 +90,10 @@ sys_sigaction(int sig, const struct old_sigaction __user *act, if (!ret && oact) { if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) || __put_user(old_ka.sa.sa_flags, &oact->sa_flags) || __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask)) return -EFAULT; __put_user(old_ka.sa.sa_flags, &oact->sa_flags); __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); } return ret; Loading Loading @@ -610,15 +597,6 @@ static void do_signal(struct pt_regs *regs, int syscall) siginfo_t info; int signr; /* * We want the common case to go fast, which * is why we may in certain cases get here from * kernel mode. Just return without doing anything * if so. */ if (!user_mode(regs)) return; /* * If we were from a system call, check for system call restarting... */ Loading @@ -635,18 +613,13 @@ static void do_signal(struct pt_regs *regs, int syscall) case -ERESTARTNOHAND: case -ERESTARTSYS: case -ERESTARTNOINTR: case -ERESTART_RESTARTBLOCK: regs->ARM_r0 = regs->ARM_ORIG_r0; regs->ARM_pc = restart_addr; break; case -ERESTART_RESTARTBLOCK: regs->ARM_r0 = -EINTR; break; } } if (try_to_freeze()) goto no_signal; /* * Get the signal to deliver. When running under ptrace, at this * point the debugger may change all our registers ... Loading @@ -661,12 +634,14 @@ static void do_signal(struct pt_regs *regs, int syscall) * debugger has chosen to restart at a different PC. */ if (regs->ARM_pc == restart_addr) { if (retval == -ERESTARTNOHAND if (retval == -ERESTARTNOHAND || retval == -ERESTART_RESTARTBLOCK || (retval == -ERESTARTSYS && !(ka.sa.sa_flags & SA_RESTART))) { regs->ARM_r0 = -EINTR; regs->ARM_pc = continue_addr; } clear_thread_flag(TIF_SYSCALL_RESTARTSYS); } if (test_thread_flag(TIF_RESTORE_SIGMASK)) Loading @@ -686,7 +661,6 @@ static void do_signal(struct pt_regs *regs, int syscall) return; } no_signal: if (syscall) { /* * Handle restarting a different system call. As above, Loading @@ -694,38 +668,15 @@ static void do_signal(struct pt_regs *regs, int syscall) * ignore the restart. */ if (retval == -ERESTART_RESTARTBLOCK && regs->ARM_pc == continue_addr) { if (thumb_mode(regs)) { regs->ARM_r7 = __NR_restart_syscall - __NR_SYSCALL_BASE; regs->ARM_pc -= 2; } else { #if defined(CONFIG_AEABI) && !defined(CONFIG_OABI_COMPAT) regs->ARM_r7 = __NR_restart_syscall; regs->ARM_pc -= 4; #else u32 __user *usp; regs->ARM_sp -= 4; usp = (u32 __user *)regs->ARM_sp; if (put_user(regs->ARM_pc, usp) == 0) { regs->ARM_pc = KERN_RESTART_CODE; } else { regs->ARM_sp += 4; force_sigsegv(0, current); } #endif } && regs->ARM_pc == restart_addr) set_thread_flag(TIF_SYSCALL_RESTARTSYS); } /* If there's no signal to deliver, we just put the saved sigmask * back. */ if (test_thread_flag(TIF_RESTORE_SIGMASK)) { clear_thread_flag(TIF_RESTORE_SIGMASK); sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } } if (test_and_clear_thread_flag(TIF_RESTORE_SIGMASK)) set_current_blocked(¤t->saved_sigmask); } asmlinkage void Loading arch/arm/kernel/signal.h +0 −2 Original line number Diff line number Diff line Loading @@ -8,7 +8,5 @@ * published by the Free Software Foundation. */ #define KERN_SIGRETURN_CODE (CONFIG_VECTORS_BASE + 0x00000500) #define KERN_RESTART_CODE (KERN_SIGRETURN_CODE + sizeof(sigreturn_codes)) extern const unsigned long sigreturn_codes[7]; extern const unsigned long syscall_restart_code[2]; Loading
arch/arm/include/asm/thread_info.h +5 −3 Original line number Diff line number Diff line Loading @@ -148,6 +148,7 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *, #define TIF_NOTIFY_RESUME 2 /* callback before returning to user */ #define TIF_SYSCALL_TRACE 8 #define TIF_SYSCALL_AUDIT 9 #define TIF_SYSCALL_RESTARTSYS 10 #define TIF_POLLING_NRFLAG 16 #define TIF_USING_IWMMXT 17 #define TIF_MEMDIE 18 /* is terminating due to OOM killer */ Loading @@ -162,16 +163,17 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *, #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) #define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT) #define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) #define _TIF_SECCOMP (1 << TIF_SECCOMP) #define _TIF_SYSCALL_RESTARTSYS (1 << TIF_SYSCALL_RESTARTSYS) /* Checks for any syscall work in entry-common.S */ #define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT) #define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \ _TIF_SYSCALL_RESTARTSYS) /* * Change these and you break ASM code in entry-common.S */ #define _TIF_WORK_MASK 0x000000ff #define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | _TIF_NOTIFY_RESUME) #endif /* __KERNEL__ */ #endif /* __ASM_ARM_THREAD_INFO_H */
arch/arm/kernel/entry-common.S +6 −2 Original line number Diff line number Diff line Loading @@ -53,9 +53,13 @@ fast_work_pending: work_pending: tst r1, #_TIF_NEED_RESCHED bne work_resched tst r1, #_TIF_SIGPENDING|_TIF_NOTIFY_RESUME beq no_work_pending /* * TIF_SIGPENDING or TIF_NOTIFY_RESUME must've been set if we got here */ ldr r2, [sp, #S_PSR] mov r0, sp @ 'regs' tst r2, #15 @ are we returning to user mode? bne no_work_pending @ no? just leave, then... mov r2, why @ 'syscall' tst r1, #_TIF_SIGPENDING @ delivering a signal? movne why, #0 @ prevent further restarts Loading
arch/arm/kernel/ptrace.c +3 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include <linux/regset.h> #include <linux/audit.h> #include <linux/tracehook.h> #include <linux/unistd.h> #include <asm/pgtable.h> #include <asm/traps.h> Loading Loading @@ -917,6 +918,8 @@ asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno) audit_syscall_entry(AUDIT_ARCH_ARM, scno, regs->ARM_r0, regs->ARM_r1, regs->ARM_r2, regs->ARM_r3); if (why == 0 && test_and_clear_thread_flag(TIF_SYSCALL_RESTARTSYS)) scno = __NR_restart_syscall - __NR_SYSCALL_BASE; if (!test_thread_flag(TIF_SYSCALL_TRACE)) return scno; Loading
arch/arm/kernel/signal.c +18 −67 Original line number Diff line number Diff line Loading @@ -29,7 +29,6 @@ */ #define SWI_SYS_SIGRETURN (0xef000000|(__NR_sigreturn)|(__NR_OABI_SYSCALL_BASE)) #define SWI_SYS_RT_SIGRETURN (0xef000000|(__NR_rt_sigreturn)|(__NR_OABI_SYSCALL_BASE)) #define SWI_SYS_RESTART (0xef000000|__NR_restart_syscall|__NR_OABI_SYSCALL_BASE) /* * With EABI, the syscall number has to be loaded into r7. Loading @@ -49,18 +48,6 @@ const unsigned long sigreturn_codes[7] = { MOV_R7_NR_RT_SIGRETURN, SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN, }; /* * Either we support OABI only, or we have EABI with the OABI * compat layer enabled. In the later case we don't know if * user space is EABI or not, and if not we must not clobber r7. * Always using the OABI syscall solves that issue and works for * all those cases. */ const unsigned long syscall_restart_code[2] = { SWI_SYS_RESTART, /* swi __NR_restart_syscall */ 0xe49df004, /* ldr pc, [sp], #4 */ }; /* * atomically swap in the new signal mask, and wait for a signal. */ Loading Loading @@ -91,10 +78,10 @@ sys_sigaction(int sig, const struct old_sigaction __user *act, old_sigset_t mask; if (!access_ok(VERIFY_READ, act, sizeof(*act)) || __get_user(new_ka.sa.sa_handler, &act->sa_handler) || __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) || __get_user(new_ka.sa.sa_flags, &act->sa_flags) || __get_user(mask, &act->sa_mask)) return -EFAULT; __get_user(new_ka.sa.sa_flags, &act->sa_flags); __get_user(mask, &act->sa_mask); siginitset(&new_ka.sa.sa_mask, mask); } Loading @@ -103,10 +90,10 @@ sys_sigaction(int sig, const struct old_sigaction __user *act, if (!ret && oact) { if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) || __put_user(old_ka.sa.sa_flags, &oact->sa_flags) || __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask)) return -EFAULT; __put_user(old_ka.sa.sa_flags, &oact->sa_flags); __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); } return ret; Loading Loading @@ -610,15 +597,6 @@ static void do_signal(struct pt_regs *regs, int syscall) siginfo_t info; int signr; /* * We want the common case to go fast, which * is why we may in certain cases get here from * kernel mode. Just return without doing anything * if so. */ if (!user_mode(regs)) return; /* * If we were from a system call, check for system call restarting... */ Loading @@ -635,18 +613,13 @@ static void do_signal(struct pt_regs *regs, int syscall) case -ERESTARTNOHAND: case -ERESTARTSYS: case -ERESTARTNOINTR: case -ERESTART_RESTARTBLOCK: regs->ARM_r0 = regs->ARM_ORIG_r0; regs->ARM_pc = restart_addr; break; case -ERESTART_RESTARTBLOCK: regs->ARM_r0 = -EINTR; break; } } if (try_to_freeze()) goto no_signal; /* * Get the signal to deliver. When running under ptrace, at this * point the debugger may change all our registers ... Loading @@ -661,12 +634,14 @@ static void do_signal(struct pt_regs *regs, int syscall) * debugger has chosen to restart at a different PC. */ if (regs->ARM_pc == restart_addr) { if (retval == -ERESTARTNOHAND if (retval == -ERESTARTNOHAND || retval == -ERESTART_RESTARTBLOCK || (retval == -ERESTARTSYS && !(ka.sa.sa_flags & SA_RESTART))) { regs->ARM_r0 = -EINTR; regs->ARM_pc = continue_addr; } clear_thread_flag(TIF_SYSCALL_RESTARTSYS); } if (test_thread_flag(TIF_RESTORE_SIGMASK)) Loading @@ -686,7 +661,6 @@ static void do_signal(struct pt_regs *regs, int syscall) return; } no_signal: if (syscall) { /* * Handle restarting a different system call. As above, Loading @@ -694,38 +668,15 @@ static void do_signal(struct pt_regs *regs, int syscall) * ignore the restart. */ if (retval == -ERESTART_RESTARTBLOCK && regs->ARM_pc == continue_addr) { if (thumb_mode(regs)) { regs->ARM_r7 = __NR_restart_syscall - __NR_SYSCALL_BASE; regs->ARM_pc -= 2; } else { #if defined(CONFIG_AEABI) && !defined(CONFIG_OABI_COMPAT) regs->ARM_r7 = __NR_restart_syscall; regs->ARM_pc -= 4; #else u32 __user *usp; regs->ARM_sp -= 4; usp = (u32 __user *)regs->ARM_sp; if (put_user(regs->ARM_pc, usp) == 0) { regs->ARM_pc = KERN_RESTART_CODE; } else { regs->ARM_sp += 4; force_sigsegv(0, current); } #endif } && regs->ARM_pc == restart_addr) set_thread_flag(TIF_SYSCALL_RESTARTSYS); } /* If there's no signal to deliver, we just put the saved sigmask * back. */ if (test_thread_flag(TIF_RESTORE_SIGMASK)) { clear_thread_flag(TIF_RESTORE_SIGMASK); sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } } if (test_and_clear_thread_flag(TIF_RESTORE_SIGMASK)) set_current_blocked(¤t->saved_sigmask); } asmlinkage void Loading
arch/arm/kernel/signal.h +0 −2 Original line number Diff line number Diff line Loading @@ -8,7 +8,5 @@ * published by the Free Software Foundation. */ #define KERN_SIGRETURN_CODE (CONFIG_VECTORS_BASE + 0x00000500) #define KERN_RESTART_CODE (KERN_SIGRETURN_CODE + sizeof(sigreturn_codes)) extern const unsigned long sigreturn_codes[7]; extern const unsigned long syscall_restart_code[2];