Linux Audio

Check our new training course

Loading...
v4.6
 
 1/*
 2 * Code for tracing calls in Linux kernel.
 3 * Copyright (C) 2009-2016 Helge Deller <deller@gmx.de>
 4 *
 5 * based on code for x86 which is:
 6 * Copyright (C) 2007-2008 Steven Rostedt <srostedt@redhat.com>
 7 *
 8 * future possible enhancements:
 9 * 	- add CONFIG_DYNAMIC_FTRACE
10 *	- add CONFIG_STACK_TRACER
11 */
12
13#include <linux/init.h>
14#include <linux/ftrace.h>
15
16#include <asm/assembly.h>
17#include <asm/sections.h>
18#include <asm/ftrace.h>
19
20
 
 
21#ifdef CONFIG_FUNCTION_GRAPH_TRACER
22/*
23 * Hook the return address and push it in the stack of return addrs
24 * in current thread info.
25 */
26static void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
 
27{
28	unsigned long old;
29	struct ftrace_graph_ent trace;
30	extern int parisc_return_to_handler;
31
32	if (unlikely(ftrace_graph_is_dead()))
33		return;
34
35	if (unlikely(atomic_read(&current->tracing_graph_pause)))
36		return;
37
38	old = *parent;
39
40	trace.func = self_addr;
41	trace.depth = current->curr_ret_stack + 1;
42
43	/* Only trace if the calling function expects to */
44	if (!ftrace_graph_entry(&trace))
45		return;
46
47        if (ftrace_push_return_trace(old, self_addr, &trace.depth,
48			0 ) == -EBUSY)
49                return;
50
51	/* activate parisc_return_to_handler() as return point */
52	*parent = (unsigned long) &parisc_return_to_handler;
53}
54#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
55
56void notrace ftrace_function_trampoline(unsigned long parent,
57				unsigned long self_addr,
58				unsigned long org_sp_gr3)
59{
60	extern ftrace_func_t ftrace_trace_function;  /* depends on CONFIG_DYNAMIC_FTRACE */
61	extern int ftrace_graph_entry_stub(struct ftrace_graph_ent *trace);
62
63	if (ftrace_trace_function != ftrace_stub) {
64		/* struct ftrace_ops *op, struct pt_regs *regs); */
65		ftrace_trace_function(parent, self_addr, NULL, NULL);
66		return;
67	}
68
69#ifdef CONFIG_FUNCTION_GRAPH_TRACER
70	if (ftrace_graph_return != (trace_func_graph_ret_t) ftrace_stub ||
71		ftrace_graph_entry != ftrace_graph_entry_stub) {
72		unsigned long *parent_rp;
73
74		/* calculate pointer to %rp in stack */
75		parent_rp = (unsigned long *) (org_sp_gr3 - RP_OFFSET);
76		/* sanity check: parent_rp should hold parent */
77		if (*parent_rp != parent)
78			return;
79
80		prepare_ftrace_return(parent_rp, self_addr);
81		return;
82	}
83#endif
84}
85
v4.17
 1// SPDX-License-Identifier: GPL-2.0
 2/*
 3 * Code for tracing calls in Linux kernel.
 4 * Copyright (C) 2009-2016 Helge Deller <deller@gmx.de>
 5 *
 6 * based on code for x86 which is:
 7 * Copyright (C) 2007-2008 Steven Rostedt <srostedt@redhat.com>
 8 *
 9 * future possible enhancements:
10 * 	- add CONFIG_DYNAMIC_FTRACE
11 *	- add CONFIG_STACK_TRACER
12 */
13
14#include <linux/init.h>
15#include <linux/ftrace.h>
16
17#include <asm/assembly.h>
18#include <asm/sections.h>
19#include <asm/ftrace.h>
20
21
22#define __hot __attribute__ ((__section__ (".text.hot")))
23
24#ifdef CONFIG_FUNCTION_GRAPH_TRACER
25/*
26 * Hook the return address and push it in the stack of return addrs
27 * in current thread info.
28 */
29static void __hot prepare_ftrace_return(unsigned long *parent,
30					unsigned long self_addr)
31{
32	unsigned long old;
33	struct ftrace_graph_ent trace;
34	extern int parisc_return_to_handler;
35
36	if (unlikely(ftrace_graph_is_dead()))
37		return;
38
39	if (unlikely(atomic_read(&current->tracing_graph_pause)))
40		return;
41
42	old = *parent;
43
44	trace.func = self_addr;
45	trace.depth = current->curr_ret_stack + 1;
46
47	/* Only trace if the calling function expects to */
48	if (!ftrace_graph_entry(&trace))
49		return;
50
51        if (ftrace_push_return_trace(old, self_addr, &trace.depth,
52				     0, NULL) == -EBUSY)
53                return;
54
55	/* activate parisc_return_to_handler() as return point */
56	*parent = (unsigned long) &parisc_return_to_handler;
57}
58#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
59
60void notrace __hot ftrace_function_trampoline(unsigned long parent,
61				unsigned long self_addr,
62				unsigned long org_sp_gr3)
63{
64	extern ftrace_func_t ftrace_trace_function;  /* depends on CONFIG_DYNAMIC_FTRACE */
65	extern int ftrace_graph_entry_stub(struct ftrace_graph_ent *trace);
66
67	if (ftrace_trace_function != ftrace_stub) {
68		/* struct ftrace_ops *op, struct pt_regs *regs); */
69		ftrace_trace_function(parent, self_addr, NULL, NULL);
70		return;
71	}
72
73#ifdef CONFIG_FUNCTION_GRAPH_TRACER
74	if (ftrace_graph_return != (trace_func_graph_ret_t) ftrace_stub ||
75		ftrace_graph_entry != ftrace_graph_entry_stub) {
76		unsigned long *parent_rp;
77
78		/* calculate pointer to %rp in stack */
79		parent_rp = (unsigned long *) (org_sp_gr3 - RP_OFFSET);
80		/* sanity check: parent_rp should hold parent */
81		if (*parent_rp != parent)
82			return;
83
84		prepare_ftrace_return(parent_rp, self_addr);
85		return;
86	}
87#endif
88}
89