From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754283AbdDNJeV (ORCPT ); Fri, 14 Apr 2017 05:34:21 -0400 Received: from terminus.zytor.com ([65.50.211.136]:50945 "EHLO terminus.zytor.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753877AbdDNJeD (ORCPT ); Fri, 14 Apr 2017 05:34:03 -0400 Date: Fri, 14 Apr 2017 02:26:14 -0700 From: tip-bot for Josh Poimboeuf Message-ID: Cc: bp@alien8.de, tglx@linutronix.de, linux-kernel@vger.kernel.org, daniel@iogearbox.net, torvalds@linux-foundation.org, davej@codemonkey.org.uk, brgerst@gmail.com, mingo@kernel.org, jpoimboe@redhat.com, peterz@infradead.org, luto@kernel.org, hpa@zytor.com, dvlasenk@redhat.com Reply-To: jpoimboe@redhat.com, mingo@kernel.org, linux-kernel@vger.kernel.org, torvalds@linux-foundation.org, davej@codemonkey.org.uk, daniel@iogearbox.net, brgerst@gmail.com, bp@alien8.de, tglx@linutronix.de, dvlasenk@redhat.com, hpa@zytor.com, peterz@infradead.org, luto@kernel.org In-Reply-To: References: To: linux-tip-commits@vger.kernel.org Subject: [tip:x86/asm] x86/unwind: Read stack return address in update_stack_state() Git-Commit-ID: 6bcdf9d51b9892dd5c6892d50cf5e9628efb8062 X-Mailer: tip-git-log-daemon Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Commit-ID: 6bcdf9d51b9892dd5c6892d50cf5e9628efb8062 Gitweb: http://git.kernel.org/tip/6bcdf9d51b9892dd5c6892d50cf5e9628efb8062 Author: Josh Poimboeuf AuthorDate: Wed, 12 Apr 2017 13:47:11 -0500 Committer: Ingo Molnar CommitDate: Fri, 14 Apr 2017 10:19:59 +0200 x86/unwind: Read stack return address in update_stack_state() Instead of reading the return address when unwind_get_return_address() is called, read it from update_stack_state() and store it in the unwind state. This enables the next patch to check the return address from unwind_next_frame() so it can detect an entry code frame. Signed-off-by: Josh Poimboeuf Acked-by: Thomas Gleixner Cc: Andy Lutomirski Cc: Borislav Petkov Cc: Brian Gerst Cc: Daniel Borkmann Cc: Dave Jones Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/af0c5e4560c49c0343dca486ea26c4fa92bc4e35.1492020577.git.jpoimboe@redhat.com Signed-off-by: Ingo Molnar --- arch/x86/include/asm/unwind.h | 1 + arch/x86/kernel/unwind_frame.c | 25 +++++++++++++------------ 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/arch/x86/include/asm/unwind.h b/arch/x86/include/asm/unwind.h index 6fa75b1..5663425 100644 --- a/arch/x86/include/asm/unwind.h +++ b/arch/x86/include/asm/unwind.h @@ -14,6 +14,7 @@ struct unwind_state { #ifdef CONFIG_FRAME_POINTER unsigned long *bp, *orig_sp; struct pt_regs *regs; + unsigned long ip; #else unsigned long *sp; #endif diff --git a/arch/x86/kernel/unwind_frame.c b/arch/x86/kernel/unwind_frame.c index 9098ef1..c67a059 100644 --- a/arch/x86/kernel/unwind_frame.c +++ b/arch/x86/kernel/unwind_frame.c @@ -56,20 +56,10 @@ static void unwind_dump(struct unwind_state *state, unsigned long *sp) unsigned long unwind_get_return_address(struct unwind_state *state) { - unsigned long addr; - unsigned long *addr_p = unwind_get_return_address_ptr(state); - if (unwind_done(state)) return 0; - if (state->regs && user_mode(state->regs)) - return 0; - - addr = READ_ONCE_TASK_STACK(state->task, *addr_p); - addr = ftrace_graph_ret_addr(state->task, &state->graph_idx, addr, - addr_p); - - return __kernel_text_address(addr) ? addr : 0; + return __kernel_text_address(state->ip) ? state->ip : 0; } EXPORT_SYMBOL_GPL(unwind_get_return_address); @@ -141,7 +131,7 @@ static bool update_stack_state(struct unwind_state *state, struct stack_info *info = &state->stack_info; enum stack_type prev_type = info->type; struct pt_regs *regs; - unsigned long *frame, *prev_frame_end; + unsigned long *frame, *prev_frame_end, *addr_p, addr; size_t len; if (state->regs) @@ -185,6 +175,16 @@ static bool update_stack_state(struct unwind_state *state, state->regs = NULL; } + /* Save the return address: */ + if (state->regs && user_mode(state->regs)) + state->ip = 0; + else { + addr_p = unwind_get_return_address_ptr(state); + addr = READ_ONCE_TASK_STACK(state->task, *addr_p); + state->ip = ftrace_graph_ret_addr(state->task, &state->graph_idx, + addr, addr_p); + } + /* Save the original stack pointer for unwind_dump(): */ if (!state->orig_sp || info->type != prev_type) state->orig_sp = frame; @@ -228,6 +228,7 @@ bool unwind_next_frame(struct unwind_state *state) */ state->regs = regs; state->bp = NULL; + state->ip = 0; return true; }