@@ -24,7 +24,6 @@ typedef struct {
#include <asm/sigcontext.h>
void do_rseq_syscall(struct pt_regs *regs);
-int do_work_pending(struct pt_regs *regs, unsigned int thread_flags,
- int syscall);
+void do_work_pending(struct pt_regs *regs, unsigned int thread_flags);
#endif
@@ -86,14 +86,8 @@ ENDPROC(ret_fast_syscall)
bne __sys_trace_return_nosave
slow_work_pending:
mov r0, sp @ 'regs'
- mov r2, why @ 'syscall'
bl do_work_pending
- cmp r0, #0
- beq no_work_pending
- movlt scno, #(__NR_restart_syscall - __NR_SYSCALL_BASE)
- str scno, [tsk, #TI_ABI_SYSCALL] @ make sure tracers see update
- ldmia sp, {r0 - r6} @ have to reload r0 - r6
- b local_restart @ ... and off we go
+ b no_work_pending
ENDPROC(ret_fast_syscall)
/*
@@ -266,7 +260,6 @@ ENTRY(vector_swi)
*/
TRACE( ldmia sp, {r0 - r3} )
-local_restart:
ldr r10, [tsk, #TI_FLAGS] @ check for syscall tracing
stmdb sp!, {r4, r5} @ push fifth and sixth args
@@ -18,6 +18,7 @@
#include <asm/traps.h>
#include <asm/unistd.h>
#include <asm/vfp.h>
+#include <asm/syscall.h>
#include <asm/syscalls.h>
#include "signal.h"
@@ -534,9 +535,10 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
* the kernel can handle, and then we build all the user-level signal handling
* stack-frames in one go after that.
*/
-static int do_signal(struct pt_regs *regs, int syscall)
+static void arch_do_signal_or_restart(struct pt_regs *regs)
{
unsigned int retval = 0, continue_addr = 0, restart_addr = 0;
+ bool syscall = (syscall_get_nr(current, regs) != -1);
struct ksignal ksig;
int restart = 0;
@@ -590,16 +592,14 @@ static int do_signal(struct pt_regs *regs, int syscall)
} else {
/* no handler */
restore_saved_sigmask();
- if (unlikely(restart) && regs->ARM_pc == restart_addr) {
+ if (unlikely(restart) && regs->ARM_pc == restart_addr)
regs->ARM_pc = continue_addr;
- return restart;
- }
}
- return 0;
+ return;
}
-asmlinkage int
-do_work_pending(struct pt_regs *regs, unsigned int thread_flags, int syscall)
+asmlinkage void
+do_work_pending(struct pt_regs *regs, unsigned int thread_flags)
{
/*
* The assembly code enters us with IRQs off, but it hasn't
@@ -612,19 +612,10 @@ do_work_pending(struct pt_regs *regs, unsigned int thread_flags, int syscall)
schedule();
} else {
if (unlikely(!user_mode(regs)))
- return 0;
+ return;
local_irq_enable();
if (thread_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL)) {
- int restart = do_signal(regs, syscall);
- if (unlikely(restart)) {
- /*
- * Restart without handlers.
- * Deal with it without leaving
- * the kernel space.
- */
- return restart;
- }
- syscall = 0;
+ arch_do_signal_or_restart(regs);
} else if (thread_flags & _TIF_UPROBE) {
uprobe_notify_resume(regs);
} else {
@@ -634,7 +625,6 @@ do_work_pending(struct pt_regs *regs, unsigned int thread_flags, int syscall)
local_irq_disable();
thread_flags = read_thread_flags();
} while (thread_flags & _TIF_WORK_MASK);
- return 0;
}
struct page *get_signal_page(void)
The ARM kernel contains a quirk to handle syscall restarts inside the kernel without exiting to userspace. The generic entry cannot handle this. Rename do_signal() to arch_do_signal_or_restart() to fit with the upcoming generic entry conversion. This is essentially a revert of commit 81783786d5cf "ARM: 7473/1: deal with handlerless restarts without leaving the kernel" from 2012. After the conversion to generic entry later in this series, the local restart will be reimplemented again, but in C. Link: http://lists.infradead.org/pipermail/linux-arm-kernel/2012-June/104733.html Link: https://lore.kernel.org/all/1340377626-17075-1-git-send-email-will.deacon@arm.com/ Signed-off-by: Linus Walleij <linus.walleij@linaro.org> --- arch/arm/include/asm/signal.h | 3 +-- arch/arm/kernel/entry-common.S | 9 +-------- arch/arm/kernel/signal.c | 28 +++++++++------------------- 3 files changed, 11 insertions(+), 29 deletions(-)