From b0598c10f1b7b7bd9bf35849883d6e2c87da18d3 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Mon, 8 Apr 2013 01:29:19 +0400 Subject: [PATCH] --- yaml --- r: 374982 b: refs/heads/master c: 3ae908c99e944a7a5c4f4b2d8c603a6bc57b728b h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/arch/xtensa/include/asm/ftrace.h | 34 +++++++++++++++++++++++++- trunk/arch/xtensa/kernel/stacktrace.c | 33 +++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 2 deletions(-) diff --git a/[refs] b/[refs] index 95c1c935e1f8..7ce44de5f1be 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 3e4196a5cc9cff50900f3dc8acc3d41e5963fd50 +refs/heads/master: 3ae908c99e944a7a5c4f4b2d8c603a6bc57b728b diff --git a/trunk/arch/xtensa/include/asm/ftrace.h b/trunk/arch/xtensa/include/asm/ftrace.h index 40a8c178f10d..36dc7a684397 100644 --- a/trunk/arch/xtensa/include/asm/ftrace.h +++ b/trunk/arch/xtensa/include/asm/ftrace.h @@ -1 +1,33 @@ -/* empty */ +/* + * arch/xtensa/include/asm/ftrace.h + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2013 Tensilica Inc. + */ +#ifndef _XTENSA_FTRACE_H +#define _XTENSA_FTRACE_H + +#include + +#define HAVE_ARCH_CALLER_ADDR +#define CALLER_ADDR0 ({ unsigned long a0, a1; \ + __asm__ __volatile__ ( \ + "mov %0, a0\n" \ + "mov %1, a1\n" \ + : "=r"(a0), "=r"(a1) : : ); \ + MAKE_PC_FROM_RA(a0, a1); }) +#ifdef CONFIG_FRAME_POINTER +extern unsigned long return_address(unsigned level); +#define CALLER_ADDR1 return_address(1) +#define CALLER_ADDR2 return_address(2) +#define CALLER_ADDR3 return_address(3) +#else +#define CALLER_ADDR1 (0) +#define CALLER_ADDR2 (0) +#define CALLER_ADDR3 (0) +#endif + +#endif /* _XTENSA_FTRACE_H */ diff --git a/trunk/arch/xtensa/kernel/stacktrace.c b/trunk/arch/xtensa/kernel/stacktrace.c index e3aff9575183..7d2c317bd98b 100644 --- a/trunk/arch/xtensa/kernel/stacktrace.c +++ b/trunk/arch/xtensa/kernel/stacktrace.c @@ -85,3 +85,36 @@ void save_stack_trace(struct stack_trace *trace) EXPORT_SYMBOL_GPL(save_stack_trace); #endif + +#ifdef CONFIG_FRAME_POINTER + +struct return_addr_data { + unsigned long addr; + unsigned skip; +}; + +static int return_address_cb(struct stackframe *frame, void *data) +{ + struct return_addr_data *r = data; + + if (r->skip) { + --r->skip; + return 0; + } + if (!kernel_text_address(frame->pc)) + return 0; + r->addr = frame->pc; + return 1; +} + +unsigned long return_address(unsigned level) +{ + struct return_addr_data r = { + .skip = level + 1, + }; + walk_stackframe(stack_pointer(NULL), return_address_cb, &r); + return r.addr; +} +EXPORT_SYMBOL(return_address); + +#endif