Skip to content

Commit

Permalink
ftrace: Fix -Wcast-function-type warnings on powerpc64
Browse files Browse the repository at this point in the history
In order to make sure new function cast mismatches are not introduced
in the kernel (to avoid tripping CFI checking), the kernel should be
globally built with -Wcast-function-type.

So, fix the following -Wcast-function-type warnings on powerpc64
(ppc64_defconfig):

kernel/trace/ftrace.c: In function 'ftrace_ops_get_list_func':
kernel/trace/ftrace.c:128:31: warning: cast between incompatible function types from 'void (*)(long unsigned int,  long unsigned int)' to 'void (*)(long unsigned int,  long unsigned int,  struct ftrace_ops *, struct ftrace_regs *)' [-Wcast-function-type]
  128 | #define ftrace_ops_list_func ((ftrace_func_t)ftrace_ops_no_ops)
      |                               ^
kernel/trace/ftrace.c:174:10: note: in expansion of macro 'ftrace_ops_list_func'
  174 |   return ftrace_ops_list_func;
      |          ^~~~~~~~~~~~~~~~~~~~
kernel/trace/ftrace.c: In function 'update_ftrace_function':
kernel/trace/ftrace.c:128:31: warning: cast between incompatible function types from 'void (*)(long unsigned int,  long unsigned int)' to 'void (*)(long unsigned int,  long unsigned int,  struct ftrace_ops *, struct ftrace_regs *)' [-Wcast-function-type]
  128 | #define ftrace_ops_list_func ((ftrace_func_t)ftrace_ops_no_ops)
      |                               ^
kernel/trace/ftrace.c:207:10: note: in expansion of macro 'ftrace_ops_list_func'
  207 |   func = ftrace_ops_list_func;
      |          ^~~~~~~~~~~~~~~~~~~~
kernel/trace/ftrace.c:128:31: warning: cast between incompatible function types from 'void (*)(long unsigned int,  long unsigned int)' to 'void (*)(long unsigned int,  long unsigned int,  struct ftrace_ops *, struct ftrace_regs *)' [-Wcast-function-type]
  128 | #define ftrace_ops_list_func ((ftrace_func_t)ftrace_ops_no_ops)
      |                               ^
