mirror of https://gitee.com/openkylin/linux.git
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: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
29bf5dd895
commit
44fbbb3dc6
|
@ -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
|
||||
|
|
|
@ -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. */
|
||||
|
|
Loading…
Reference in New Issue