aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOleg Nesterov <oleg@redhat.com>2012-09-08 12:38:15 -0400
committerOleg Nesterov <oleg@redhat.com>2012-09-15 11:37:32 -0400
commitd6a00b35e411519d774d978cdf80e4406d01b36b (patch)
treee928315e06a4b6199d173848fac7d08301b32362
parent3a4664aa8362d9fa9110828f55afa9f9fcd7e484 (diff)
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>
-rw-r--r--arch/x86/kernel/uprobes.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
index 7e993d1f1992..9538f00827a9 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)
706{ 706{
707 struct task_struct *task = current; 707 struct task_struct *task = current;
708 struct arch_uprobe_task *autask = &task->utask->autask; 708 struct arch_uprobe_task *autask = &task->utask->autask;
709 bool trapped = (task->utask->state == UTASK_SSTEP_TRAPPED);
709 struct pt_regs *regs = task_pt_regs(task); 710 struct pt_regs *regs = task_pt_regs(task);
710 /* 711 /*
711 * The state of TIF_BLOCKSTEP was not saved so we can get an extra 712 * The state of TIF_BLOCKSTEP was not saved so we can get an extra
712 * SIGTRAP if we do not clear TF. We need to examine the opcode to 713 * SIGTRAP if we do not clear TF. We need to examine the opcode to
713 * make it right. 714 * make it right.
714 */ 715 */
715 if (autask->saved_tf) 716 if (unlikely(trapped)) {
716 send_sig(SIGTRAP, task, 0); 717 if (!autask->saved_tf)
717 else if (!(auprobe->fixups & UPROBE_FIX_SETF)) 718 regs->flags &= ~X86_EFLAGS_TF;
718 regs->flags &= ~X86_EFLAGS_TF; 719 } else {
720 if (autask->saved_tf)
721 send_sig(SIGTRAP, task, 0);
722 else if (!(auprobe->fixups & UPROBE_FIX_SETF))
723 regs->flags &= ~X86_EFLAGS_TF;
724 }
719} 725}