Commit d19ad077 authored by Steven Rostedt (VMware)'s avatar Steven Rostedt (VMware)
Browse files

ftrace: Have the callbacks receive a struct ftrace_regs instead of pt_regs



In preparation to have arguments of a function passed to callbacks attached
to functions as default, change the default callback prototype to receive a
struct ftrace_regs as the forth parameter instead of a pt_regs.

For callbacks that set the FL_SAVE_REGS flag in their ftrace_ops flags, they
will now need to get the pt_regs via a ftrace_get_regs() helper call. If
this is called by a callback that their ftrace_ops did not have a
FL_SAVE_REGS flag set, it that helper function will return NULL.

This will allow the ftrace_regs to hold enough just to get the parameters
and stack pointer, but without the worry that callbacks may have a pt_regs
that is not completely filled.

Acked-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: default avatarMasami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: default avatarSteven Rostedt (VMware) <rostedt@goodmis.org>
parent 58954b3b
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -11,17 +11,19 @@ int arch_check_ftrace_location(struct kprobe *p)

/* Ftrace callback handler for kprobes -- called under preepmt disabed */
void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
			   struct ftrace_ops *ops, struct pt_regs *regs)
			   struct ftrace_ops *ops, struct ftrace_regs *fregs)
{
	int bit;
	bool lr_saver = false;
	struct kprobe *p;
	struct kprobe_ctlblk *kcb;
	struct pt_regs *regs;

	bit = ftrace_test_recursion_trylock(ip, parent_ip);
	if (bit < 0)
		return;

	regs = ftrace_get_regs(fregs);
	preempt_disable_notrace();
	p = get_kprobe((kprobe_opcode_t *)ip);
	if (!p) {
+2 −2
Original line number Diff line number Diff line
@@ -10,7 +10,7 @@ extern void (*ftrace_trace_function)(unsigned long, unsigned long,
extern void ftrace_graph_caller(void);

noinline void __naked ftrace_stub(unsigned long ip, unsigned long parent_ip,
				  struct ftrace_ops *op, struct pt_regs *regs)
				  struct ftrace_ops *op, struct ftrace_regs *fregs)
{
	__asm__ ("");  /* avoid to optimize as pure function */
}
@@ -38,7 +38,7 @@ EXPORT_SYMBOL(_mcount);
#else /* CONFIG_DYNAMIC_FTRACE */

noinline void __naked ftrace_stub(unsigned long ip, unsigned long parent_ip,
				  struct ftrace_ops *op, struct pt_regs *regs)
				  struct ftrace_ops *op, struct ftrace_regs *fregs)
{
	__asm__ ("");  /* avoid to optimize as pure function */
}
+5 −3
Original line number Diff line number Diff line
@@ -51,7 +51,7 @@ static void __hot prepare_ftrace_return(unsigned long *parent,
void notrace __hot ftrace_function_trampoline(unsigned long parent,
				unsigned long self_addr,
				unsigned long org_sp_gr3,
				struct pt_regs *regs)
				struct ftrace_regs *fregs)
{
#ifndef CONFIG_DYNAMIC_FTRACE
	extern ftrace_func_t ftrace_trace_function;
@@ -61,7 +61,7 @@ void notrace __hot ftrace_function_trampoline(unsigned long parent,
	if (function_trace_op->flags & FTRACE_OPS_FL_ENABLED &&
	    ftrace_trace_function != ftrace_stub)
		ftrace_trace_function(self_addr, parent,
				function_trace_op, regs);
				function_trace_op, fregs);

#ifdef CONFIG_FUNCTION_GRAPH_TRACER
	if (dereference_function_descriptor(ftrace_graph_return) !=
@@ -204,9 +204,10 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec,

#ifdef CONFIG_KPROBES_ON_FTRACE
void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
			   struct ftrace_ops *ops, struct pt_regs *regs)
			   struct ftrace_ops *ops, struct ftrace_regs *fregs)
{
	struct kprobe_ctlblk *kcb;
	struct pt_regs *regs;
	struct kprobe *p;
	int bit;

@@ -214,6 +215,7 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
	if (bit < 0)
		return;

	regs = ftrace_get_regs(fregs);
	preempt_disable_notrace();
	p = get_kprobe((kprobe_opcode_t *)ip);
	if (unlikely(!p) || kprobe_disabled(p))
+3 −1
Original line number Diff line number Diff line
@@ -14,16 +14,18 @@

/* Ftrace callback handler for kprobes */
void kprobe_ftrace_handler(unsigned long nip, unsigned long parent_nip,
			   struct ftrace_ops *ops, struct pt_regs *regs)
			   struct ftrace_ops *ops, struct ftrace_regs *fregs)
{
	struct kprobe *p;
	struct kprobe_ctlblk *kcb;
	struct pt_regs *regs;
	int bit;

	bit = ftrace_test_recursion_trylock(nip, parent_nip);
	if (bit < 0)
		return;

	regs = ftrace_get_regs(fregs);
	preempt_disable_notrace();
	p = get_kprobe((kprobe_opcode_t *)nip);
	if (unlikely(!p) || kprobe_disabled(p))
+3 −1
Original line number Diff line number Diff line
@@ -198,9 +198,10 @@ int ftrace_disable_ftrace_graph_caller(void)

#ifdef CONFIG_KPROBES_ON_FTRACE
void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
		struct ftrace_ops *ops, struct pt_regs *regs)
		struct ftrace_ops *ops, struct ftrace_regs *fregs)
{
	struct kprobe_ctlblk *kcb;
	struct pt_regs *regs;
	struct kprobe *p;
	int bit;

@@ -208,6 +209,7 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
	if (bit < 0)
		return;

	regs = ftrace_get_regs(fregs);
	preempt_disable_notrace();
	p = get_kprobe((kprobe_opcode_t *)ip);
	if (unlikely(!p) || kprobe_disabled(p))
Loading