[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20111019215344.GG16395@redhat.com>
Date: Wed, 19 Oct 2011 23:53:44 +0200
From: Oleg Nesterov <oleg@...hat.com>
To: Srikar Dronamraju <srikar@...ux.vnet.ibm.com>
Cc: Peter Zijlstra <peterz@...radead.org>, Ingo Molnar <mingo@...e.hu>,
Steven Rostedt <rostedt@...dmis.org>,
Linux-mm <linux-mm@...ck.org>,
Arnaldo Carvalho de Melo <acme@...radead.org>,
Linus Torvalds <torvalds@...ux-foundation.org>,
Jonathan Corbet <corbet@....net>,
Masami Hiramatsu <masami.hiramatsu.pt@...achi.com>,
Hugh Dickins <hughd@...gle.com>,
Christoph Hellwig <hch@...radead.org>,
Ananth N Mavinakayanahalli <ananth@...ibm.com>,
Thomas Gleixner <tglx@...utronix.de>,
Andi Kleen <andi@...stfloor.org>,
Andrew Morton <akpm@...ux-foundation.org>,
Jim Keniston <jkenisto@...ux.vnet.ibm.com>,
Roland McGrath <roland@...k.frob.com>,
LKML <linux-kernel@...r.kernel.org>
Subject: [PATCH 13/X] uprobes: introduce UTASK_SSTEP_TRAPPED logic
Finally, add UTASK_SSTEP_TRAPPED state/code to handle the case when
xol insn itself triggers the signal.
In this case we should restart the original insn even if the task is
already SIGKILL'ed (say, the coredump should report the correct ip).
This is even more important if the task has a handler for SIGSEGV/etc,
The _same_ instruction should be repeated again after return from the
signal handler, and SSTEP can never finish in this case.
So this patch changes uprobe_deny_signal() to set UTASK_SSTEP_TRAPPED
and TIF_UPROBE. It also sets TIF_NOTIFY_RESUME, _afaics_ TIF_UPROBE
alone is not enough to trigger do_notify_resume() in this case.
When uprobe_notify_resume() sees UTASK_SSTEP_TRAPPED it does abort_xol()
instead of post_xol().
---
arch/x86/kernel/uprobes.c | 1 +
include/linux/uprobes.h | 1 +
kernel/uprobes.c | 8 ++++++++
3 files changed, 10 insertions(+), 0 deletions(-)
diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
index bc11a89..73f58ad 100644
--- a/arch/x86/kernel/uprobes.c
+++ b/arch/x86/kernel/uprobes.c
@@ -550,6 +550,7 @@ int post_xol(struct uprobe *uprobe, struct pt_regs *regs)
int result = 0;
long correction;
+ WARN_ON_ONCE(current->thread.trap_no != UPROBE_TRAP_NO);
current->thread.trap_no = utask->tskinfo.saved_trap_no;
correction = (long)(utask->vaddr - utask->xol_vaddr);
diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h
index 27928e5..2b4bc8c 100644
--- a/include/linux/uprobes.h
+++ b/include/linux/uprobes.h
@@ -76,6 +76,7 @@ enum uprobe_task_state {
UTASK_BP_HIT,
UTASK_SSTEP,
UTASK_SSTEP_ACK,
+ UTASK_SSTEP_TRAPPED,
};
/*
diff --git a/kernel/uprobes.c b/kernel/uprobes.c
index d6f4508..aa5492a 100644
--- a/kernel/uprobes.c
+++ b/kernel/uprobes.c
@@ -1334,6 +1334,12 @@ bool uprobe_deny_signal(void)
spin_lock_irq(&tsk->sighand->siglock);
clear_tsk_thread_flag(tsk, TIF_SIGPENDING);
spin_unlock_irq(&tsk->sighand->siglock);
+
+ if (xol_was_trapped(tsk)) {
+ utask->state = UTASK_SSTEP_TRAPPED;
+ set_tsk_thread_flag(tsk, TIF_UPROBE);
+ set_tsk_thread_flag(tsk, TIF_NOTIFY_RESUME);
+ }
}
return true;
@@ -1389,6 +1395,8 @@ void uprobe_notify_resume(struct pt_regs *regs)
if (utask->state == UTASK_SSTEP_ACK)
post_xol(u, regs); /* TODO: check result? */
+ else if (utask->state == UTASK_SSTEP_TRAPPED)
+ abort_xol(regs);
else
WARN_ON_ONCE(1);
--
1.5.5.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists