Merge tag 'trace-v5.3' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux...
[linux-2.6-block.git] / arch / x86 / kernel / ftrace.c
index ba37bcb7f92ba4a2126be149594b788acedb2046..024c3053dbbab673d4d23f7e78726022b03620b5 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/module.h>
+#include <linux/memory.h>
 
 #include <trace/syscall.h>
 
 #ifdef CONFIG_DYNAMIC_FTRACE
 
 int ftrace_arch_code_modify_prepare(void)
+    __acquires(&text_mutex)
 {
+       /*
+        * Need to grab text_mutex to prevent a race from module loading
+        * and live kernel patching from changing the text permissions while
+        * ftrace has it set to "read/write".
+        */
+       mutex_lock(&text_mutex);
        set_kernel_text_rw();
        set_all_modules_text_rw();
        return 0;
 }
 
 int ftrace_arch_code_modify_post_process(void)
+    __releases(&text_mutex)
 {
        set_all_modules_text_ro();
        set_kernel_text_ro();
+       mutex_unlock(&text_mutex);
        return 0;
 }
 
@@ -300,7 +310,6 @@ int ftrace_int3_handler(struct pt_regs *regs)
 
        ip = regs->ip - INT3_INSN_SIZE;
 
-#ifdef CONFIG_X86_64
        if (ftrace_location(ip)) {
                int3_emulate_call(regs, (unsigned long)ftrace_regs_caller);
                return 1;
@@ -312,12 +321,6 @@ int ftrace_int3_handler(struct pt_regs *regs)
                int3_emulate_call(regs, ftrace_update_func_call);
                return 1;
        }
-#else
-       if (ftrace_location(ip) || is_ftrace_caller(ip)) {
-               int3_emulate_jmp(regs, ip + CALL_INSN_SIZE);
-               return 1;
-       }
-#endif
 
        return 0;
 }