diff options
author | Oleg Nesterov <oleg@redhat.com> | 2012-09-08 18:38:15 +0200 |
---|---|---|
committer | Anton Arapov <anton@redhat.com> | 2012-10-29 11:23:47 +0100 |
commit | 9df971294861bd6de1d699b4f0cedcfb8cfbc95f (patch) | |
tree | 451d21646ad15c91c003962e1f87d9026012b197 /arch/x86/kernel/uprobes.c | |
parent | 65f4fb9715827630e63934868e53781ea82ea0e1 (diff) | |
download | kernel-uprobes-9df971294861bd6de1d699b4f0cedcfb8cfbc95f.tar.gz kernel-uprobes-9df971294861bd6de1d699b4f0cedcfb8cfbc95f.tar.xz kernel-uprobes-9df971294861bd6de1d699b4f0cedcfb8cfbc95f.zip |
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>
Diffstat (limited to 'arch/x86/kernel/uprobes.c')
-rw-r--r-- | arch/x86/kernel/uprobes.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c index 7e993d1f199..9538f00827a 100644 --- a/arch/x86/kernel/uprobes.c +++ b/arch/x86/kernel/uprobes.c @@ -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; + } } |