Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932224AbbFSOKG (ORCPT ); Fri, 19 Jun 2015 10:10:06 -0400 Received: from verein.lst.de ([213.95.11.211]:60979 "EHLO newverein.lst.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754549AbbFSOJ5 (ORCPT ); Fri, 19 Jun 2015 10:09:57 -0400 Date: Fri, 19 Jun 2015 16:09:55 +0200 From: Torsten Duwe To: Steven Rostedt , Michael Ellerman Cc: Jiri Kosina , linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 4/4] ppc64 ftrace_with_regs recursion protection Message-ID: <20150619140955.GD8824@lst.de> References: <20150619140403.GA8681@lst.de> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20150619140403.GA8681@lst.de> User-Agent: Mutt/1.5.17 (2007-11-01) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2564 Lines: 72 This is an *emergency* parachute to avoid an endless recursion and consecutively a kernel stack overflow, should any function within some ftrace framework cause an access fault, which calls _mcount / ftrace_caller in return and so on. It might also call an ftrace'd function directly. As Michael Ellerman pointed out, it is a tedious and error-prone task to maintain a complete list of those functions that _might_ get called from *_access_fault or any dynamic tracer function. So we'll concentrate on the most frequent cases to enhance performance later, while for now sticking with this fill-in. It will later serve as a backup protection. * arch/powerpc/kernel/entry_64.S: - test-and-set TRACE_FTRACE_BIT in task_struct's trace_recursion, do not call the actual tracer function if set, clear flag on return. Signed-off-by: Torsten Duwe --- arch/powerpc/kernel/asm-offsets.c | 1 + arch/powerpc/kernel/entry_64.S | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 4717859..ae10752 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -72,6 +72,7 @@ int main(void) DEFINE(THREAD, offsetof(struct task_struct, thread)); DEFINE(MM, offsetof(struct task_struct, mm)); DEFINE(MMCONTEXTID, offsetof(struct mm_struct, context.id)); + DEFINE(TASK_TRACEREC, offsetof(struct task_struct, trace_recursion)); #ifdef CONFIG_PPC64 DEFINE(AUDITCONTEXT, offsetof(struct task_struct, audit_context)); DEFINE(SIGSEGV, SIGSEGV); diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index a4132ef..4768104 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -1202,7 +1202,13 @@ _GLOBAL(ftrace_caller) SAVE_8GPRS(16,r1) SAVE_8GPRS(24,r1) - + ld r3, PACACURRENT(r13) + ld r4, TASK_TRACEREC(r3) + andi. r5, r4, 0x0010 // ( 1 << TRACE_FTRACE_BIT ) + ori r4, r4, 0x0010 + std r4, TASK_TRACEREC(r3) + bne- 3f // ftrace in progress - avoid recursion! + LOAD_REG_IMMEDIATE(r3,function_trace_op) ld r5,0(r3) @@ -1224,9 +1230,14 @@ ftrace_call: bl ftrace_stub nop + ld r3, PACACURRENT(r13) + ld r4, TASK_TRACEREC(r3) + andi. r4, r4, 0xffef // ~( 1 << TRACE_FTRACE_BIT ) + std r4, TASK_TRACEREC(r3) + ld r3, _NIP(r1) mtlr r3 - +3: REST_8GPRS(0,r1) REST_8GPRS(8,r1) REST_8GPRS(16,r1) -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in Please read the FAQ at http://www.tux.org/lkml/