objtool: Make jump label hack optional
Objtool secretly does a jump label hack to overcome the limitations of the toolchain. Make the hack 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/3bdcbfdd27ecb01ddec13c04bdf756a583b13d24.1650300597.git.jpoimboe@redhat.com
This commit is contained in:
parent
26e176896a
commit
4ab7674f59
|
@ -46,6 +46,7 @@ config JUMP_LABEL
|
|||
bool "Optimize very unlikely/likely branches"
|
||||
depends on HAVE_ARCH_JUMP_LABEL
|
||||
depends on CC_HAS_ASM_GOTO
|
||||
select OBJTOOL if HAVE_JUMP_LABEL_HACK
|
||||
help
|
||||
This option enables a transparent branch optimization that
|
||||
makes certain almost-always-true or almost-always-false branch
|
||||
|
@ -1031,6 +1032,9 @@ config ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
|
|||
config HAVE_OBJTOOL
|
||||
bool
|
||||
|
||||
config HAVE_JUMP_LABEL_HACK
|
||||
bool
|
||||
|
||||
config HAVE_STACK_VALIDATION
|
||||
bool
|
||||
help
|
||||
|
|
|
@ -212,6 +212,7 @@ config X86
|
|||
select HAVE_IOREMAP_PROT
|
||||
select HAVE_IRQ_EXIT_ON_IRQ_STACK if X86_64
|
||||
select HAVE_IRQ_TIME_ACCOUNTING
|
||||
select HAVE_JUMP_LABEL_HACK if HAVE_OBJTOOL
|
||||
select HAVE_KERNEL_BZIP2
|
||||
select HAVE_KERNEL_GZIP
|
||||
select HAVE_KERNEL_LZ4
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
_ASM_PTR "%c0 + %c1 - .\n\t" \
|
||||
".popsection \n\t"
|
||||
|
||||
#ifdef CONFIG_OBJTOOL
|
||||
#ifdef CONFIG_HAVE_JUMP_LABEL_HACK
|
||||
|
||||
static __always_inline bool arch_static_branch(struct static_key *key, bool branch)
|
||||
{
|
||||
|
@ -34,7 +34,7 @@ static __always_inline bool arch_static_branch(struct static_key *key, bool bran
|
|||
return true;
|
||||
}
|
||||
|
||||
#else /* !CONFIG_OBJTOOL */
|
||||
#else /* !CONFIG_HAVE_JUMP_LABEL_HACK */
|
||||
|
||||
static __always_inline bool arch_static_branch(struct static_key * const key, const bool branch)
|
||||
{
|
||||
|
@ -48,7 +48,7 @@ static __always_inline bool arch_static_branch(struct static_key * const key, co
|
|||
return true;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_OBJTOOL */
|
||||
#endif /* CONFIG_HAVE_JUMP_LABEL_HACK */
|
||||
|
||||
static __always_inline bool arch_static_branch_jump(struct static_key * const key, const bool branch)
|
||||
{
|
||||
|
|
|
@ -227,6 +227,7 @@ ifdef CONFIG_OBJTOOL
|
|||
objtool := $(objtree)/tools/objtool/objtool
|
||||
|
||||
objtool_args = \
|
||||
$(if $(CONFIG_HAVE_JUMP_LABEL_HACK), --hacks=jump_label) \
|
||||
$(if $(CONFIG_X86_KERNEL_IBT), --lto --ibt) \
|
||||
$(if $(CONFIG_FTRACE_MCOUNT_USE_OBJTOOL), --mcount) \
|
||||
$(if $(CONFIG_UNWINDER_ORC), --orc) \
|
||||
|
|
|
@ -117,6 +117,10 @@ objtool_link()
|
|||
# Don't perform vmlinux validation unless explicitly requested,
|
||||
# but run objtool on vmlinux.o now that we have an object file.
|
||||
|
||||
if is_enabled CONFIG_HAVE_JUMP_LABEL_HACK; then
|
||||
objtoolopt="${objtoolopt} --hacks=jump_label"
|
||||
fi
|
||||
|
||||
if is_enabled CONFIG_X86_KERNEL_IBT; then
|
||||
objtoolopt="${objtoolopt} --ibt"
|
||||
fi
|
||||
|
|
|
@ -31,8 +31,28 @@ static int parse_dump(const struct option *opt, const char *str, int unset)
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int parse_hacks(const struct option *opt, const char *str, int unset)
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
/*
|
||||
* Use strstr() as a lazy method of checking for comma-separated
|
||||
* options.
|
||||
*
|
||||
* No string provided == enable all options.
|
||||
*/
|
||||
|
||||
if (!str || strstr(str, "jump_label")) {
|
||||
opts.hack_jump_label = true;
|
||||
found = true;
|
||||
}
|
||||
|
||||
return found ? 0 : -1;
|
||||
}
|
||||
|
||||
const struct option check_options[] = {
|
||||
OPT_GROUP("Actions:"),
|
||||
OPT_CALLBACK_OPTARG('h', "hacks", NULL, NULL, "jump_label", "patch toolchain bugs/limitations", parse_hacks),
|
||||
OPT_BOOLEAN('i', "ibt", &opts.ibt, "validate and annotate IBT"),
|
||||
OPT_BOOLEAN('m', "mcount", &opts.mcount, "annotate mcount/fentry calls for ftrace"),
|
||||
OPT_BOOLEAN('n', "noinstr", &opts.noinstr, "validate noinstr rules"),
|
||||
|
@ -87,14 +107,15 @@ int cmd_parse_options(int argc, const char **argv, const char * const usage[])
|
|||
|
||||
static bool opts_valid(void)
|
||||
{
|
||||
if (opts.ibt ||
|
||||
opts.mcount ||
|
||||
opts.noinstr ||
|
||||
opts.orc ||
|
||||
opts.retpoline ||
|
||||
opts.sls ||
|
||||
opts.stackval ||
|
||||
opts.static_call ||
|
||||
if (opts.hack_jump_label ||
|
||||
opts.ibt ||
|
||||
opts.mcount ||
|
||||
opts.noinstr ||
|
||||
opts.orc ||
|
||||
opts.retpoline ||
|
||||
opts.sls ||
|
||||
opts.stackval ||
|
||||
opts.static_call ||
|
||||
opts.uaccess) {
|
||||
if (opts.dump_orc) {
|
||||
fprintf(stderr, "--dump can't be combined with other options\n");
|
||||
|
|
|
@ -1592,7 +1592,7 @@ static int handle_jump_alt(struct objtool_file *file,
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (special_alt->key_addend & 2) {
|
||||
if (opts.hack_jump_label && special_alt->key_addend & 2) {
|
||||
struct reloc *reloc = insn_reloc(file, orig_insn);
|
||||
|
||||
if (reloc) {
|
||||
|
|
|
@ -12,6 +12,7 @@ extern const struct option check_options[];
|
|||
struct opts {
|
||||
/* actions: */
|
||||
bool dump_orc;
|
||||
bool hack_jump_label;
|
||||
bool ibt;
|
||||
bool mcount;
|
||||
bool noinstr;
|
||||
|
|
Loading…
Reference in New Issue