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

objtool: Abstract alternative special case handling

Some alternatives associated with a specific feature need to be treated
in a special way. Since the features and how to treat them vary from one
architecture to another, move the special case handling to arch specific
code.

Reviewed-by: Miroslav Benes <mbenes@suse.cz>
Signed-off-by: Julien Thierry <jthierry@redhat.com>
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>

authored by

Julien Thierry and committed by
Josh Poimboeuf
eda3dc90 c8ea0d67

+47 -29
+1
tools/objtool/arch/x86/Build
··· 1 + objtool-y += special.o 1 2 objtool-y += decode.o 2 3 3 4 inat_tables_script = ../arch/x86/tools/gen-insn-attr-x86.awk
+37
tools/objtool/arch/x86/special.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + #include "../../special.h" 3 + #include "../../builtin.h" 4 + 5 + #define X86_FEATURE_POPCNT (4 * 32 + 23) 6 + #define X86_FEATURE_SMAP (9 * 32 + 20) 7 + 8 + void arch_handle_alternative(unsigned short feature, struct special_alt *alt) 9 + { 10 + switch (feature) { 11 + case X86_FEATURE_SMAP: 12 + /* 13 + * If UACCESS validation is enabled; force that alternative; 14 + * otherwise force it the other way. 15 + * 16 + * What we want to avoid is having both the original and the 17 + * alternative code flow at the same time, in that case we can 18 + * find paths that see the STAC but take the NOP instead of 19 + * CLAC and the other way around. 20 + */ 21 + if (uaccess) 22 + alt->skip_orig = true; 23 + else 24 + alt->skip_alt = true; 25 + break; 26 + case X86_FEATURE_POPCNT: 27 + /* 28 + * It has been requested that we don't validate the !POPCNT 29 + * feature path which is a "very very small percentage of 30 + * machines". 31 + */ 32 + alt->skip_orig = true; 33 + break; 34 + default: 35 + break; 36 + } 37 + }
+2
tools/objtool/objtool.h
··· 12 12 13 13 #include "elf.h" 14 14 15 + #define __weak __attribute__((weak)) 16 + 15 17 struct objtool_file { 16 18 struct elf *elf; 17 19 struct list_head insn_list;
+5 -27
tools/objtool/special.c
··· 16 16 #include "warn.h" 17 17 #include "arch_special.h" 18 18 19 - #define X86_FEATURE_POPCNT (4*32+23) 20 - #define X86_FEATURE_SMAP (9*32+20) 21 - 22 19 struct special_entry { 23 20 const char *sec; 24 21 bool group, jump_or_nop; ··· 51 54 {}, 52 55 }; 53 56 57 + void __weak arch_handle_alternative(unsigned short feature, struct special_alt *alt) 58 + { 59 + } 60 + 54 61 static int get_alt_entry(struct elf *elf, struct special_entry *entry, 55 62 struct section *sec, int idx, 56 63 struct special_alt *alt) ··· 79 78 80 79 feature = *(unsigned short *)(sec->data->d_buf + offset + 81 80 entry->feature); 82 - 83 - /* 84 - * It has been requested that we don't validate the !POPCNT 85 - * feature path which is a "very very small percentage of 86 - * machines". 87 - */ 88 - if (feature == X86_FEATURE_POPCNT) 89 - alt->skip_orig = true; 90 - 91 - /* 92 - * If UACCESS validation is enabled; force that alternative; 93 - * otherwise force it the other way. 94 - * 95 - * What we want to avoid is having both the original and the 96 - * alternative code flow at the same time, in that case we can 97 - * find paths that see the STAC but take the NOP instead of 98 - * CLAC and the other way around. 99 - */ 100 - if (feature == X86_FEATURE_SMAP) { 101 - if (uaccess) 102 - alt->skip_orig = true; 103 - else 104 - alt->skip_alt = true; 105 - } 81 + arch_handle_alternative(feature, alt); 106 82 } 107 83 108 84 orig_reloc = find_reloc_by_dest(elf, sec, offset + entry->orig);
+2
tools/objtool/special.h
··· 28 28 29 29 int special_get_alts(struct elf *elf, struct list_head *alts); 30 30 31 + void arch_handle_alternative(unsigned short feature, struct special_alt *alt); 32 + 31 33 #endif /* _SPECIAL_H */
-2
tools/objtool/weak.c
··· 9 9 #include <errno.h> 10 10 #include "objtool.h" 11 11 12 - #define __weak __attribute__((weak)) 13 - 14 12 #define UNSUPPORTED(name) \ 15 13 ({ \ 16 14 fprintf(stderr, "error: objtool: " name " not implemented\n"); \