summaryrefslogtreecommitdiff
path: root/arch/powerpc/kernel/trace
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/trace')
-rw-r--r--arch/powerpc/kernel/trace/ftrace.c42
-rw-r--r--arch/powerpc/kernel/trace/ftrace_64_pg.c6
-rw-r--r--arch/powerpc/kernel/trace/ftrace_entry.S44
3 files changed, 60 insertions, 32 deletions
diff --git a/arch/powerpc/kernel/trace/ftrace.c b/arch/powerpc/kernel/trace/ftrace.c
index 2f776f137a89..1b2f293e7dcb 100644
--- a/arch/powerpc/kernel/trace/ftrace.c
+++ b/arch/powerpc/kernel/trace/ftrace.c
@@ -37,11 +37,29 @@ unsigned long ftrace_call_adjust(unsigned long addr)
if (addr >= (unsigned long)__exittext_begin && addr < (unsigned long)__exittext_end)
return 0;
- if (IS_ENABLED(CONFIG_ARCH_USING_PATCHABLE_FUNCTION_ENTRY) &&
- !IS_ENABLED(CONFIG_PPC_FTRACE_OUT_OF_LINE)) {
- addr += MCOUNT_INSN_SIZE;
- if (IS_ENABLED(CONFIG_DYNAMIC_FTRACE_WITH_CALL_OPS))
+ if (IS_ENABLED(CONFIG_ARCH_USING_PATCHABLE_FUNCTION_ENTRY)) {
+ if (!IS_ENABLED(CONFIG_PPC_FTRACE_OUT_OF_LINE)) {
addr += MCOUNT_INSN_SIZE;
+ if (IS_ENABLED(CONFIG_DYNAMIC_FTRACE_WITH_CALL_OPS))
+ addr += MCOUNT_INSN_SIZE;
+ } else if (IS_ENABLED(CONFIG_CC_IS_CLANG) && IS_ENABLED(CONFIG_PPC64)) {
+ /*
+ * addr points to global entry point though the NOP was emitted at local
+ * entry point due to https://github.com/llvm/llvm-project/issues/163706
+ * Handle that here with ppc_function_entry() for kernel symbols while
+ * adjusting module addresses in the else case, by looking for the below
+ * module global entry point sequence:
+ * ld r2, -8(r12)
+ * add r2, r2, r12
+ */
+ if (is_kernel_text(addr) || is_kernel_inittext(addr))
+ addr = ppc_function_entry((void *)addr);
+ else if ((ppc_inst_val(ppc_inst_read((u32 *)addr)) ==
+ PPC_RAW_LD(_R2, _R12, -8)) &&
+ (ppc_inst_val(ppc_inst_read((u32 *)(addr+4))) ==
+ PPC_RAW_ADD(_R2, _R2, _R12)))
+ addr += 8;
+ }
}
return addr;
@@ -115,10 +133,8 @@ static unsigned long ftrace_lookup_module_stub(unsigned long ip, unsigned long a
{
struct module *mod = NULL;
- preempt_disable();
- mod = __module_text_address(ip);
- preempt_enable();
-
+ scoped_guard(rcu)
+ mod = __module_text_address(ip);
if (!mod)
pr_err("No module loaded at addr=%lx\n", ip);
@@ -490,8 +506,10 @@ int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec)
return ret;
/* Set up out-of-line stub */
- if (IS_ENABLED(CONFIG_PPC_FTRACE_OUT_OF_LINE))
- return ftrace_init_ool_stub(mod, rec);
+ if (IS_ENABLED(CONFIG_PPC_FTRACE_OUT_OF_LINE)) {
+ ret = ftrace_init_ool_stub(mod, rec);
+ goto out;
+ }
/* Nop-out the ftrace location */
new = ppc_inst(PPC_RAW_NOP());
@@ -522,6 +540,10 @@ int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec)
return -EINVAL;
}
+out:
+ if (!ret)
+ ret = ftrace_rec_set_nop_ops(rec);
+
return ret;
}
diff --git a/arch/powerpc/kernel/trace/ftrace_64_pg.c b/arch/powerpc/kernel/trace/ftrace_64_pg.c
index ac35015f04c6..5c6e545d1708 100644
--- a/arch/powerpc/kernel/trace/ftrace_64_pg.c
+++ b/arch/powerpc/kernel/trace/ftrace_64_pg.c
@@ -120,10 +120,8 @@ static struct module *ftrace_lookup_module(struct dyn_ftrace *rec)
{
struct module *mod;
- preempt_disable();
- mod = __module_text_address(rec->ip);
- preempt_enable();
-
+ scoped_guard(rcu)
+ mod = __module_text_address(rec->ip);
if (!mod)
pr_err("No module loaded at addr=%lx\n", rec->ip);
diff --git a/arch/powerpc/kernel/trace/ftrace_entry.S b/arch/powerpc/kernel/trace/ftrace_entry.S
index 2c1b24100eca..6599fe3c6234 100644
--- a/arch/powerpc/kernel/trace/ftrace_entry.S
+++ b/arch/powerpc/kernel/trace/ftrace_entry.S
@@ -212,10 +212,10 @@
bne- 1f
mr r3, r15
+1: mtlr r3
.if \allregs == 0
REST_GPR(15, r1)
.endif
-1: mtlr r3
#endif
/* Restore gprs */
@@ -409,23 +409,31 @@ EXPORT_SYMBOL(_mcount)
_GLOBAL(return_to_handler)
/* need to save return values */
#ifdef CONFIG_PPC64
- std r4, -32(r1)
- std r3, -24(r1)
+ stdu r1, -SWITCH_FRAME_SIZE(r1)
+ std r4, GPR4(r1)
+ std r3, GPR3(r1)
+ /* Save previous stack pointer (r1) */
+ addi r3, r1, SWITCH_FRAME_SIZE
+ std r3, GPR1(r1)
/* save TOC */
- std r2, -16(r1)
- std r31, -8(r1)
+ std r2, 24(r1)
+ std r31, 32(r1)
mr r31, r1
- stdu r1, -112(r1)
-
+ /* pass ftrace_regs/pt_regs to ftrace_return_to_handler */
+ addi r3, r1, STACK_INT_FRAME_REGS
/*
* We might be called from a module.
* Switch to our TOC to run inside the core kernel.
*/
LOAD_PACA_TOC()
#else
- stwu r1, -16(r1)
- stw r3, 8(r1)
- stw r4, 12(r1)
+ stwu r1, -SWITCH_FRAME_SIZE(r1)
+ stw r4, GPR4(r1)
+ stw r3, GPR3(r1)
+ addi r3, r1, SWITCH_FRAME_SIZE
+ stw r3, GPR1(r1)
+ /* pass ftrace_regs/pt_regs to ftrace_return_to_handler */
+ addi r3, r1, STACK_INT_FRAME_REGS
#endif
bl ftrace_return_to_handler
@@ -435,15 +443,15 @@ _GLOBAL(return_to_handler)
mtlr r3
#ifdef CONFIG_PPC64
- ld r1, 0(r1)
- ld r4, -32(r1)
- ld r3, -24(r1)
- ld r2, -16(r1)
- ld r31, -8(r1)
+ ld r4, GPR4(r1)
+ ld r3, GPR3(r1)
+ ld r2, 24(r1)
+ ld r31, 32(r1)
+ ld r1, 0(r1)
#else
- lwz r3, 8(r1)
- lwz r4, 12(r1)
- addi r1, r1, 16
+ lwz r3, GPR3(r1)
+ lwz r4, GPR4(r1)
+ addi r1, r1, SWITCH_FRAME_SIZE
#endif
/* Jump back to real return address */