Skip to content

Commit

Permalink
arm64: ftrace: Add CALLER_ADDRx macros
Browse files Browse the repository at this point in the history
CALLER_ADDRx returns caller's address at specified level in call stacks.
They are used for several tracers like irqsoff and preemptoff.
Strange to say, however, they are refered even without FTRACE.

Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
Signed-off-by: Will Deacon <will.deacon@arm.com>
  • Loading branch information
AKASHI Takahiro authored and Will Deacon committed May 29, 2014
1 parent bd7d38d commit 3711784
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 2 deletions.
5 changes: 4 additions & 1 deletion arch/arm64/include/asm/ftrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#ifndef __ASSEMBLY__
extern void _mcount(unsigned long);
extern void *return_address(unsigned int);

struct dyn_arch_ftrace {
/* No extra data needed for arm64 */
Expand All @@ -33,6 +34,8 @@ static inline unsigned long ftrace_call_adjust(unsigned long addr)
*/
return addr;
}
#endif /* __ASSEMBLY__ */

#define ftrace_return_address(n) return_address(n)
#endif /* ifndef __ASSEMBLY__ */

#endif /* __ASM_FTRACE_H */
3 changes: 2 additions & 1 deletion arch/arm64/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@ AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET)

CFLAGS_REMOVE_ftrace.o = -pg
CFLAGS_REMOVE_insn.o = -pg
CFLAGS_REMOVE_return_address.o = -pg

# Object file lists.
arm64-obj-y := cputable.o debug-monitors.o entry.o irq.o fpsimd.o \
entry-fpsimd.o process.o ptrace.o setup.o signal.o \
sys.o stacktrace.o time.o traps.o io.o vdso.o \
hyp-stub.o psci.o cpu_ops.o insn.o
hyp-stub.o psci.o cpu_ops.o insn.o return_address.o

arm64-obj-$(CONFIG_COMPAT) += sys32.o kuser32.o signal32.o \
sys_compat.o
Expand Down
55 changes: 55 additions & 0 deletions arch/arm64/kernel/return_address.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* arch/arm64/kernel/return_address.c
*
* Copyright (C) 2013 Linaro Limited
* Author: AKASHI Takahiro <takahiro.akashi@linaro.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/

#include <linux/export.h>
#include <linux/ftrace.h>

#include <asm/stacktrace.h>

struct return_address_data {
unsigned int level;
void *addr;
};

static int save_return_addr(struct stackframe *frame, void *d)
{
struct return_address_data *data = d;

if (!data->level) {
data->addr = (void *)frame->pc;
return 1;
} else {
--data->level;
return 0;
}
}

void *return_address(unsigned int level)
{
struct return_address_data data;
struct stackframe frame;
register unsigned long current_sp asm ("sp");

data.level = level + 2;
data.addr = NULL;

frame.fp = (unsigned long)__builtin_frame_address(0);
frame.sp = current_sp;
frame.pc = (unsigned long)return_address; /* dummy */

walk_stackframe(&frame, save_return_addr, &data);

if (!data.level)
return data.addr;
else
return NULL;
}
EXPORT_SYMBOL_GPL(return_address);

0 comments on commit 3711784

Please sign in to comment.