uprobes/x86: Fix arch_uprobe_disable_step() && UTASK_SSTEP_TRAPPED interaction
arch_uprobe_disable_step() should also take UTASK_SSTEP_TRAPPED into account. In this case the probed insn was not executed, we need to clear X86_EFLAGS_TF if it was set by us and that is all. Again, this code will look more clean when we move it into arch_uprobe_post_xol() and arch_uprobe_abort_xol(). Signed-off-by: Oleg Nesterov <oleg@redhat.com> Acked-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
This commit is contained in:
Родитель
3a4664aa83
Коммит
d6a00b35e4
|
@ -706,14 +706,20 @@ void arch_uprobe_disable_step(struct arch_uprobe *auprobe)
|
|||
{
|
||||
struct task_struct *task = current;
|
||||
struct arch_uprobe_task *autask = &task->utask->autask;
|
||||
bool trapped = (task->utask->state == UTASK_SSTEP_TRAPPED);
|
||||
struct pt_regs *regs = task_pt_regs(task);
|
||||
/*
|
||||
* The state of TIF_BLOCKSTEP was not saved so we can get an extra
|
||||
* SIGTRAP if we do not clear TF. We need to examine the opcode to
|
||||
* make it right.
|
||||
*/
|
||||
if (autask->saved_tf)
|
||||
send_sig(SIGTRAP, task, 0);
|
||||
else if (!(auprobe->fixups & UPROBE_FIX_SETF))
|
||||
regs->flags &= ~X86_EFLAGS_TF;
|
||||
if (unlikely(trapped)) {
|
||||
if (!autask->saved_tf)
|
||||
regs->flags &= ~X86_EFLAGS_TF;
|
||||
} else {
|
||||
if (autask->saved_tf)
|
||||
send_sig(SIGTRAP, task, 0);
|
||||
else if (!(auprobe->fixups & UPROBE_FIX_SETF))
|
||||
regs->flags &= ~X86_EFLAGS_TF;
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче