x86_64: remove bogus optimization in sysret_signal
This short-circuit path in sysret_signal looks wrong to me. AFAICT, in practice the branch is never taken--and if it were, it would go wrong. To wit, try loading a module whose init function does set_thread_flag(TIF_IRET), and see insmod crash (presumably with a wrong user stack pointer). This is because the FIXUP_TOP_OF_STACK work hasn't been done yet when we jump around the call to ptregscall_common and get to int_with_check--where it expects the user RSP,SS,CS and EFLAGS to have been stored by FIXUP_TOP_OF_STACK. I don't think it's normally possible to get to sysret_signal with no _TIF_DO_NOTIFY_MASK bits set anyway, so these two instructions are already superfluous. If it ever did happen, it is harmless to call do_notify_resume with nothing for it to do. Signed-off-by: Roland McGrath <roland@redhat.com>
This commit is contained in:
parent
20b7997e8a
commit
15e8f348db
1 changed files with 1 additions and 5 deletions
|
@ -402,16 +402,12 @@ sysret_careful:
|
|||
sysret_signal:
|
||||
TRACE_IRQS_ON
|
||||
ENABLE_INTERRUPTS(CLBR_NONE)
|
||||
testl $_TIF_DO_NOTIFY_MASK,%edx
|
||||
jz 1f
|
||||
|
||||
/* Really a signal */
|
||||
/* edx: work flags (arg3) */
|
||||
leaq do_notify_resume(%rip),%rax
|
||||
leaq -ARGOFFSET(%rsp),%rdi # &pt_regs -> arg1
|
||||
xorl %esi,%esi # oldset -> arg2
|
||||
call ptregscall_common
|
||||
1: movl $_TIF_WORK_MASK,%edi
|
||||
movl $_TIF_WORK_MASK,%edi
|
||||
/* Use IRET because user could have changed frame. This
|
||||
works because ptregscall_common has called FIXUP_TOP_OF_STACK. */
|
||||
DISABLE_INTERRUPTS(CLBR_NONE)
|
||||
|
|
Loading…
Reference in a new issue