If we end up calling do_notify_resume() with !user_mode(refs), it
does nothing (do_signal() explicitly bails out and we can't get there
with TIF_NOTIFY_RESUME in such situations).  Then we jump to
resume_userspace_sig, which rechecks the same thing and bails out
to resume_kernel, thus breaking the loop.
It's easier and cheaper to check *before* calling do_notify_resume()
and bail out to resume_kernel immediately.  And kill the check in
do_signal()...
Note that on amd64 we can't get there with !user_mode() at all - asm
glue takes care of that.
Acked-and-reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
        preempt_stop(CLBR_ANY)
 ret_from_intr:
        GET_THREAD_INFO(%ebp)
-resume_userspace_sig:
 #ifdef CONFIG_VM86
        movl PT_EFLAGS(%esp), %eax      # mix EFLAGS and CS
        movb PT_CS(%esp), %al
                                        # vm86-space
        TRACE_IRQS_ON
        ENABLE_INTERRUPTS(CLBR_NONE)
+       movb PT_CS(%esp), %bl
+       andb $SEGMENT_RPL_MASK, %bl
+       cmpb $USER_RPL, %bl
+       jb resume_kernel
        xorl %edx, %edx
        call do_notify_resume
-       jmp resume_userspace_sig
+       jmp resume_userspace
 
        ALIGN
 work_notifysig_v86:
 #endif
        TRACE_IRQS_ON
        ENABLE_INTERRUPTS(CLBR_NONE)
+       movb PT_CS(%esp), %bl
+       andb $SEGMENT_RPL_MASK, %bl
+       cmpb $USER_RPL, %bl
+       jb resume_kernel
        xorl %edx, %edx
        call do_notify_resume
-       jmp resume_userspace_sig
+       jmp resume_userspace
 END(work_pending)
 
        # perform syscall exit tracing
 
        siginfo_t info;
        int signr;
 
-       /*
-        * We want the common case to go fast, which is why we may in certain
-        * cases get here from kernel mode. Just return without doing anything
-        * if so.
-        * X86_32: vm86 regs switched out by assembly code before reaching
-        * here, so testing against kernel CS suffices.
-        */
-       if (!user_mode(regs))
-               return;
-
        signr = get_signal_to_deliver(&info, &ka, regs, NULL);
        if (signr > 0) {
                /* Whee! Actually deliver the signal.  */