From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 26898 invoked by alias); 19 Dec 2013 09:09:59 -0000 Mailing-List: contact systemtap-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: systemtap-owner@sourceware.org Received: (qmail 26831 invoked by uid 89); 19 Dec 2013 09:09:59 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.7 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail9.hitachi.co.jp Received: from mail9.hitachi.co.jp (HELO mail9.hitachi.co.jp) (133.145.228.44) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 19 Dec 2013 09:09:57 +0000 Received: from mlsv8.hitachi.co.jp (unknown [133.144.234.166]) by mail9.hitachi.co.jp (Postfix) with ESMTP id 7340337C95; Thu, 19 Dec 2013 18:09:55 +0900 (JST) Received: from mfilter05.hitachi.co.jp by mlsv8.hitachi.co.jp (8.13.1/8.13.1) id rBJ99tvl013694; Thu, 19 Dec 2013 18:09:55 +0900 Received: from vshuts01.hitachi.co.jp (vshuts01.hitachi.co.jp [10.201.6.83]) by mfilter05.hitachi.co.jp (Switch-3.3.4/Switch-3.3.4) with ESMTP id rBJ99q9C005287; Thu, 19 Dec 2013 18:09:54 +0900 Received: from gmml27.itg.hitachi.co.jp (unknown [158.213.165.130]) by vshuts01.hitachi.co.jp (Postfix) with ESMTP id 9EE6B2F0043; Thu, 19 Dec 2013 18:09:53 +0900 (JST) Received: from kbuild-fedora.novalocal by gmml27.itg.hitachi.co.jp (AIX5.2/8.11.6p2/8.11.0) id rBJ99r211079846; Thu, 19 Dec 2013 18:09:53 +0900 Subject: [PATCH -tip v6 07/22] kprobes/x86: Call exception handlers directly from do_int3/do_debug To: Ingo Molnar From: Masami Hiramatsu Cc: linux-arch@vger.kernel.org, Andi Kleen , Ananth N Mavinakayanahalli , Sandeepa Prabhu , Frederic Weisbecker , x86@kernel.org, lkml , Steven Rostedt , Andrew Morton , Ingo Molnar , systemtap@sourceware.org, "H. Peter Anvin" , Sasha Levin , Thomas Gleixner , Seiji Aguchi , "David S. Miller" Date: Thu, 19 Dec 2013 09:10:00 -0000 Message-ID: <20131219090411.14309.86591.stgit@kbuild-fedora.novalocal> In-Reply-To: <20131219090353.14309.15496.stgit@kbuild-fedora.novalocal> References: <20131219090353.14309.15496.stgit@kbuild-fedora.novalocal> User-Agent: StGit/0.16 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-IsSubscribed: yes X-SW-Source: 2013-q4/txt/msg00440.txt.bz2 To avoid a kernel crash by probing on lockdep code, call kprobe_int3_handler and kprobe_debug_handler directly from do_int3 and do_debug. Since there is a locking code in notify_die, lockdep code can be invoked. And because the lockdep involves printk() related things, theoretically, we need to prohibit probing on much more code... Anyway, most of the int3 handlers in the kernel are already called from do_int3 directly, e.g. ftrace_int3_handler, poke_int3_handler, kgdb_ll_trap. Actually only kprobe_exceptions_notify is on the notifier_call_chain. Signed-off-by: Masami Hiramatsu Cc: Thomas Gleixner Cc: Ingo Molnar Cc: "H. Peter Anvin" Cc: Ananth N Mavinakayanahalli Cc: Andi Kleen Cc: Steven Rostedt Cc: Sasha Levin Cc: Andrew Morton Cc: Seiji Aguchi Cc: Frederic Weisbecker --- arch/x86/include/asm/kprobes.h | 2 ++ arch/x86/kernel/kprobes/core.c | 24 +++--------------------- arch/x86/kernel/traps.c | 10 ++++++++++ 3 files changed, 15 insertions(+), 21 deletions(-) diff --git a/arch/x86/include/asm/kprobes.h b/arch/x86/include/asm/kprobes.h index 9454c16..53cdfb2 100644 --- a/arch/x86/include/asm/kprobes.h +++ b/arch/x86/include/asm/kprobes.h @@ -116,4 +116,6 @@ struct kprobe_ctlblk { extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr); extern int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val, void *data); +extern int kprobe_int3_handler(struct pt_regs *regs); +extern int kprobe_debug_handler(struct pt_regs *regs); #endif /* _ASM_X86_KPROBES_H */ diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c index c01e70f..4d7dbe1 100644 --- a/arch/x86/kernel/kprobes/core.c +++ b/arch/x86/kernel/kprobes/core.c @@ -558,7 +558,7 @@ reenter_kprobe(struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *kcb * Interrupts are disabled on entry as trap3 is an interrupt gate and they * remain disabled throughout this function. */ -static int __kprobes kprobe_handler(struct pt_regs *regs) +int __kprobes kprobe_int3_handler(struct pt_regs *regs) { kprobe_opcode_t *addr; struct kprobe *p; @@ -856,7 +856,7 @@ no_change: * Interrupts are disabled on entry as trap1 is an interrupt gate and they * remain disabled throughout this function. */ -static int __kprobes post_kprobe_handler(struct pt_regs *regs) +int __kprobes kprobe_debug_handler(struct pt_regs *regs) { struct kprobe *cur = kprobe_running(); struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); @@ -964,22 +964,7 @@ kprobe_exceptions_notify(struct notifier_block *self, unsigned long val, void *d if (args->regs && user_mode_vm(args->regs)) return ret; - switch (val) { - case DIE_INT3: - if (kprobe_handler(args->regs)) - ret = NOTIFY_STOP; - break; - case DIE_DEBUG: - if (post_kprobe_handler(args->regs)) { - /* - * Reset the BS bit in dr6 (pointed by args->err) to - * denote completion of processing - */ - (*(unsigned long *)ERR_PTR(args->err)) &= ~DR_STEP; - ret = NOTIFY_STOP; - } - break; - case DIE_GPF: + if (val == DIE_GPF) { /* * To be potentially processing a kprobe fault and to * trust the result from kprobe_running(), we have @@ -988,9 +973,6 @@ kprobe_exceptions_notify(struct notifier_block *self, unsigned long val, void *d if (!preemptible() && kprobe_running() && kprobe_fault_handler(args->regs, args->trapnr)) ret = NOTIFY_STOP; - break; - default: - break; } return ret; } diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 57409f6..e5d4a70 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -334,6 +334,11 @@ dotraplinkage void __kprobes notrace do_int3(struct pt_regs *regs, long error_co goto exit; #endif /* CONFIG_KGDB_LOW_LEVEL_TRAP */ +#ifdef CONFIG_KPROBES + if (kprobe_int3_handler(regs)) + return; +#endif + if (notify_die(DIE_INT3, "int3", regs, error_code, X86_TRAP_BP, SIGTRAP) == NOTIFY_STOP) goto exit; @@ -440,6 +445,11 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code) /* Store the virtualized DR6 value */ tsk->thread.debugreg6 = dr6; +#ifdef CONFIG_KPROBES + if (kprobe_debug_handler(regs)) + goto exit; +#endif + if (notify_die(DIE_DEBUG, "debug", regs, (long)&dr6, error_code, SIGTRAP) == NOTIFY_STOP) goto exit;