riscv: patch code by fixmap mapping
authorZong Li <zong.li@sifive.com>
Mon, 9 Mar 2020 16:55:44 +0000 (00:55 +0800)
committerPalmer Dabbelt <palmerdabbelt@google.com>
Thu, 26 Mar 2020 16:24:55 +0000 (09:24 -0700)
On strict kernel memory permission, the ftrace have to change the
permission of text for dynamic patching the intructions. Use
riscv_patch_text_nosync() to patch code instead of probe_kernel_write.

Signed-off-by: Zong Li <zong.li@sifive.com>
Signed-off-by: Palmer Dabbelt <palmerdabbelt@google.com>
arch/riscv/kernel/ftrace.c

index c40fdcdeb950a59f48f1be56ff8776253883bf90..ce69b34ff55d092ae51baf338f522109481ea3d6 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/ftrace.h>
 #include <linux/uaccess.h>
 #include <asm/cacheflush.h>
+#include <asm/patch.h>
 
 #ifdef CONFIG_DYNAMIC_FTRACE
 static int ftrace_check_current_call(unsigned long hook_pos,
@@ -46,20 +47,14 @@ static int __ftrace_modify_call(unsigned long hook_pos, unsigned long target,
 {
        unsigned int call[2];
        unsigned int nops[2] = {NOP4, NOP4};
-       int ret = 0;
 
        make_call(hook_pos, target, call);
 
-       /* replace the auipc-jalr pair at once */
-       ret = probe_kernel_write((void *)hook_pos, enable ? call : nops,
-                                MCOUNT_INSN_SIZE);
-       /* return must be -EPERM on write error */
-       if (ret)
+       /* Replace the auipc-jalr pair at once. Return -EPERM on write error. */
+       if (riscv_patch_text_nosync
+           ((void *)hook_pos, enable ? call : nops, MCOUNT_INSN_SIZE))
                return -EPERM;
 
-       smp_mb();
-       flush_icache_range((void *)hook_pos, (void *)hook_pos + MCOUNT_INSN_SIZE);
-
        return 0;
 }