Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

objtool: Make noinstr hacks optional

Objtool has some hacks in place to workaround toolchain limitations
which otherwise would break no-instrumentation rules. Make the hacks
explicit (and optional for other arches) by turning it into a cmdline
option and kernel config option.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Miroslav Benes <mbenes@suse.cz>
Link: https://lkml.kernel.org/r/b326eeb9c33231b9dfbb925f194ed7ee40edcd7c.1650300597.git.jpoimboe@redhat.com

authored by

Josh Poimboeuf and committed by
Peter Zijlstra
22102f45 4ab7674f

+23 -6
+3
arch/Kconfig
··· 1035 1035 config HAVE_JUMP_LABEL_HACK 1036 1036 bool 1037 1037 1038 + config HAVE_NOINSTR_HACK 1039 + bool 1040 + 1038 1041 config HAVE_STACK_VALIDATION 1039 1042 bool 1040 1043 help
+1
arch/x86/Kconfig
··· 231 231 select HAVE_MOD_ARCH_SPECIFIC 232 232 select HAVE_MOVE_PMD 233 233 select HAVE_MOVE_PUD 234 + select HAVE_NOINSTR_HACK if HAVE_OBJTOOL 234 235 select HAVE_NMI 235 236 select HAVE_OBJTOOL if X86_64 236 237 select HAVE_OPTPROBES
+2 -2
lib/Kconfig.debug
··· 2036 2036 bool "Code coverage for fuzzing" 2037 2037 depends on ARCH_HAS_KCOV 2038 2038 depends on CC_HAS_SANCOV_TRACE_PC || GCC_PLUGINS 2039 - depends on !ARCH_WANTS_NO_INSTR || HAVE_OBJTOOL || \ 2039 + depends on !ARCH_WANTS_NO_INSTR || HAVE_NOINSTR_HACK || \ 2040 2040 GCC_VERSION >= 120000 || CLANG_VERSION >= 130000 2041 2041 select DEBUG_FS 2042 2042 select GCC_PLUGIN_SANCOV if !CC_HAS_SANCOV_TRACE_PC 2043 - select OBJTOOL if HAVE_OBJTOOL 2043 + select OBJTOOL if HAVE_NOINSTR_HACK 2044 2044 help 2045 2045 KCOV exposes kernel code coverage information in a form suitable 2046 2046 for coverage-guided fuzzing (randomized testing).
+3 -2
lib/Kconfig.kcsan
··· 187 187 # We can either let objtool nop __tsan_func_{entry,exit}() and builtin 188 188 # atomics instrumentation in .noinstr.text, or use a compiler that can 189 189 # implement __no_kcsan to really remove all instrumentation. 190 - depends on HAVE_OBJTOOL || CC_IS_GCC || CLANG_VERSION >= 140000 191 - select OBJTOOL if HAVE_OBJTOOL 190 + depends on !ARCH_WANTS_NO_INSTR || HAVE_NOINSTR_HACK || \ 191 + CC_IS_GCC || CLANG_VERSION >= 140000 192 + select OBJTOOL if HAVE_NOINSTR_HACK 192 193 help 193 194 Enable support for modeling a subset of weak memory, which allows 194 195 detecting a subset of data races due to missing memory barriers.
+1
scripts/Makefile.build
··· 228 228 229 229 objtool_args = \ 230 230 $(if $(CONFIG_HAVE_JUMP_LABEL_HACK), --hacks=jump_label) \ 231 + $(if $(CONFIG_HAVE_NOINSTR_HACK), --hacks=noinstr) \ 231 232 $(if $(CONFIG_X86_KERNEL_IBT), --lto --ibt) \ 232 233 $(if $(CONFIG_FTRACE_MCOUNT_USE_OBJTOOL), --mcount) \ 233 234 $(if $(CONFIG_UNWINDER_ORC), --orc) \
+7 -1
tools/objtool/builtin-check.c
··· 47 47 found = true; 48 48 } 49 49 50 + if (!str || strstr(str, "noinstr")) { 51 + opts.hack_noinstr = true; 52 + found = true; 53 + } 54 + 50 55 return found ? 0 : -1; 51 56 } 52 57 53 58 const struct option check_options[] = { 54 59 OPT_GROUP("Actions:"), 55 - OPT_CALLBACK_OPTARG('h', "hacks", NULL, NULL, "jump_label", "patch toolchain bugs/limitations", parse_hacks), 60 + OPT_CALLBACK_OPTARG('h', "hacks", NULL, NULL, "jump_label,noinstr", "patch toolchain bugs/limitations", parse_hacks), 56 61 OPT_BOOLEAN('i', "ibt", &opts.ibt, "validate and annotate IBT"), 57 62 OPT_BOOLEAN('m', "mcount", &opts.mcount, "annotate mcount/fentry calls for ftrace"), 58 63 OPT_BOOLEAN('n', "noinstr", &opts.noinstr, "validate noinstr rules"), ··· 113 108 static bool opts_valid(void) 114 109 { 115 110 if (opts.hack_jump_label || 111 + opts.hack_noinstr || 116 112 opts.ibt || 117 113 opts.mcount || 118 114 opts.noinstr ||
+1 -1
tools/objtool/check.c
··· 1144 1144 * attribute so they need a little help, NOP out any such calls from 1145 1145 * noinstr text. 1146 1146 */ 1147 - if (insn->sec->noinstr && sym->profiling_func) { 1147 + if (opts.hack_noinstr && insn->sec->noinstr && sym->profiling_func) { 1148 1148 if (reloc) { 1149 1149 reloc->type = R_NONE; 1150 1150 elf_write_reloc(file->elf, reloc);
+1
tools/objtool/include/objtool/builtin.h
··· 13 13 /* actions: */ 14 14 bool dump_orc; 15 15 bool hack_jump_label; 16 + bool hack_noinstr; 16 17 bool ibt; 17 18 bool mcount; 18 19 bool noinstr;