diff options
author | Will Deacon <will.deacon@arm.com> | 2012-07-19 12:46:44 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2012-07-28 06:11:51 -0400 |
commit | ad82cc08f70486b5741560b1b2121dadf82897de (patch) | |
tree | 4e95106f82bf8d7db53fbbec1c04b81c36b1243e /arch | |
parent | ad722541147e6e517a2077e3d944105e7bc4fa8e (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.h | 5 | ||||
-rw-r--r-- | arch/arm/kernel/ptrace.c | 8 | ||||
-rw-r--r-- | arch/arm/kernel/signal.c | 33 |
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 | ||
941 | asmlinkage int syscall_trace_enter(struct pt_regs *regs, int scno) | 942 | asmlinkage 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(); |