aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel
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/arm/kernel
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/arm/kernel')
-rw-r--r--arch/arm/kernel/ptrace.c8
-rw-r--r--arch/arm/kernel/signal.c33
2 files changed, 13 insertions, 28 deletions
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();