Skip to content

Commit 3711784

Browse files
AKASHI Takahirowildea01
AKASHI Takahiro
authored andcommitted
arm64: ftrace: Add CALLER_ADDRx macros
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 <[email protected]> Signed-off-by: Will Deacon <[email protected]>
1 parent bd7d38d commit 3711784

File tree

3 files changed

+61
-2
lines changed

3 files changed

+61
-2
lines changed

arch/arm64/include/asm/ftrace.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
#ifndef __ASSEMBLY__
2020
extern void _mcount(unsigned long);
21+
extern void *return_address(unsigned int);
2122

2223
struct dyn_arch_ftrace {
2324
/* No extra data needed for arm64 */
@@ -33,6 +34,8 @@ static inline unsigned long ftrace_call_adjust(unsigned long addr)
3334
*/
3435
return addr;
3536
}
36-
#endif /* __ASSEMBLY__ */
37+
38+
#define ftrace_return_address(n) return_address(n)
39+
#endif /* ifndef __ASSEMBLY__ */
3740

3841
#endif /* __ASM_FTRACE_H */

arch/arm64/kernel/Makefile

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@ AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET)
77

88
CFLAGS_REMOVE_ftrace.o = -pg
99
CFLAGS_REMOVE_insn.o = -pg
10+
CFLAGS_REMOVE_return_address.o = -pg
1011

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

1718
arm64-obj-$(CONFIG_COMPAT) += sys32.o kuser32.o signal32.o \
1819
sys_compat.o

arch/arm64/kernel/return_address.c

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* arch/arm64/kernel/return_address.c
3+
*
4+
* Copyright (C) 2013 Linaro Limited
5+
* Author: AKASHI Takahiro <[email protected]>
6+
*
7+
* This program is free software; you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License version 2 as
9+
* published by the Free Software Foundation.
10+
*/
11+
12+
#include <linux/export.h>
13+
#include <linux/ftrace.h>
14+
15+
#include <asm/stacktrace.h>
16+
17+
struct return_address_data {
18+
unsigned int level;
19+
void *addr;
20+
};
21+
22+
static int save_return_addr(struct stackframe *frame, void *d)
23+
{
24+
struct return_address_data *data = d;
25+
26+
if (!data->level) {
27+
data->addr = (void *)frame->pc;
28+
return 1;
29+
} else {
30+
--data->level;
31+
return 0;
32+
}
33+
}
34+
35+
void *return_address(unsigned int level)
36+
{
37+
struct return_address_data data;
38+
struct stackframe frame;
39+
register unsigned long current_sp asm ("sp");
40+
41+
data.level = level + 2;
42+
data.addr = NULL;
43+
44+
frame.fp = (unsigned long)__builtin_frame_address(0);
45+
frame.sp = current_sp;
46+
frame.pc = (unsigned long)return_address; /* dummy */
47+
48+
walk_stackframe(&frame, save_return_addr, &data);
49+
50+
if (!data.level)
51+
return data.addr;
52+
else
53+
return NULL;
54+
}
55+
EXPORT_SYMBOL_GPL(return_address);

0 commit comments

Comments
 (0)