Skip to content

Commit 4ab7674

Browse files
jpoimboePeter Zijlstra
authored andcommitted
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 <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Reviewed-by: Miroslav Benes <[email protected]> Link: https://lkml.kernel.org/r/3bdcbfdd27ecb01ddec13c04bdf756a583b13d24.1650300597.git.jpoimboe@redhat.com
1 parent 26e1768 commit 4ab7674

File tree

8 files changed

+44
-12
lines changed

8 files changed

+44
-12
lines changed

arch/Kconfig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ config JUMP_LABEL
4646
bool "Optimize very unlikely/likely branches"
4747
depends on HAVE_ARCH_JUMP_LABEL
4848
depends on CC_HAS_ASM_GOTO
49+
select OBJTOOL if HAVE_JUMP_LABEL_HACK
4950
help
5051
This option enables a transparent branch optimization that
5152
makes certain almost-always-true or almost-always-false branch
@@ -1031,6 +1032,9 @@ config ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
10311032
config HAVE_OBJTOOL
10321033
bool
10331034

1035+
config HAVE_JUMP_LABEL_HACK
1036+
bool
1037+
10341038
config HAVE_STACK_VALIDATION
10351039
bool
10361040
help

arch/x86/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ config X86
212212
select HAVE_IOREMAP_PROT
213213
select HAVE_IRQ_EXIT_ON_IRQ_STACK if X86_64
214214
select HAVE_IRQ_TIME_ACCOUNTING
215+
select HAVE_JUMP_LABEL_HACK if HAVE_OBJTOOL
215216
select HAVE_KERNEL_BZIP2
216217
select HAVE_KERNEL_GZIP
217218
select HAVE_KERNEL_LZ4

arch/x86/include/asm/jump_label.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
_ASM_PTR "%c0 + %c1 - .\n\t" \
2121
".popsection \n\t"
2222

23-
#ifdef CONFIG_OBJTOOL
23+
#ifdef CONFIG_HAVE_JUMP_LABEL_HACK
2424

2525
static __always_inline bool arch_static_branch(struct static_key *key, bool branch)
2626
{
@@ -34,7 +34,7 @@ static __always_inline bool arch_static_branch(struct static_key *key, bool bran
3434
return true;
3535
}
3636

37-
#else /* !CONFIG_OBJTOOL */
37+
#else /* !CONFIG_HAVE_JUMP_LABEL_HACK */
3838

3939
static __always_inline bool arch_static_branch(struct static_key * const key, const bool branch)
4040
{
@@ -48,7 +48,7 @@ static __always_inline bool arch_static_branch(struct static_key * const key, co
4848
return true;
4949
}
5050

51-
#endif /* CONFIG_OBJTOOL */
51+
#endif /* CONFIG_HAVE_JUMP_LABEL_HACK */
5252

5353
static __always_inline bool arch_static_branch_jump(struct static_key * const key, const bool branch)
5454
{

scripts/Makefile.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ ifdef CONFIG_OBJTOOL
227227
objtool := $(objtree)/tools/objtool/objtool
228228

229229
objtool_args = \
230+
$(if $(CONFIG_HAVE_JUMP_LABEL_HACK), --hacks=jump_label) \
230231
$(if $(CONFIG_X86_KERNEL_IBT), --lto --ibt) \
231232
$(if $(CONFIG_FTRACE_MCOUNT_USE_OBJTOOL), --mcount) \
232233
$(if $(CONFIG_UNWINDER_ORC), --orc) \

scripts/link-vmlinux.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,10 @@ objtool_link()
117117
# Don't perform vmlinux validation unless explicitly requested,
118118
# but run objtool on vmlinux.o now that we have an object file.
119119

120+
if is_enabled CONFIG_HAVE_JUMP_LABEL_HACK; then
121+
objtoolopt="${objtoolopt} --hacks=jump_label"
122+
fi
123+
120124
if is_enabled CONFIG_X86_KERNEL_IBT; then
121125
objtoolopt="${objtoolopt} --ibt"
122126
fi

tools/objtool/builtin-check.c

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,28 @@ static int parse_dump(const struct option *opt, const char *str, int unset)
3131
return -1;
3232
}
3333

34+
static int parse_hacks(const struct option *opt, const char *str, int unset)
35+
{
36+
bool found = false;
37+
38+
/*
39+
* Use strstr() as a lazy method of checking for comma-separated
40+
* options.
41+
*
42+
* No string provided == enable all options.
43+
*/
44+
45+
if (!str || strstr(str, "jump_label")) {
46+
opts.hack_jump_label = true;
47+
found = true;
48+
}
49+
50+
return found ? 0 : -1;
51+
}
52+
3453
const struct option check_options[] = {
3554
OPT_GROUP("Actions:"),
55+
OPT_CALLBACK_OPTARG('h', "hacks", NULL, NULL, "jump_label", "patch toolchain bugs/limitations", parse_hacks),
3656
OPT_BOOLEAN('i', "ibt", &opts.ibt, "validate and annotate IBT"),
3757
OPT_BOOLEAN('m', "mcount", &opts.mcount, "annotate mcount/fentry calls for ftrace"),
3858
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[])
87107

88108
static bool opts_valid(void)
89109
{
90-
if (opts.ibt ||
91-
opts.mcount ||
92-
opts.noinstr ||
93-
opts.orc ||
94-
opts.retpoline ||
95-
opts.sls ||
96-
opts.stackval ||
97-
opts.static_call ||
110+
if (opts.hack_jump_label ||
111+
opts.ibt ||
112+
opts.mcount ||
113+
opts.noinstr ||
114+
opts.orc ||
115+
opts.retpoline ||
116+
opts.sls ||
117+
opts.stackval ||
118+
opts.static_call ||
98119
opts.uaccess) {
99120
if (opts.dump_orc) {
100121
fprintf(stderr, "--dump can't be combined with other options\n");

tools/objtool/check.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1592,7 +1592,7 @@ static int handle_jump_alt(struct objtool_file *file,
15921592
return -1;
15931593
}
15941594

1595-
if (special_alt->key_addend & 2) {
1595+
if (opts.hack_jump_label && special_alt->key_addend & 2) {
15961596
struct reloc *reloc = insn_reloc(file, orig_insn);
15971597

15981598
if (reloc) {

tools/objtool/include/objtool/builtin.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ extern const struct option check_options[];
1212
struct opts {
1313
/* actions: */
1414
bool dump_orc;
15+
bool hack_jump_label;
1516
bool ibt;
1617
bool mcount;
1718
bool noinstr;

0 commit comments

Comments
 (0)