Commit f89b30b8 authored by Will Deacon's avatar Will Deacon
Browse files

Merge tag 'trace-direct-v6.3-rc3' of...

Merge tag 'trace-direct-v6.3-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace into for-next/ftrace

Pull in ftrace trampoline updates from Steve so that we can implement
support for direct calls for arm64 on top:

tracing: Direct trampoline updates

Updates to the direct trampoline to allow ARM64 to have direct
trampolines.
parents e8d018dd fee86a4e
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -32,6 +32,11 @@ ENTRY(ftrace_stub)
	BR_EX	%r14
ENDPROC(ftrace_stub)

SYM_CODE_START(ftrace_stub_direct_tramp)
	lgr	%r1, %r0
	BR_EX	%r1
SYM_CODE_END(ftrace_stub_direct_tramp)

	.macro	ftrace_regs_entry, allregs=0
	stg	%r14,(__SF_GPRS+8*8)(%r15)	# save traced function caller

+5 −0
Original line number Diff line number Diff line
@@ -163,6 +163,11 @@ SYM_INNER_LABEL(ftrace_regs_call, SYM_L_GLOBAL)
	jmp	.Lftrace_ret
SYM_CODE_END(ftrace_regs_caller)

SYM_FUNC_START(ftrace_stub_direct_tramp)
	CALL_DEPTH_ACCOUNT
	RET
SYM_FUNC_END(ftrace_stub_direct_tramp)

#ifdef CONFIG_FUNCTION_GRAPH_TRACER
SYM_CODE_START(ftrace_graph_caller)
	pushl	%eax
+4 −0
Original line number Diff line number Diff line
@@ -309,6 +309,10 @@ SYM_INNER_LABEL(ftrace_regs_caller_end, SYM_L_GLOBAL)
SYM_FUNC_END(ftrace_regs_caller)
STACK_FRAME_NON_STANDARD_FP(ftrace_regs_caller)

SYM_FUNC_START(ftrace_stub_direct_tramp)
	CALL_DEPTH_ACCOUNT
	RET
SYM_FUNC_END(ftrace_stub_direct_tramp)

#else /* ! CONFIG_DYNAMIC_FTRACE */

+21 −40
Original line number Diff line number Diff line
@@ -241,6 +241,12 @@ enum {
	FTRACE_OPS_FL_DIRECT			= BIT(17),
};

#ifndef CONFIG_DYNAMIC_FTRACE_WITH_ARGS
#define FTRACE_OPS_FL_SAVE_ARGS                        FTRACE_OPS_FL_SAVE_REGS
#else
#define FTRACE_OPS_FL_SAVE_ARGS                        0
#endif

