diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2020-04-06 09:55:50 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2020-04-06 09:55:50 -0700 |
commit | f183d269cc6c64481b47ecbf9d3aff128dc0978c (patch) | |
tree | 3897411e0d277ac966c996c9acaf17f8252df027 /arch/csky/kernel/ftrace.c | |
parent | b6ff10700d1bf33c4323d34eca1e80bc8a69f9f5 (diff) | |
parent | aefd9461d34a1b0a2acad0750c43216c1c27b9d4 (diff) |
Merge tag 'csky-for-linus-5.7-rc1' of git://github.com/c-sky/csky-linux
Pull csky updates from Guo Ren:
- Add kproobes/uprobes support
- Add lockdep, rseq, gcov support
- Fixup init_fpu
- Fixup ftrace_modify deadlock
- Fixup speculative execution on IO area
* tag 'csky-for-linus-5.7-rc1' of git://github.com/c-sky/csky-linux:
csky: Fixup cpu speculative execution to IO area
csky: Add uprobes support
csky: Add kprobes supported
csky: Enable LOCKDEP_SUPPORT
csky: Enable the gcov function
csky: Fixup get wrong psr value from phyical reg
csky/ftrace: Fixup ftrace_modify_code deadlock without CPU_HAS_ICACHE_INS
csky: Implement ftrace with regs
csky: Add support for restartable sequence
csky: Implement ptrace regs and stack API
csky: Fixup init_fpu compile warning with __init
Diffstat (limited to 'arch/csky/kernel/ftrace.c')
-rw-r--r-- | arch/csky/kernel/ftrace.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/arch/csky/kernel/ftrace.c b/arch/csky/kernel/ftrace.c index 44f4880179b7..44628e3f7fa6 100644 --- a/arch/csky/kernel/ftrace.c +++ b/arch/csky/kernel/ftrace.c @@ -3,6 +3,7 @@ #include <linux/ftrace.h> #include <linux/uaccess.h> +#include <linux/stop_machine.h> #include <asm/cacheflush.h> #ifdef CONFIG_DYNAMIC_FTRACE @@ -126,6 +127,9 @@ int ftrace_update_ftrace_func(ftrace_func_t func) { int ret = ftrace_modify_code((unsigned long)&ftrace_call, (unsigned long)func, true, true); + if (!ret) + ret = ftrace_modify_code((unsigned long)&ftrace_regs_call, + (unsigned long)func, true, true); return ret; } @@ -135,6 +139,14 @@ int __init ftrace_dyn_arch_init(void) } #endif /* CONFIG_DYNAMIC_FTRACE */ +#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS +int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, + unsigned long addr) +{ + return ftrace_modify_code(rec->ip, addr, true, true); +} +#endif + #ifdef CONFIG_FUNCTION_GRAPH_TRACER void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, unsigned long frame_pointer) @@ -190,5 +202,35 @@ int ftrace_disable_ftrace_graph_caller(void) #endif /* CONFIG_DYNAMIC_FTRACE */ #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ +#ifndef CONFIG_CPU_HAS_ICACHE_INS +struct ftrace_modify_param { + int command; + atomic_t cpu_count; +}; + +static int __ftrace_modify_code(void *data) +{ + struct ftrace_modify_param *param = data; + + if (atomic_inc_return(¶m->cpu_count) == 1) { + ftrace_modify_all_code(param->command); + atomic_inc(¶m->cpu_count); + } else { + while (atomic_read(¶m->cpu_count) <= num_online_cpus()) + cpu_relax(); + local_icache_inv_all(NULL); + } + + return 0; +} + +void arch_ftrace_update_code(int command) +{ + struct ftrace_modify_param param = { command, ATOMIC_INIT(0) }; + + stop_machine(__ftrace_modify_code, ¶m, cpu_online_mask); +} +#endif + /* _mcount is defined in abi's mcount.S */ EXPORT_SYMBOL(_mcount); |