summaryrefslogtreecommitdiff
path: root/arch/powerpc/kernel/trace
diff options
context:
space:
mode:
authorNaveen N Rao <naveen@kernel.org>2023-06-19 15:17:26 +0530
committerMichael Ellerman <mpe@ellerman.id.au>2023-08-22 00:09:05 +1000
commitf4fcbf2e093e25a7faa8a3c2a5097524114e9547 (patch)
treed6ac421959bf917b0d1e684273008869328d3196 /arch/powerpc/kernel/trace
parentbad90aa52d9a0141c41e00ccd4c40be30a29acc6 (diff)
powerpc/ftrace: Refactor ftrace_modify_code()
Split up ftrace_modify_code() into a few helpers for future use. Also update error messages accordingly. Signed-off-by: Naveen N Rao <naveen@kernel.org> Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://msgid.link/a8daa49712b44ff539e6c22a2ea649a540386798.1687166935.git.naveen@kernel.org
Diffstat (limited to 'arch/powerpc/kernel/trace')
-rw-r--r--arch/powerpc/kernel/trace/ftrace.c47
1 files changed, 27 insertions, 20 deletions
diff --git a/arch/powerpc/kernel/trace/ftrace.c b/arch/powerpc/kernel/trace/ftrace.c
index 913c7aa63d3f..ef4e49c2c377 100644
--- a/arch/powerpc/kernel/trace/ftrace.c
+++ b/arch/powerpc/kernel/trace/ftrace.c
@@ -50,32 +50,39 @@ ftrace_call_replace(unsigned long ip, unsigned long addr, int link)
return op;
}
-static inline int
-ftrace_modify_code(unsigned long ip, ppc_inst_t old, ppc_inst_t new)
+static inline int ftrace_read_inst(unsigned long ip, ppc_inst_t *op)
{
- ppc_inst_t replaced;
+ if (copy_inst_from_kernel_nofault(op, (void *)ip)) {
+ pr_err("0x%lx: fetching instruction failed\n", ip);
+ return -EFAULT;
+ }
- /*
- * Note:
- * We are paranoid about modifying text, as if a bug was to happen, it
- * could cause us to read or write to someplace that could cause harm.
- * Carefully read and modify the code with probe_kernel_*(), and make
- * sure what we read is what we expected it to be before modifying it.
- */
+ return 0;
+}
- /* read the text we want to modify */
- if (copy_inst_from_kernel_nofault(&replaced, (void *)ip))
- return -EFAULT;
+static inline int ftrace_validate_inst(unsigned long ip, ppc_inst_t inst)
+{
+ ppc_inst_t op;
+ int ret;
- /* Make sure it is what we expect it to be */
- if (!ppc_inst_equal(replaced, old)) {
- pr_err("%p: replaced (%08lx) != old (%08lx)", (void *)ip,
- ppc_inst_as_ulong(replaced), ppc_inst_as_ulong(old));
- return -EINVAL;
+ ret = ftrace_read_inst(ip, &op);
+ if (!ret && !ppc_inst_equal(op, inst)) {
+ pr_err("0x%lx: expected (%08lx) != found (%08lx)\n",
+ ip, ppc_inst_as_ulong(inst), ppc_inst_as_ulong(op));
+ ret = -EINVAL;
}
- /* replace the text with the new text */
- return patch_instruction((u32 *)ip, new);
+ return ret;
+}
+
+static inline int ftrace_modify_code(unsigned long ip, ppc_inst_t old, ppc_inst_t new)
+{
+ int ret = ftrace_validate_inst(ip, old);
+
+ if (!ret)
+ ret = patch_instruction((u32 *)ip, new);
+
+ return ret;
}
/*