/*
 * FTRACE_OPS_CMD_* commands allow the ftrace core logic to request changes
 * to a ftrace_ops. Note, the requests may fail.
@@ -321,6 +327,9 @@ struct ftrace_ops {
	unsigned long			trampoline_size;
	struct list_head		list;
	ftrace_ops_func_t		ops_func;
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
	unsigned long			direct_call;
#endif
#endif
};

@@ -397,64 +406,36 @@ struct ftrace_func_entry {

#ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
extern int ftrace_direct_func_count;
int register_ftrace_direct(unsigned long ip, unsigned long addr);
int unregister_ftrace_direct(unsigned long ip, unsigned long addr);
int modify_ftrace_direct(unsigned long ip, unsigned long old_addr, unsigned long new_addr);
struct ftrace_direct_func *ftrace_find_direct_func(unsigned long addr);
int ftrace_modify_direct_caller(struct ftrace_func_entry *entry,
				struct dyn_ftrace *rec,
				unsigned long old_addr,
				unsigned long new_addr);
unsigned long ftrace_find_rec_direct(unsigned long ip);
int register_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr);
int unregister_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr);
int modify_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr);
int modify_ftrace_direct_multi_nolock(struct ftrace_ops *ops, unsigned long addr);
int register_ftrace_direct(struct ftrace_ops *ops, unsigned long addr);
int unregister_ftrace_direct(struct ftrace_ops *ops, unsigned long addr,
			     bool free_filters);
int modify_ftrace_direct(struct ftrace_ops *ops, unsigned long addr);
int modify_ftrace_direct_nolock(struct ftrace_ops *ops, unsigned long addr);

void ftrace_stub_direct_tramp(void);

#else
struct ftrace_ops;
# define ftrace_direct_func_count 0
static inline int register_ftrace_direct(unsigned long ip, unsigned long addr)
{
	return -ENOTSUPP;
}
static inline int unregister_ftrace_direct(unsigned long ip, unsigned long addr)
{
	return -ENOTSUPP;
}
static inline int modify_ftrace_direct(unsigned long ip,
				       unsigned long old_addr, unsigned long new_addr)
{
	return -ENOTSUPP;
}
static inline struct ftrace_direct_func *ftrace_find_direct_func(unsigned long addr)
{
	return NULL;
}
static inline int ftrace_modify_direct_caller(struct ftrace_func_entry *entry,
					      struct dyn_ftrace *rec,
					      unsigned long old_addr,
					      unsigned long new_addr)
{
	return -ENODEV;
}
static inline unsigned long ftrace_find_rec_direct(unsigned long ip)
{
	return 0;
}
static inline int register_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr)
static inline int register_ftrace_direct(struct ftrace_ops *ops, unsigned long addr)
{
	return -ENODEV;
}
static inline int unregister_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr)
static inline int unregister_ftrace_direct(struct ftrace_ops *ops, unsigned long addr,
					   bool free_filters)
{
	return -ENODEV;
}
static inline int modify_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr)
static inline int modify_ftrace_direct(struct ftrace_ops *ops, unsigned long addr)
{
	return -ENODEV;
}
static inline int modify_ftrace_direct_multi_nolock(struct ftrace_ops *ops, unsigned long addr)
static inline int modify_ftrace_direct_nolock(struct ftrace_ops *ops, unsigned long addr)
{
	return -ENODEV;
}
+6 −6
Original line number Diff line number Diff line
@@ -45,8 +45,8 @@ static int bpf_tramp_ftrace_ops_func(struct ftrace_ops *ops, enum ftrace_ops_cmd
		lockdep_assert_held_once(&tr->mutex);

		/* Instead of updating the trampoline here, we propagate
		 * -EAGAIN to register_ftrace_direct_multi(). Then we can
		 * retry register_ftrace_direct_multi() after updating the
		 * -EAGAIN to register_ftrace_direct(). Then we can
		 * retry register_ftrace_direct() after updating the
		 * trampoline.
		 */
		if ((tr->flags & BPF_TRAMP_F_CALL_ORIG) &&
@@ -198,7 +198,7 @@ static int unregister_fentry(struct bpf_trampoline *tr, void *old_addr)
	int ret;

	if (tr->func.ftrace_managed)
		ret = unregister_ftrace_direct_multi(tr->fops, (long)old_addr);
		ret = unregister_ftrace_direct(tr->fops, (long)old_addr, false);
	else
		ret = bpf_arch_text_poke(ip, BPF_MOD_CALL, old_addr, NULL);

@@ -215,9 +215,9 @@ static int modify_fentry(struct bpf_trampoline *tr, void *old_addr, void *new_ad

	if (tr->func.ftrace_managed) {
		if (lock_direct_mutex)
			ret = modify_ftrace_direct_multi(tr->fops, (long)new_addr);
			ret = modify_ftrace_direct(tr->fops, (long)new_addr);
		else
			ret = modify_ftrace_direct_multi_nolock(tr->fops, (long)new_addr);
			ret = modify_ftrace_direct_nolock(tr->fops, (long)new_addr);
	} else {
		ret = bpf_arch_text_poke(ip, BPF_MOD_CALL, old_addr, new_addr);
	}
@@ -243,7 +243,7 @@ static int register_fentry(struct bpf_trampoline *tr, void *new_addr)

	if (tr->func.ftrace_managed) {
		ftrace_set_filter_ip(tr->fops, (unsigned long)ip, 0, 1);
		ret = register_ftrace_direct_multi(tr->fops, (long)new_addr);
		ret = register_ftrace_direct(tr->fops, (long)new_addr);
	} else {
		ret = bpf_arch_text_poke(ip, BPF_MOD_CALL, NULL, new_addr);
	}
Loading