kernel/trace/ftrace.c:220:14: note: in expansion of macro 'ftrace_ops_list_func'
  220 |  if (func == ftrace_ops_list_func) {
      |              ^~~~~~~~~~~~~~~~~~~~
kernel/trace/ftrace.c: In function 'ftrace_modify_all_code':
kernel/trace/ftrace.c:128:31: warning: cast between incompatible function types from 'void (*)(long unsigned int,  long unsigned int)' to 'void (*)(long unsigned int,  long unsigned int,  struct ftrace_ops *, struct ftrace_regs *)' [-Wcast-function-type]
  128 | #define ftrace_ops_list_func ((ftrace_func_t)ftrace_ops_no_ops)
      |                               ^
kernel/trace/ftrace.c:2698:35: note: in expansion of macro 'ftrace_ops_list_func'
 2698 |   err = ftrace_update_ftrace_func(ftrace_ops_list_func);
      |                                   ^~~~~~~~~~~~~~~~~~~~
kernel/trace/ftrace.c:128:31: warning: cast between incompatible function types from 'void (*)(long unsigned int,  long unsigned int)' to 'void (*)(long unsigned int,  long unsigned int,  struct ftrace_ops *, struct ftrace_regs *)' [-Wcast-function-type]

  128 | #define ftrace_ops_list_func ((ftrace_func_t)ftrace_ops_no_ops)
      |                               ^
kernel/trace/ftrace.c:2708:41: note: in expansion of macro 'ftrace_ops_list_func'
 2708 |  if (update && ftrace_trace_function != ftrace_ops_list_func) {

Link: KSPP#20
Link: https://lore.kernel.org/lkml/20210930095300.73be1555@canb.auug.org.au/
Reported-by: Stephen Rothwell <sfr@canb.auug.org.au>
Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
  • Loading branch information
GustavoARSilva authored and intel-lab-lkp committed Oct 5, 2021
1 parent 4110083 commit 9c10c07
Show file tree
Hide file tree
Showing 7 changed files with 37 additions and 22 deletions.
7 changes: 7 additions & 0 deletions include/linux/ftrace.h
Expand Up @@ -114,8 +114,15 @@ static __always_inline struct pt_regs *ftrace_get_regs(struct ftrace_regs *fregs
return arch_ftrace_get_regs(fregs);
}

#if ARCH_SUPPORTS_FTRACE_OPS
typedef void (*ftrace_func_t)(unsigned long ip, unsigned long parent_ip,
struct ftrace_ops *op, struct ftrace_regs *fregs);
#else
typedef void (*ftrace_func_t)(unsigned long ip, unsigned long parent_ip);
#endif

typedef void (*ftrace_func_base_t)(void);
#define CAST_FTRACE_FUNC(f) ((ftrace_func_t)((ftrace_func_base_t)(f)))

ftrace_func_t ftrace_ops_get_func(struct ftrace_ops *ops);

Expand Down
2 changes: 1 addition & 1 deletion kernel/trace/fgraph.c
Expand Up @@ -333,7 +333,7 @@ unsigned long ftrace_graph_ret_addr(struct task_struct *task, int *idx,
#endif /* HAVE_FUNCTION_GRAPH_RET_ADDR_PTR */

static struct ftrace_ops graph_ops = {
.func = ftrace_stub,
.func = CAST_FTRACE_FUNC(ftrace_stub),
.flags = FTRACE_OPS_FL_INITIALIZED |
FTRACE_OPS_FL_PID |
FTRACE_OPS_FL_STUB,
Expand Down
34 changes: 21 additions & 13 deletions kernel/trace/ftrace.c
Expand Up @@ -79,7 +79,7 @@ enum {
};

struct ftrace_ops ftrace_list_end __read_mostly = {
.func = ftrace_stub,
.func = CAST_FTRACE_FUNC(ftrace_stub),
.flags = FTRACE_OPS_FL_STUB,
INIT_OPS_HASH(ftrace_list_end)
};
Expand Down Expand Up @@ -116,7 +116,7 @@ static int ftrace_disabled __read_mostly;
DEFINE_MUTEX(ftrace_lock);

struct ftrace_ops __rcu *ftrace_ops_list __read_mostly = &ftrace_list_end;
ftrace_func_t ftrace_trace_function __read_mostly = ftrace_stub;
ftrace_func_t ftrace_trace_function __read_mostly = CAST_FTRACE_FUNC(ftrace_stub);
struct ftrace_ops global_ops;

#if ARCH_SUPPORTS_FTRACE_OPS
Expand All @@ -142,6 +142,7 @@ static inline void ftrace_ops_init(struct ftrace_ops *ops)
static void ftrace_pid_func(unsigned long ip, unsigned long parent_ip,
struct ftrace_ops *op, struct ftrace_regs *fregs)
{
#if ARCH_SUPPORTS_FTRACE_OPS
struct trace_array *tr = op->private;
int pid;

Expand All @@ -155,6 +156,7 @@ static void ftrace_pid_func(unsigned long ip, unsigned long parent_ip,
}

op->saved_func(ip, parent_ip, op, fregs);
#endif
}

static void ftrace_sync_ipi(void *data)
Expand Down Expand Up @@ -190,7 +192,7 @@ static void update_ftrace_function(void)

/* If there's no ftrace_ops registered, just call the stub function */
if (set_function_trace_op == &ftrace_list_end) {
func = ftrace_stub;
func = CAST_FTRACE_FUNC(ftrace_stub);

/*
* If we are at the end of the list and this ops is
Expand Down Expand Up @@ -332,7 +334,7 @@ int __register_ftrace_function(struct ftrace_ops *ops)
ops->saved_func = ops->func;

if (ftrace_pids_enabled(ops))
ops->func = ftrace_pid_func;
ops->func = CAST_FTRACE_FUNC(ftrace_pid_func);

ftrace_update_trampoline(ops);

Expand Down Expand Up @@ -367,13 +369,13 @@ static void ftrace_update_pid_func(void)
struct ftrace_ops *op;

/* Only do something if we are tracing something */
if (ftrace_trace_function == ftrace_stub)
if (ftrace_trace_function == CAST_FTRACE_FUNC(ftrace_stub))
return;

do_for_each_ftrace_op(op, ftrace_ops_list) {
if (op->flags & FTRACE_OPS_FL_PID) {
op->func = ftrace_pids_enabled(op) ?
ftrace_pid_func : op->saved_func;
CAST_FTRACE_FUNC(ftrace_pid_func) : op->saved_func;
ftrace_update_trampoline(op);
}
} while_for_each_ftrace_op(op);
Expand Down Expand Up @@ -1036,7 +1038,7 @@ static const struct ftrace_hash empty_hash = {
#define EMPTY_HASH ((struct ftrace_hash *)&empty_hash)

struct ftrace_ops global_ops = {
.func = ftrace_stub,
.func = CAST_FTRACE_FUNC(ftrace_stub),
.local_hash.notrace_hash = EMPTY_HASH,
.local_hash.filter_hash = EMPTY_HASH,
INIT_OPS_HASH(global_ops)
Expand Down Expand Up @@ -4545,7 +4547,7 @@ register_ftrace_function_probe(char *glob, struct trace_array *tr,
return -ENOMEM;
}
probe->probe_ops = probe_ops;
probe->ops.func = function_trace_probe_call;
probe->ops.func = CAST_FTRACE_FUNC(function_trace_probe_call);
probe->tr = tr;
ftrace_ops_init(&probe->ops);
list_add(&probe->list, &tr->func_probes);
Expand Down Expand Up @@ -6956,7 +6958,7 @@ void ftrace_init_array_ops(struct trace_array *tr, ftrace_func_t func)
{
/* If we filter on pids, update to use the pid function */
if (tr->flags & TRACE_ARRAY_FL_GLOBAL) {
if (WARN_ON(tr->ops->func != ftrace_stub))
if (WARN_ON(tr->ops->func != CAST_FTRACE_FUNC(ftrace_stub)))
printk("ftrace ops had %pS for function\n",
tr->ops->func);
}
Expand All @@ -6966,7 +6968,7 @@ void ftrace_init_array_ops(struct trace_array *tr, ftrace_func_t func)

void ftrace_reset_array_ops(struct trace_array *tr)
{
tr->ops->func = ftrace_stub;
tr->ops->func = CAST_FTRACE_FUNC(ftrace_stub);
}

static nokprobe_inline void
Expand Down Expand Up @@ -7006,7 +7008,11 @@ __ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip,
pr_warn("op=%p %pS\n", op, op);
goto out;
}
#if ARCH_SUPPORTS_FTRACE_OPS
op->func(ip, parent_ip, op, fregs);
#else
op->func(ip, parent_ip);
#endif
}
} while_for_each_ftrace_op(op);
out:
Expand Down Expand Up @@ -7050,6 +7056,7 @@ NOKPROBE_SYMBOL(ftrace_ops_no_ops);
static void ftrace_ops_assist_func(unsigned long ip, unsigned long parent_ip,
struct ftrace_ops *op, struct ftrace_regs *fregs)
{
#if ARCH_SUPPORTS_FTRACE_OPS
int bit;

bit = trace_test_and_set_recursion(ip, parent_ip, TRACE_LIST_START, TRACE_LIST_MAX);
Expand All @@ -7063,6 +7070,7 @@ static void ftrace_ops_assist_func(unsigned long ip, unsigned long parent_ip,

preempt_enable_notrace();
trace_clear_recursion(bit);
#endif
}
NOKPROBE_SYMBOL(ftrace_ops_assist_func);

Expand All @@ -7085,7 +7093,7 @@ ftrace_func_t ftrace_ops_get_func(struct ftrace_ops *ops)
*/
if (ops->flags & (FTRACE_OPS_FL_RECURSION |
FTRACE_OPS_FL_RCU))
return ftrace_ops_assist_func;
return CAST_FTRACE_FUNC(ftrace_ops_assist_func);

return ops->func;
}
Expand Down Expand Up @@ -7521,7 +7529,7 @@ void ftrace_kill(void)
{
ftrace_disabled = 1;
ftrace_enabled = 0;
ftrace_trace_function = ftrace_stub;
ftrace_trace_function = CAST_FTRACE_FUNC(ftrace_stub);
}

/**
Expand Down Expand Up @@ -7622,7 +7630,7 @@ ftrace_enable_sysctl(struct ctl_table *table, int write,
}

/* stopping ftrace calls (just send to ftrace_stub) */
ftrace_trace_function = ftrace_stub;
ftrace_trace_function = CAST_FTRACE_FUNC(ftrace_stub);

ftrace_shutdown_sysctl();
}
Expand Down
2 changes: 1 addition & 1 deletion kernel/trace/trace_event_perf.c
Expand Up @@ -484,7 +484,7 @@ static int perf_ftrace_function_register(struct perf_event *event)
{
struct ftrace_ops *ops = &event->ftrace_ops;

ops->func = perf_ftrace_function_call;
ops->func = CAST_FTRACE_FUNC(perf_ftrace_function_call);
ops->private = (void *)(unsigned long)nr_cpu_ids;

return register_ftrace_function(ops);
Expand Down
10 changes: 5 additions & 5 deletions kernel/trace/trace_functions.c
Expand Up @@ -62,7 +62,7 @@ int ftrace_allocate_ftrace_ops(struct trace_array *tr)
return -ENOMEM;

/* Currently only the non stack version is supported */
ops->func = function_trace_call;
ops->func = CAST_FTRACE_FUNC(function_trace_call);
ops->flags = FTRACE_OPS_FL_PID;

tr->ops = ops;
Expand Down Expand Up @@ -105,13 +105,13 @@ static ftrace_func_t select_trace_function(u32 flags_val)
{
switch (flags_val & TRACE_FUNC_OPT_MASK) {
case TRACE_FUNC_NO_OPTS:
return function_trace_call;
return CAST_FTRACE_FUNC(function_trace_call);
case TRACE_FUNC_OPT_STACK:
return function_stack_trace_call;
return CAST_FTRACE_FUNC(function_stack_trace_call);
case TRACE_FUNC_OPT_NO_REPEATS:
return function_no_repeats_trace_call;
return CAST_FTRACE_FUNC(function_no_repeats_trace_call);
case TRACE_FUNC_OPT_STACK | TRACE_FUNC_OPT_NO_REPEATS:
return function_stack_no_repeats_trace_call;
return CAST_FTRACE_FUNC(function_stack_no_repeats_trace_call);
default:
return NULL;
}
Expand Down
2 changes: 1 addition & 1 deletion kernel/trace/trace_sched_wakeup.c
Expand Up @@ -673,7 +673,7 @@ static int __wakeup_tracer_init(struct trace_array *tr)

tr->max_latency = 0;
wakeup_trace = tr;
ftrace_init_array_ops(tr, wakeup_tracer_call);
ftrace_init_array_ops(tr, CAST_FTRACE_FUNC(wakeup_tracer_call));
start_wakeup_tracer(tr);

wakeup_busy = true;
Expand Down
2 changes: 1 addition & 1 deletion kernel/trace/trace_stack.c
Expand Up @@ -317,7 +317,7 @@ stack_trace_call(unsigned long ip, unsigned long parent_ip,

static struct ftrace_ops trace_ops __read_mostly =
{
.func = stack_trace_call,
.func = CAST_FTRACE_FUNC(stack_trace_call),
};

static ssize_t
Expand Down

0 comments on commit 9c10c07

Please sign in to comment.