aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorWill Deacon <will.deacon@arm.com>2012-07-19 12:46:44 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2012-07-28 06:11:51 -0400
commitad82cc08f70486b5741560b1b2121dadf82897de (patch)
tree4e95106f82bf8d7db53fbbec1c04b81c36b1243e /arch
parentad722541147e6e517a2077e3d944105e7bc4fa8e (diff)
ARM: 7470/1: Revert "7443/1: Revert "new way of handling ERESTART_RESTARTBLOCK""
This reverts commit 433e2f307beff8adba241646ce9108544e0c5a03. Conflicts: arch/arm/kernel/ptrace.c Reintroduce the new syscall restart handling in preparation for further patches from Al Viro. Signed-off-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/include/asm/thread_info.h5
-rw-r--r--arch/arm/kernel/ptrace.c8
-rw-r--r--arch/arm/kernel/signal.c33
3 files changed, 17 insertions, 29 deletions
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
index af7b0bda3355..b79f8e97f775 100644
--- a/arch/arm/include/asm/thread_info.h
+++ b/arch/arm/include/asm/thread_info.h
@@ -148,6 +148,7 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *,
148#define TIF_NOTIFY_RESUME 2 /* callback before returning to user */ 148#define TIF_NOTIFY_RESUME 2 /* callback before returning to user */
149#define TIF_SYSCALL_TRACE 8 149#define TIF_SYSCALL_TRACE 8
150#define TIF_SYSCALL_AUDIT 9 150#define TIF_SYSCALL_AUDIT 9
151#define TIF_SYSCALL_RESTARTSYS 10
151#define TIF_POLLING_NRFLAG 16 152#define TIF_POLLING_NRFLAG 16
152#define TIF_USING_IWMMXT 17 153#define TIF_USING_IWMMXT 17
153#define TIF_MEMDIE 18 /* is terminating due to OOM killer */ 154#define TIF_MEMDIE 18 /* is terminating due to OOM killer */
@@ -163,9 +164,11 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *,
163#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) 164#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
164#define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT) 165#define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT)
165#define _TIF_SECCOMP (1 << TIF_SECCOMP) 166#define _TIF_SECCOMP (1 << TIF_SECCOMP)
167#define _TIF_SYSCALL_RESTARTSYS (1 << TIF_SYSCALL_RESTARTSYS)
166 168
167/* Checks for any syscall work in entry-common.S */ 169/* Checks for any syscall work in entry-common.S */
168#define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT) 170#define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
171 _TIF_SYSCALL_RESTARTSYS)
169 172
170/* 173/*
171 * Change these and you break ASM code in entry-common.S 174 * Change these and you break ASM code in entry-common.S
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index dab711e6e1ca..efd25d65ae13 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -25,6 +25,7 @@
25#include <linux/regset.h> 25#include <linux/regset.h>
26#include <linux/audit.h> 26#include <linux/audit.h>
27#include <linux/tracehook.h> 27#include <linux/tracehook.h>
28#include <linux/unistd.h>
28 29
29#include <asm/pgtable.h> 30#include <asm/pgtable.h>
30#include <asm/traps.h> 31#include <asm/traps.h>
@@ -940,7 +941,12 @@ static int ptrace_syscall_trace(struct pt_regs *regs, int scno,
940 941
941asmlinkage int syscall_trace_enter(struct pt_regs *regs, int scno) 942asmlinkage int syscall_trace_enter(struct pt_regs *regs, int scno)
942{ 943{
943 int ret = ptrace_syscall_trace(regs, scno, PTRACE_SYSCALL_ENTER); 944 int ret;
945
946 if (test_and_clear_thread_flag(TIF_SYSCALL_RESTARTSYS))
947 scno = __NR_restart_syscall - __NR_SYSCALL_BASE;
948
949 ret = ptrace_syscall_trace(regs, scno, PTRACE_SYSCALL_ENTER);
944 audit_syscall_entry(AUDIT_ARCH_ARM, scno, regs->ARM_r0, regs->ARM_r1, 950 audit_syscall_entry(AUDIT_ARCH_ARM, scno, regs->ARM_r0, regs->ARM_r1,
945 regs->ARM_r2, regs->ARM_r3); 951 regs->ARM_r2, regs->ARM_r3);
946 return ret; 952 return ret;
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index 536c5d6b340b..6d3bce5bd7bc 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -605,12 +605,10 @@ static void do_signal(struct pt_regs *regs, int syscall)
605 case -ERESTARTNOHAND: 605 case -ERESTARTNOHAND:
606 case -ERESTARTSYS: 606 case -ERESTARTSYS:
607 case -ERESTARTNOINTR: 607 case -ERESTARTNOINTR:
608 case -ERESTART_RESTARTBLOCK:
608 regs->ARM_r0 = regs->ARM_ORIG_r0; 609 regs->ARM_r0 = regs->ARM_ORIG_r0;
609 regs->ARM_pc = restart_addr; 610 regs->ARM_pc = restart_addr;
610 break; 611 break;
611 case -ERESTART_RESTARTBLOCK:
612 regs->ARM_r0 = -EINTR;
613 break;
614 } 612 }
615 } 613 }
616 614
@@ -626,12 +624,14 @@ static void do_signal(struct pt_regs *regs, int syscall)
626 * debugger has chosen to restart at a different PC. 624 * debugger has chosen to restart at a different PC.
627 */ 625 */
628 if (regs->ARM_pc == restart_addr) { 626 if (regs->ARM_pc == restart_addr) {
629 if (retval == -ERESTARTNOHAND 627 if (retval == -ERESTARTNOHAND ||
628 retval == -ERESTART_RESTARTBLOCK
630 || (retval == -ERESTARTSYS 629 || (retval == -ERESTARTSYS
631 && !(ka.sa.sa_flags & SA_RESTART))) { 630 && !(ka.sa.sa_flags & SA_RESTART))) {
632 regs->ARM_r0 = -EINTR; 631 regs->ARM_r0 = -EINTR;
633 regs->ARM_pc = continue_addr; 632 regs->ARM_pc = continue_addr;
634 } 633 }
634 clear_thread_flag(TIF_SYSCALL_RESTARTSYS);
635 } 635 }
636 636
637 handle_signal(signr, &ka, &info, regs); 637 handle_signal(signr, &ka, &info, regs);
@@ -645,29 +645,8 @@ static void do_signal(struct pt_regs *regs, int syscall)
645 * ignore the restart. 645 * ignore the restart.
646 */ 646 */
647 if (retval == -ERESTART_RESTARTBLOCK 647 if (retval == -ERESTART_RESTARTBLOCK
648 && regs->ARM_pc == continue_addr) { 648 && regs->ARM_pc == restart_addr)
649 if (thumb_mode(regs)) { 649 set_thread_flag(TIF_SYSCALL_RESTARTSYS);
650 regs->ARM_r7 = __NR_restart_syscall - __NR_SYSCALL_BASE;
651 regs->ARM_pc -= 2;
652 } else {
653#if defined(CONFIG_AEABI) && !defined(CONFIG_OABI_COMPAT)
654 regs->ARM_r7 = __NR_restart_syscall;
655 regs->ARM_pc -= 4;
656#else
657 u32 __user *usp;
658
659 regs->ARM_sp -= 4;
660 usp = (u32 __user *)regs->ARM_sp;
661
662 if (put_user(regs->ARM_pc, usp) == 0) {
663 regs->ARM_pc = KERN_RESTART_CODE;
664 } else {
665 regs->ARM_sp += 4;
666 force_sigsegv(0, current);
667 }
668#endif
669 }
670 }
671 } 650 }
672 651
673 restore_saved_sigmask(); 652 restore_saved_sigmask();