objtool, kcsan: Remove memory barrier instrumentation from noinstr
[platform/kernel/linux-rpi.git] / tools / objtool / check.c
index add3990..a9a1f72 100644 (file)
@@ -849,6 +849,10 @@ static const char *uaccess_safe_builtin[] = {
        "__asan_report_store16_noabort",
        /* KCSAN */
        "__kcsan_check_access",
+       "__kcsan_mb",
+       "__kcsan_wmb",
+       "__kcsan_rmb",
+       "__kcsan_release",
        "kcsan_found_watchpoint",
        "kcsan_setup_watchpoint",
        "kcsan_check_scoped_accesses",
@@ -1068,11 +1072,11 @@ static void annotate_call_site(struct objtool_file *file,
        }
 
        /*
-        * Many compilers cannot disable KCOV with a function attribute
-        * so they need a little help, NOP out any KCOV calls from noinstr
-        * text.
+        * Many compilers cannot disable KCOV or sanitizer calls with a function
+        * attribute so they need a little help, NOP out any such calls from
+        * noinstr text.
         */
-       if (insn->sec->noinstr && sym->kcov) {
+       if (insn->sec->noinstr && sym->profiling_func) {
                if (reloc) {
                        reloc->type = R_NONE;
                        elf_write_reloc(file->elf, reloc);
@@ -1987,6 +1991,31 @@ static int read_intra_function_calls(struct objtool_file *file)
        return 0;
 }
 
+/*
+ * Return true if name matches an instrumentation function, where calls to that
+ * function from noinstr code can safely be removed, but compilers won't do so.
+ */
+static bool is_profiling_func(const char *name)
+{
+       /*
+        * Many compilers cannot disable KCOV with a function attribute.
+        */
+       if (!strncmp(name, "__sanitizer_cov_", 16))
+               return true;
+
+       /*
+        * Some compilers currently do not remove __tsan_func_entry/exit nor
+        * __tsan_atomic_signal_fence (used for barrier instrumentation) with
+        * the __no_sanitize_thread attribute, remove them. Once the kernel's
+        * minimum Clang version is 14.0, this can be removed.
+        */
+       if (!strncmp(name, "__tsan_func_", 12) ||
+           !strcmp(name, "__tsan_atomic_signal_fence"))
+               return true;
+
+       return false;
+}
+
 static int classify_symbols(struct objtool_file *file)
 {
        struct section *sec;
@@ -2007,8 +2036,8 @@ static int classify_symbols(struct objtool_file *file)
                        if (!strcmp(func->name, "__fentry__"))
                                func->fentry = true;
 
-                       if (!strncmp(func->name, "__sanitizer_cov_", 16))
-                               func->kcov = true;
+                       if (is_profiling_func(func->name))
+                               func->profiling_func = true;
                }
        }
 
@@ -3310,6 +3339,9 @@ static bool ignore_unreachable_insn(struct objtool_file *file, struct instructio
        if (!insn->func)
                return false;
 
+       if (insn->func->static_call_tramp)
+               return true;
+
        /*
         * CONFIG_UBSAN_TRAP inserts a UD2 when it sees
         * __builtin_unreachable().  The BUG() macro has an unreachable() after