Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 44fbbb3d authored by Al Viro's avatar Al Viro
Browse files

x86: get rid of calling do_notify_resume() when returning to kernel mode



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: default avatarThomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 29bf5dd8
Loading
Loading
Loading
Loading
+10 −3
Original line number Diff line number Diff line
@@ -316,7 +316,6 @@ ret_from_exception:
	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
@@ -615,9 +614,13 @@ work_notifysig: # deal with pending signals and
					# 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:
@@ -630,9 +633,13 @@ 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
+0 −10
Original line number Diff line number Diff line
@@ -737,16 +737,6 @@ static void do_signal(struct pt_regs *regs)
	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.  */