[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20210301201526.65ce7f1c@oasis.local.home>
Date: Mon, 1 Mar 2021 20:15:26 -0500
From: Steven Rostedt <rostedt@...dmis.org>
To: Sami Tolvanen <samitolvanen@...gle.com>
Cc: kernel test robot <oliver.sang@...el.com>,
Peter Zijlstra <peterz@...radead.org>,
Kees Cook <keescook@...omium.org>,
LKML <linux-kernel@...r.kernel.org>, lkp@...ts.01.org,
kernel test robot <lkp@...el.com>
Subject: Re: [x86, build] 6dafca9780:
WARNING:at_arch/x86/kernel/ftrace.c:#ftrace_verify_code
On Mon, 1 Mar 2021 16:03:51 -0800
Sami Tolvanen <samitolvanen@...gle.com> wrote:
>
> > ret = ftrace_verify_code(rec->ip, old);
> > +
> > + if (__is_defined(CC_USING_NOP_MCOUNT) && ret && old_nop) {
> > + /* Compiler could have put in P6_NOP5 */
> > + old = P6_NOP5;
> > + ret = ftrace_verify_code(rec->ip, old);
> > + }
> > +
>
> Wouldn't that still hit WARN(1) in the initial ftrace_verify_code()
> call if ideal_nops doesn't match?
That was too quickly written ;-)
Take 2:
[ with fixes for setting p6_nop ]
diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c
index 7edbd5ee5ed4..e8afc765e00a 100644
--- a/arch/x86/kernel/ftrace.c
+++ b/arch/x86/kernel/ftrace.c
@@ -36,6 +36,7 @@
#ifdef CONFIG_DYNAMIC_FTRACE
static int ftrace_poke_late = 0;
+static const char p6_nop[] = { P6_NOP5 };
int ftrace_arch_code_modify_prepare(void)
__acquires(&text_mutex)
@@ -74,7 +75,7 @@ static const char *ftrace_call_replace(unsigned long ip, unsigned long addr)
return text_gen_insn(CALL_INSN_OPCODE, (void *)ip, (void *)addr);
}
-static int ftrace_verify_code(unsigned long ip, const char *old_code)
+static int ftrace_verify_code(unsigned long ip, const char *old_code, bool warn)
{
char cur_code[MCOUNT_INSN_SIZE];
@@ -87,13 +88,13 @@ static int ftrace_verify_code(unsigned long ip, const char *old_code)
*/
/* read the text we want to modify */
if (copy_from_kernel_nofault(cur_code, (void *)ip, MCOUNT_INSN_SIZE)) {
- WARN_ON(1);
+ WARN_ON(warn);
return -EFAULT;
}
/* Make sure it is what we expect it to be */
if (memcmp(cur_code, old_code, MCOUNT_INSN_SIZE) != 0) {
- WARN_ON(1);
+ WARN_ON(warn);
return -EINVAL;
}
@@ -107,9 +108,9 @@ static int ftrace_verify_code(unsigned long ip, const char *old_code)
*/
static int __ref
ftrace_modify_code_direct(unsigned long ip, const char *old_code,
- const char *new_code)
+ const char *new_code, bool verify_warn)
{
- int ret = ftrace_verify_code(ip, old_code);
+ int ret = ftrace_verify_code(ip, old_code, verify_warn);
if (ret)
return ret;
@@ -138,7 +139,7 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, unsigned long ad
* just modify the code directly.
*/
if (addr == MCOUNT_ADDR)
- return ftrace_modify_code_direct(ip, old, new);
+ return ftrace_modify_code_direct(ip, old, new, true);
/*
* x86 overrides ftrace_replace_code -- this function will never be used
@@ -152,12 +153,20 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
{
unsigned long ip = rec->ip;
const char *new, *old;
+ bool verify_warn = !__is_defined(CC_USING_NOP_MCOUNT);
+ int ret;
old = ftrace_nop_replace();
new = ftrace_call_replace(ip, addr);
/* Should only be called when module is loaded */
- return ftrace_modify_code_direct(rec->ip, old, new);
+ ret = ftrace_modify_code_direct(rec->ip, old, new, verify_warn);
+ if (ret && !verify_warn) {
+ /* Compiler could have put in P6_NOP5 */
+ old = p6_nop;
+ ret = ftrace_modify_code_direct(rec->ip, old, new, true);
+ }
+ return ret;
}
/*
@@ -199,6 +208,8 @@ void ftrace_replace_code(int enable)
int ret;
for_ftrace_rec_iter(iter) {
+ bool verify_warn = true;
+
rec = ftrace_rec_iter_record(iter);
switch (ftrace_test_record(rec, enable)) {
@@ -208,6 +219,7 @@ void ftrace_replace_code(int enable)
case FTRACE_UPDATE_MAKE_CALL:
old = ftrace_nop_replace();
+ verify_warn = !__is_defined(CC_USING_NOP_MCOUNT);
break;
case FTRACE_UPDATE_MODIFY_CALL:
@@ -216,7 +228,14 @@ void ftrace_replace_code(int enable)
break;
}
- ret = ftrace_verify_code(rec->ip, old);
+ ret = ftrace_verify_code(rec->ip, old, verify_warn);
+
+ if (ret && !verify_warn) {
+ /* Compiler could have put in P6_NOP5 */
+ old = p6_nop;
+ ret = ftrace_verify_code(rec->ip, old, true);
+ }
+
if (ret) {
ftrace_bug(ret, rec);
return;
-- Steve
Powered by blists - more mailing lists