Commit 87051ec1 authored by Marcin Nowakowski's avatar Marcin Nowakowski Committed by Ralf Baechle

MIPS: ftrace: fix init functions tracing

Since introduction of tracing for init functions the in_kernel_space()
check is no longer correct, as it ignores the init sections. As a
result, when probes are inserted (and disabled) in the init functions,
a branch instruction is inserted instead of a nop, which is likely to
result in random crashes during boot.

Remove the MIPS-specific in_kernel_space() method and replace it with a
generic core_kernel_text() that also checks for init sections during
system boot stage.

Fixes: 42c269c8 ("ftrace: Allow for function tracing to record init functions on boot up")
Signed-off-by: default avatarMarcin Nowakowski <marcin.nowakowski@imgtec.com>
Tested-by: default avatarMatt Redfearn <matt.redfearn@imgtec.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/16092/Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent c56e7a4c
...@@ -38,20 +38,6 @@ void arch_ftrace_update_code(int command) ...@@ -38,20 +38,6 @@ void arch_ftrace_update_code(int command)
#endif #endif
/*
* Check if the address is in kernel space
*
* Clone core_kernel_text() from kernel/extable.c, but doesn't call
* init_kernel_text() for Ftrace doesn't trace functions in init sections.
*/
static inline int in_kernel_space(unsigned long ip)
{
if (ip >= (unsigned long)_stext &&
ip <= (unsigned long)_etext)
return 1;
return 0;
}
#ifdef CONFIG_DYNAMIC_FTRACE #ifdef CONFIG_DYNAMIC_FTRACE
#define JAL 0x0c000000 /* jump & link: ip --> ra, jump to target */ #define JAL 0x0c000000 /* jump & link: ip --> ra, jump to target */
...@@ -198,7 +184,7 @@ int ftrace_make_nop(struct module *mod, ...@@ -198,7 +184,7 @@ int ftrace_make_nop(struct module *mod,
* If ip is in kernel space, no long call, otherwise, long call is * If ip is in kernel space, no long call, otherwise, long call is
* needed. * needed.
*/ */
new = in_kernel_space(ip) ? INSN_NOP : INSN_B_1F; new = core_kernel_text(ip) ? INSN_NOP : INSN_B_1F;
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
return ftrace_modify_code(ip, new); return ftrace_modify_code(ip, new);
#else #else
...@@ -218,12 +204,12 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) ...@@ -218,12 +204,12 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
unsigned int new; unsigned int new;
unsigned long ip = rec->ip; unsigned long ip = rec->ip;
new = in_kernel_space(ip) ? insn_jal_ftrace_caller : insn_la_mcount[0]; new = core_kernel_text(ip) ? insn_jal_ftrace_caller : insn_la_mcount[0];
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
return ftrace_modify_code(ip, new); return ftrace_modify_code(ip, new);
#else #else
return ftrace_modify_code_2r(ip, new, in_kernel_space(ip) ? return ftrace_modify_code_2r(ip, new, core_kernel_text(ip) ?
INSN_NOP : insn_la_mcount[1]); INSN_NOP : insn_la_mcount[1]);
#endif #endif
} }
...@@ -289,7 +275,7 @@ unsigned long ftrace_get_parent_ra_addr(unsigned long self_ra, unsigned long ...@@ -289,7 +275,7 @@ unsigned long ftrace_get_parent_ra_addr(unsigned long self_ra, unsigned long
* instruction "lui v1, hi_16bit_of_mcount"(offset is 24), but for * instruction "lui v1, hi_16bit_of_mcount"(offset is 24), but for
* kernel, move after the instruction "move ra, at"(offset is 16) * kernel, move after the instruction "move ra, at"(offset is 16)
*/ */
ip = self_ra - (in_kernel_space(self_ra) ? 16 : 24); ip = self_ra - (core_kernel_text(self_ra) ? 16 : 24);
/* /*
* search the text until finding the non-store instruction or "s{d,w} * search the text until finding the non-store instruction or "s{d,w}
...@@ -394,7 +380,7 @@ void prepare_ftrace_return(unsigned long *parent_ra_addr, unsigned long self_ra, ...@@ -394,7 +380,7 @@ void prepare_ftrace_return(unsigned long *parent_ra_addr, unsigned long self_ra,
* entries configured through the tracing/set_graph_function interface. * entries configured through the tracing/set_graph_function interface.
*/ */
insns = in_kernel_space(self_ra) ? 2 : MCOUNT_OFFSET_INSNS + 1; insns = core_kernel_text(self_ra) ? 2 : MCOUNT_OFFSET_INSNS + 1;
trace.func = self_ra - (MCOUNT_INSN_SIZE * insns); trace.func = self_ra - (MCOUNT_INSN_SIZE * insns);
/* Only trace if the calling function expects to */ /* Only trace if the calling function expects to */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment