Commit dc283d70 authored by Rabin Vincent's avatar Rabin Vincent Committed by Russell King

ARM: 7351/1: ftrace: remove useless memory checks

Before replacing an instruction, the ftrace code determines what the old
instruction should be and verifies that that's what's really there in
memory before replacing it.  This is useful if for example a bug in
mcountrecord causes it to record wrong locations.

However, in cases where we replace call sites in entry-common.S, these
checks are not needed.  For these, we currently just memcpy() the memory
content and then "verify" it -- this is quite useless and can be
removed.
Signed-off-by: default avatarRabin Vincent <rabin@rab.in>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 9141a003
...@@ -121,15 +121,17 @@ static unsigned long ftrace_call_replace(unsigned long pc, unsigned long addr) ...@@ -121,15 +121,17 @@ static unsigned long ftrace_call_replace(unsigned long pc, unsigned long addr)
} }
static int ftrace_modify_code(unsigned long pc, unsigned long old, static int ftrace_modify_code(unsigned long pc, unsigned long old,
unsigned long new) unsigned long new, bool validate)
{ {
unsigned long replaced; unsigned long replaced;
if (probe_kernel_read(&replaced, (void *)pc, MCOUNT_INSN_SIZE)) if (validate) {
return -EFAULT; if (probe_kernel_read(&replaced, (void *)pc, MCOUNT_INSN_SIZE))
return -EFAULT;
if (replaced != old) if (replaced != old)
return -EINVAL; return -EINVAL;
}
if (probe_kernel_write((void *)pc, &new, MCOUNT_INSN_SIZE)) if (probe_kernel_write((void *)pc, &new, MCOUNT_INSN_SIZE))
return -EPERM; return -EPERM;
...@@ -141,23 +143,21 @@ static int ftrace_modify_code(unsigned long pc, unsigned long old, ...@@ -141,23 +143,21 @@ static int ftrace_modify_code(unsigned long pc, unsigned long old,
int ftrace_update_ftrace_func(ftrace_func_t func) int ftrace_update_ftrace_func(ftrace_func_t func)
{ {
unsigned long pc, old; unsigned long pc;
unsigned long new; unsigned long new;
int ret; int ret;
pc = (unsigned long)&ftrace_call; pc = (unsigned long)&ftrace_call;
memcpy(&old, &ftrace_call, MCOUNT_INSN_SIZE);
new = ftrace_call_replace(pc, (unsigned long)func); new = ftrace_call_replace(pc, (unsigned long)func);
ret = ftrace_modify_code(pc, old, new); ret = ftrace_modify_code(pc, 0, new, false);
#ifdef CONFIG_OLD_MCOUNT #ifdef CONFIG_OLD_MCOUNT
if (!ret) { if (!ret) {
pc = (unsigned long)&ftrace_call_old; pc = (unsigned long)&ftrace_call_old;
memcpy(&old, &ftrace_call_old, MCOUNT_INSN_SIZE);
new = ftrace_call_replace(pc, (unsigned long)func); new = ftrace_call_replace(pc, (unsigned long)func);
ret = ftrace_modify_code(pc, old, new); ret = ftrace_modify_code(pc, 0, new, false);
} }
#endif #endif
...@@ -172,7 +172,7 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) ...@@ -172,7 +172,7 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
old = ftrace_nop_replace(rec); old = ftrace_nop_replace(rec);
new = ftrace_call_replace(ip, adjust_address(rec, addr)); new = ftrace_call_replace(ip, adjust_address(rec, addr));
return ftrace_modify_code(rec->ip, old, new); return ftrace_modify_code(rec->ip, old, new, true);
} }
int ftrace_make_nop(struct module *mod, int ftrace_make_nop(struct module *mod,
...@@ -185,7 +185,7 @@ int ftrace_make_nop(struct module *mod, ...@@ -185,7 +185,7 @@ int ftrace_make_nop(struct module *mod,
old = ftrace_call_replace(ip, adjust_address(rec, addr)); old = ftrace_call_replace(ip, adjust_address(rec, addr));
new = ftrace_nop_replace(rec); new = ftrace_nop_replace(rec);
ret = ftrace_modify_code(ip, old, new); ret = ftrace_modify_code(ip, old, new, true);
#ifdef CONFIG_OLD_MCOUNT #ifdef CONFIG_OLD_MCOUNT
if (ret == -EINVAL && addr == MCOUNT_ADDR) { if (ret == -EINVAL && addr == MCOUNT_ADDR) {
...@@ -193,7 +193,7 @@ int ftrace_make_nop(struct module *mod, ...@@ -193,7 +193,7 @@ int ftrace_make_nop(struct module *mod,
old = ftrace_call_replace(ip, adjust_address(rec, addr)); old = ftrace_call_replace(ip, adjust_address(rec, addr));
new = ftrace_nop_replace(rec); new = ftrace_nop_replace(rec);
ret = ftrace_modify_code(ip, old, new); ret = ftrace_modify_code(ip, old, new, true);
} }
#endif #endif
...@@ -254,7 +254,7 @@ static int __ftrace_modify_caller(unsigned long *callsite, ...@@ -254,7 +254,7 @@ static int __ftrace_modify_caller(unsigned long *callsite,
unsigned long old = enable ? nop : branch; unsigned long old = enable ? nop : branch;
unsigned long new = enable ? branch : nop; unsigned long new = enable ? branch : nop;
return ftrace_modify_code(pc, old, new); return ftrace_modify_code(pc, old, new, true);
} }
static int ftrace_modify_graph_caller(bool enable) static int ftrace_modify_graph_caller(bool enable)
......
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