return !!(regs->flags & (1UL << flag));
 }
 
+static inline int test_and_clear_pt_regs_flag(struct pt_regs *regs, int flag)
+{
+       int ret = test_pt_regs_flag(regs, flag);
+
+       clear_pt_regs_flag(regs, flag);
+       return ret;
+}
+
 /*
  * These are defined as per linux/ptrace.h, which see.
  */
 
         * work, the ptrace code sets PIF_SYSCALL_RET_SET, which is checked here
         * and if set, the syscall will be skipped.
         */
-       if (!test_pt_regs_flag(regs, PIF_SYSCALL_RET_SET)) {
-               regs->gprs[2] = -ENOSYS;
-               if (likely(nr < NR_syscalls))
-                       regs->gprs[2] = current->thread.sys_call_table[nr](regs);
-       } else {
-               clear_pt_regs_flag(regs, PIF_SYSCALL_RET_SET);
-       }
+       if (unlikely(test_and_clear_pt_regs_flag(regs, PIF_SYSCALL_RET_SET)))
+               goto out;
+       regs->gprs[2] = -ENOSYS;
+       if (likely(nr >= NR_syscalls))
+               goto out;
+       do {
+               regs->gprs[2] = current->thread.sys_call_table[nr](regs);
+       } while (test_and_clear_pt_regs_flag(regs, PIF_SYSCALL_RESTART));
+out:
        syscall_exit_to_user_mode_work(regs);
 }
 
        if (per_trap)
                set_thread_flag(TIF_PER_TRAP);
 
-       for (;;) {
-               regs->flags = 0;
-               set_pt_regs_flag(regs, PIF_SYSCALL);
-               do_syscall(regs);
-               if (!test_pt_regs_flag(regs, PIF_SYSCALL_RESTART))
-                       break;
-               local_irq_enable();
-       }
+       regs->flags = 0;
+       set_pt_regs_flag(regs, PIF_SYSCALL);
+       do_syscall(regs);
        exit_to_user_mode();
 }