#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_USING_IWMMXT 17
#define TIF_MEMDIE 18 /* is terminating due to OOM killer */
#define TIF_RESTORE_SIGMASK 20
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
#define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT)
#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
mov r0, sp @ 'regs'
mov r2, why @ 'syscall'
bl do_work_pending
- cmp r0, #0
+ tst r0, #1
beq no_work_pending
- movlt scno, #(__NR_restart_syscall - __NR_SYSCALL_BASE)
- ldmia sp, {r0 - r5} @ have to reload r0 - r5
+ mov r0, sp @ pointer to regs
+ ldmia r0, {r0 - r5} @ have to reload r0 - r5
b local_restart @ ... and off we go
/*
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;
*/
switch (retval) {
case -ERESTART_RESTARTBLOCK:
- restart -= 2;
+ restart++;
case -ERESTARTNOHAND:
case -ERESTARTSYS:
case -ERESTARTNOINTR:
return 0;
}
- restore_saved_sigmask();
- if (unlikely(restart))
+ if (unlikely(restart)) {
+ if (restart > 1)
+ set_thread_flag(TIF_SYSCALL_RESTARTSYS);
regs->ARM_pc = continue_addr;
+ }
+
+ restore_saved_sigmask();
return restart;
}
return 0;
local_irq_enable();
if (thread_flags & _TIF_SIGPENDING) {
- int restart = do_signal(regs, syscall);
- if (unlikely(restart)) {
+ if (unlikely(do_signal(regs, syscall))) {
/*
* Restart without handlers.
* Deal with it without leaving
* the kernel space.
*/
- return restart;
+ return 1;
}
syscall = 0;
} else {