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

Merge tag 'x86_core_for_v5.13' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 updates from Borislav Petkov:

- Turn the stack canary into a normal __percpu variable on 32-bit which
gets rid of the LAZY_GS stuff and a lot of code.

- Add an insn_decode() API which all users of the instruction decoder
should preferrably use. Its goal is to keep the details of the
instruction decoder away from its users and simplify and streamline
how one decodes insns in the kernel. Convert its users to it.

- kprobes improvements and fixes

- Set the maximum DIE per package variable on Hygon

- Rip out the dynamic NOP selection and simplify all the machinery
around selecting NOPs. Use the simplified NOPs in objtool now too.

- Add Xeon Sapphire Rapids to list of CPUs that support PPIN

- Simplify the retpolines by folding the entire thing into an
alternative now that objtool can handle alternatives with stack ops.
Then, have objtool rewrite the call to the retpoline with the
alternative which then will get patched at boot time.

- Document Intel uarch per models in intel-family.h

- Make Sub-NUMA Clustering topology the default and Cluster-on-Die the
exception on Intel.

* tag 'x86_core_for_v5.13' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (53 commits)
x86, sched: Treat Intel SNC topology as default, COD as exception
x86/cpu: Comment Skylake server stepping too
x86/cpu: Resort and comment Intel models
objtool/x86: Rewrite retpoline thunk calls
objtool: Skip magical retpoline .altinstr_replacement
objtool: Cache instruction relocs
objtool: Keep track of retpoline call sites
objtool: Add elf_create_undef_symbol()
objtool: Extract elf_symbol_add()
objtool: Extract elf_strtab_concat()
objtool: Create reloc sections implicitly
objtool: Add elf_create_reloc() helper
objtool: Rework the elf_rebuild_reloc_section() logic
objtool: Fix static_call list generation
objtool: Handle per arch retpoline naming
objtool: Correctly handle retpoline thunk calls
x86/retpoline: Simplify retpolines
x86/alternatives: Optimize optimize_nops()
x86: Add insn_decode_kernel()
x86/kprobes: Move 'inline' to the beginning of the kprobe_is_ss() declaration
...

+1937 -1451
+2 -5
arch/x86/Kconfig
··· 361 361 def_bool y 362 362 depends on X86_64 && SMP 363 363 364 - config X86_32_LAZY_GS 365 - def_bool y 366 - depends on X86_32 && !STACKPROTECTOR 367 - 368 364 config ARCH_SUPPORTS_UPROBES 369 365 def_bool y 370 366 ··· 383 387 default $(success,$(srctree)/scripts/gcc-x86_32-has-stack-protector.sh $(CC)) 384 388 help 385 389 We have to make sure stack protector is unconditionally disabled if 386 - the compiler produces broken code. 390 + the compiler produces broken code or if it does not let us control 391 + the segment on 32-bit kernels. 387 392 388 393 menu "Processor type and features" 389 394
+8
arch/x86/Makefile
··· 80 80 81 81 # temporary until string.h is fixed 82 82 KBUILD_CFLAGS += -ffreestanding 83 + 84 + ifeq ($(CONFIG_STACKPROTECTOR),y) 85 + ifeq ($(CONFIG_SMP),y) 86 + KBUILD_CFLAGS += -mstack-protector-guard-reg=fs -mstack-protector-guard-symbol=__stack_chk_guard 87 + else 88 + KBUILD_CFLAGS += -mstack-protector-guard=global 89 + endif 90 + endif 83 91 else 84 92 BITS := 64 85 93 UTS_MACHINE := x86_64
+5 -6
arch/x86/boot/compressed/sev-es.c
··· 78 78 static enum es_result vc_decode_insn(struct es_em_ctxt *ctxt) 79 79 { 80 80 char buffer[MAX_INSN_SIZE]; 81 - enum es_result ret; 81 + int ret; 82 82 83 83 memcpy(buffer, (unsigned char *)ctxt->regs->ip, MAX_INSN_SIZE); 84 84 85 - insn_init(&ctxt->insn, buffer, MAX_INSN_SIZE, 1); 86 - insn_get_length(&ctxt->insn); 85 + ret = insn_decode(&ctxt->insn, buffer, MAX_INSN_SIZE, INSN_MODE_64); 86 + if (ret < 0) 87 + return ES_DECODE_FAILED; 87 88 88 - ret = ctxt->insn.immediate.got ? ES_OK : ES_DECODE_FAILED; 89 - 90 - return ret; 89 + return ES_OK; 91 90 } 92 91 93 92 static enum es_result vc_write_mem(struct es_em_ctxt *ctxt,
+4 -91
arch/x86/entry/entry_32.S
··· 20 20 * 1C(%esp) - %ds 21 21 * 20(%esp) - %es 22 22 * 24(%esp) - %fs 23 - * 28(%esp) - %gs saved iff !CONFIG_X86_32_LAZY_GS 23 + * 28(%esp) - unused -- was %gs on old stackprotector kernels 24 24 * 2C(%esp) - orig_eax 25 25 * 30(%esp) - %eip 26 26 * 34(%esp) - %cs ··· 52 52 .section .entry.text, "ax" 53 53 54 54 #define PTI_SWITCH_MASK (1 << PAGE_SHIFT) 55 - 56 - /* 57 - * User gs save/restore 58 - * 59 - * %gs is used for userland TLS and kernel only uses it for stack 60 - * canary which is required to be at %gs:20 by gcc. Read the comment 61 - * at the top of stackprotector.h for more info. 62 - * 63 - * Local labels 98 and 99 are used. 64 - */ 65 - #ifdef CONFIG_X86_32_LAZY_GS 66 - 67 - /* unfortunately push/pop can't be no-op */ 68 - .macro PUSH_GS 69 - pushl $0 70 - .endm 71 - .macro POP_GS pop=0 72 - addl $(4 + \pop), %esp 73 - .endm 74 - .macro POP_GS_EX 75 - .endm 76 - 77 - /* all the rest are no-op */ 78 - .macro PTGS_TO_GS 79 - .endm 80 - .macro PTGS_TO_GS_EX 81 - .endm 82 - .macro GS_TO_REG reg 83 - .endm 84 - .macro REG_TO_PTGS reg 85 - .endm 86 - .macro SET_KERNEL_GS reg 87 - .endm 88 - 89 - #else /* CONFIG_X86_32_LAZY_GS */ 90 - 91 - .macro PUSH_GS 92 - pushl %gs 93 - .endm 94 - 95 - .macro POP_GS pop=0 96 - 98: popl %gs 97 - .if \pop <> 0 98 - add $\pop, %esp 99 - .endif 100 - .endm 101 - .macro POP_GS_EX 102 - .pushsection .fixup, "ax" 103 - 99: movl $0, (%esp) 104 - jmp 98b 105 - .popsection 106 - _ASM_EXTABLE(98b, 99b) 107 - .endm 108 - 109 - .macro PTGS_TO_GS 110 - 98: mov PT_GS(%esp), %gs 111 - .endm 112 - .macro PTGS_TO_GS_EX 113 - .pushsection .fixup, "ax" 114 - 99: movl $0, PT_GS(%esp) 115 - jmp 98b 116 - .popsection 117 - _ASM_EXTABLE(98b, 99b) 118 - .endm 119 - 120 - .macro GS_TO_REG reg 121 - movl %gs, \reg 122 - .endm 123 - .macro REG_TO_PTGS reg 124 - movl \reg, PT_GS(%esp) 125 - .endm 126 - .macro SET_KERNEL_GS reg 127 - movl $(__KERNEL_STACK_CANARY), \reg 128 - movl \reg, %gs 129 - .endm 130 - 131 - #endif /* CONFIG_X86_32_LAZY_GS */ 132 55 133 56 /* Unconditionally switch to user cr3 */ 134 57 .macro SWITCH_TO_USER_CR3 scratch_reg:req ··· 205 282 .macro SAVE_ALL pt_regs_ax=%eax switch_stacks=0 skip_gs=0 unwind_espfix=0 206 283 cld 207 284 .if \skip_gs == 0 208 - PUSH_GS 285 + pushl $0 209 286 .endif 210 287 pushl %fs 211 288 ··· 230 307 movl $(__USER_DS), %edx 231 308 movl %edx, %ds 232 309 movl %edx, %es 233 - .if \skip_gs == 0 234 - SET_KERNEL_GS %edx 235 - .endif 236 310 /* Switch to kernel stack if necessary */ 237 311 .if \switch_stacks > 0 238 312 SWITCH_TO_KERNEL_STACK ··· 268 348 1: popl %ds 269 349 2: popl %es 270 350 3: popl %fs 271 - POP_GS \pop 351 + addl $(4 + \pop), %esp /* pop the unused "gs" slot */ 272 352 IRET_FRAME 273 353 .pushsection .fixup, "ax" 274 354 4: movl $0, (%esp) ··· 281 361 _ASM_EXTABLE(1b, 4b) 282 362 _ASM_EXTABLE(2b, 5b) 283 363 _ASM_EXTABLE(3b, 6b) 284 - POP_GS_EX 285 364 .endm 286 365 287 366 .macro RESTORE_ALL_NMI cr3_reg:req pop=0 ··· 698 779 699 780 #ifdef CONFIG_STACKPROTECTOR 700 781 movl TASK_stack_canary(%edx), %ebx 701 - movl %ebx, PER_CPU_VAR(stack_canary)+stack_canary_offset 782 + movl %ebx, PER_CPU_VAR(__stack_chk_guard) 702 783 #endif 703 784 704 785 #ifdef CONFIG_RETPOLINE ··· 895 976 movl PT_EIP(%esp), %edx /* pt_regs->ip */ 896 977 movl PT_OLDESP(%esp), %ecx /* pt_regs->sp */ 897 978 1: mov PT_FS(%esp), %fs 898 - PTGS_TO_GS 899 979 900 980 popl %ebx /* pt_regs->bx */ 901 981 addl $2*4, %esp /* skip pt_regs->cx and pt_regs->dx */ ··· 930 1012 jmp 1b 931 1013 .popsection 932 1014 _ASM_EXTABLE(1b, 2b) 933 - PTGS_TO_GS_EX 934 1015 935 1016 .Lsysenter_fix_flags: 936 1017 pushl $X86_EFLAGS_FIXED ··· 1071 1154 SAVE_ALL switch_stacks=1 skip_gs=1 unwind_espfix=1 1072 1155 ENCODE_FRAME_POINTER 1073 1156 1074 - /* fixup %gs */ 1075 - GS_TO_REG %ecx 1076 1157 movl PT_GS(%esp), %edi # get the function address 1077 - REG_TO_PTGS %ecx 1078 - SET_KERNEL_GS %ecx 1079 1158 1080 1159 /* fixup orig %eax */ 1081 1160 movl PT_ORIG_EAX(%esp), %edx # get the error code
+5 -6
arch/x86/events/intel/ds.c
··· 1353 1353 is_64bit = kernel_ip(to) || any_64bit_mode(regs); 1354 1354 #endif 1355 1355 insn_init(&insn, kaddr, size, is_64bit); 1356 - insn_get_length(&insn); 1356 + 1357 1357 /* 1358 - * Make sure there was not a problem decoding the 1359 - * instruction and getting the length. This is 1360 - * doubly important because we have an infinite 1361 - * loop if insn.length=0. 1358 + * Make sure there was not a problem decoding the instruction. 1359 + * This is doubly important because we have an infinite loop if 1360 + * insn.length=0. 1362 1361 */ 1363 - if (!insn.length) 1362 + if (insn_get_length(&insn)) 1364 1363 break; 1365 1364 1366 1365 to += insn.length;
+5 -5
arch/x86/events/intel/lbr.c
··· 1224 1224 is64 = kernel_ip((unsigned long)addr) || any_64bit_mode(current_pt_regs()); 1225 1225 #endif 1226 1226 insn_init(&insn, addr, bytes_read, is64); 1227 - insn_get_opcode(&insn); 1228 - if (!insn.opcode.got) 1227 + if (insn_get_opcode(&insn)) 1229 1228 return X86_BR_ABORT; 1230 1229 1231 1230 switch (insn.opcode.bytes[0]) { ··· 1261 1262 ret = X86_BR_INT; 1262 1263 break; 1263 1264 case 0xe8: /* call near rel */ 1264 - insn_get_immediate(&insn); 1265 - if (insn.immediate1.value == 0) { 1265 + if (insn_get_immediate(&insn) || insn.immediate1.value == 0) { 1266 1266 /* zero length call */ 1267 1267 ret = X86_BR_ZERO_CALL; 1268 1268 break; ··· 1277 1279 ret = X86_BR_JMP; 1278 1280 break; 1279 1281 case 0xff: /* call near absolute, call far absolute ind */ 1280 - insn_get_modrm(&insn); 1282 + if (insn_get_modrm(&insn)) 1283 + return X86_BR_ABORT; 1284 + 1281 1285 ext = (insn.modrm.bytes[0] >> 3) & 0x7; 1282 1286 switch (ext) { 1283 1287 case 2: /* near ind call */
+5 -12
arch/x86/include/asm/alternative.h
··· 65 65 u16 cpuid; /* cpuid bit set for replacement */ 66 66 u8 instrlen; /* length of original instruction */ 67 67 u8 replacementlen; /* length of new instruction */ 68 - u8 padlen; /* length of build-time padding */ 69 68 } __packed; 70 69 71 70 /* ··· 103 104 104 105 #define alt_end_marker "663" 105 106 #define alt_slen "662b-661b" 106 - #define alt_pad_len alt_end_marker"b-662b" 107 107 #define alt_total_slen alt_end_marker"b-661b" 108 108 #define alt_rlen(num) e_replacement(num)"f-"b_replacement(num)"f" 109 109 ··· 149 151 " .long " b_replacement(num)"f - .\n" /* new instruction */ \ 150 152 " .word " __stringify(feature) "\n" /* feature bit */ \ 151 153 " .byte " alt_total_slen "\n" /* source len */ \ 152 - " .byte " alt_rlen(num) "\n" /* replacement len */ \ 153 - " .byte " alt_pad_len "\n" /* pad len */ 154 + " .byte " alt_rlen(num) "\n" /* replacement len */ 154 155 155 156 #define ALTINSTR_REPLACEMENT(newinstr, num) /* replacement */ \ 156 157 "# ALT: replacement " #num "\n" \ ··· 221 224 * Peculiarities: 222 225 * No memory clobber here. 223 226 * Argument numbers start with 1. 224 - * Best is to use constraints that are fixed size (like (%1) ... "r") 225 - * If you use variable sized constraints like "m" or "g" in the 226 - * replacement make sure to pad to the worst case length. 227 227 * Leaving an unused argument 0 to keep API compatibility. 228 228 */ 229 229 #define alternative_input(oldinstr, newinstr, feature, input...) \ ··· 309 315 * enough information for the alternatives patching code to patch an 310 316 * instruction. See apply_alternatives(). 311 317 */ 312 - .macro altinstruction_entry orig alt feature orig_len alt_len pad_len 318 + .macro altinstruction_entry orig alt feature orig_len alt_len 313 319 .long \orig - . 314 320 .long \alt - . 315 321 .word \feature 316 322 .byte \orig_len 317 323 .byte \alt_len 318 - .byte \pad_len 319 324 .endm 320 325 321 326 /* ··· 331 338 142: 332 339 333 340 .pushsection .altinstructions,"a" 334 - altinstruction_entry 140b,143f,\feature,142b-140b,144f-143f,142b-141b 341 + altinstruction_entry 140b,143f,\feature,142b-140b,144f-143f 335 342 .popsection 336 343 337 344 .pushsection .altinstr_replacement,"ax" ··· 368 375 142: 369 376 370 377 .pushsection .altinstructions,"a" 371 - altinstruction_entry 140b,143f,\feature1,142b-140b,144f-143f,142b-141b 372 - altinstruction_entry 140b,144f,\feature2,142b-140b,145f-144f,142b-141b 378 + altinstruction_entry 140b,143f,\feature1,142b-140b,144f-143f 379 + altinstruction_entry 140b,144f,\feature2,142b-140b,145f-144f 373 380 .popsection 374 381 375 382 .pushsection .altinstr_replacement,"ax"
+9 -8
arch/x86/include/asm/asm-prototypes.h
··· 19 19 20 20 #ifdef CONFIG_RETPOLINE 21 21 22 - #define DECL_INDIRECT_THUNK(reg) \ 23 - extern asmlinkage void __x86_indirect_thunk_ ## reg (void); 24 - 25 - #define DECL_RETPOLINE(reg) \ 26 - extern asmlinkage void __x86_retpoline_ ## reg (void); 27 - 28 22 #undef GEN 29 - #define GEN(reg) DECL_INDIRECT_THUNK(reg) 23 + #define GEN(reg) \ 24 + extern asmlinkage void __x86_indirect_thunk_ ## reg (void); 30 25 #include <asm/GEN-for-each-reg.h> 31 26 32 27 #undef GEN 33 - #define GEN(reg) DECL_RETPOLINE(reg) 28 + #define GEN(reg) \ 29 + extern asmlinkage void __x86_indirect_alt_call_ ## reg (void); 30 + #include <asm/GEN-for-each-reg.h> 31 + 32 + #undef GEN 33 + #define GEN(reg) \ 34 + extern asmlinkage void __x86_indirect_alt_jmp_ ## reg (void); 34 35 #include <asm/GEN-for-each-reg.h> 35 36 36 37 #endif /* CONFIG_RETPOLINE */
+1 -1
arch/x86/include/asm/cpufeatures.h
··· 84 84 85 85 /* CPU types for specific tunings: */ 86 86 #define X86_FEATURE_K8 ( 3*32+ 4) /* "" Opteron, Athlon64 */ 87 - #define X86_FEATURE_K7 ( 3*32+ 5) /* "" Athlon */ 87 + /* FREE, was #define X86_FEATURE_K7 ( 3*32+ 5) "" Athlon */ 88 88 #define X86_FEATURE_P3 ( 3*32+ 6) /* "" P3 */ 89 89 #define X86_FEATURE_P4 ( 3*32+ 7) /* "" P4 */ 90 90 #define X86_FEATURE_CONSTANT_TSC ( 3*32+ 8) /* TSC ticks at a constant rate */
+1 -1
arch/x86/include/asm/inat.h
··· 6 6 * 7 7 * Written by Masami Hiramatsu <mhiramat@redhat.com> 8 8 */ 9 - #include <asm/inat_types.h> 9 + #include <asm/inat_types.h> /* __ignore_sync_check__ */ 10 10 11 11 /* 12 12 * Internal bits. Don't use bitmasks directly, because these bits are
+2 -2
arch/x86/include/asm/insn-eval.h
··· 25 25 unsigned char buf[MAX_INSN_SIZE]); 26 26 int insn_fetch_from_user_inatomic(struct pt_regs *regs, 27 27 unsigned char buf[MAX_INSN_SIZE]); 28 - bool insn_decode(struct insn *insn, struct pt_regs *regs, 29 - unsigned char buf[MAX_INSN_SIZE], int buf_size); 28 + bool insn_decode_from_regs(struct insn *insn, struct pt_regs *regs, 29 + unsigned char buf[MAX_INSN_SIZE], int buf_size); 30 30 31 31 #endif /* _ASM_X86_INSN_EVAL_H */
+20 -26
arch/x86/include/asm/insn.h
··· 9 9 10 10 #include <asm/byteorder.h> 11 11 /* insn_attr_t is defined in inat.h */ 12 - #include <asm/inat.h> 12 + #include <asm/inat.h> /* __ignore_sync_check__ */ 13 13 14 14 #if defined(__BYTE_ORDER) ? __BYTE_ORDER == __LITTLE_ENDIAN : defined(__LITTLE_ENDIAN) 15 15 ··· 132 132 #define X86_VEX_M_MAX 0x1f /* VEX3.M Maximum value */ 133 133 134 134 extern void insn_init(struct insn *insn, const void *kaddr, int buf_len, int x86_64); 135 - extern void insn_get_prefixes(struct insn *insn); 136 - extern void insn_get_opcode(struct insn *insn); 137 - extern void insn_get_modrm(struct insn *insn); 138 - extern void insn_get_sib(struct insn *insn); 139 - extern void insn_get_displacement(struct insn *insn); 140 - extern void insn_get_immediate(struct insn *insn); 141 - extern void insn_get_length(struct insn *insn); 135 + extern int insn_get_prefixes(struct insn *insn); 136 + extern int insn_get_opcode(struct insn *insn); 137 + extern int insn_get_modrm(struct insn *insn); 138 + extern int insn_get_sib(struct insn *insn); 139 + extern int insn_get_displacement(struct insn *insn); 140 + extern int insn_get_immediate(struct insn *insn); 141 + extern int insn_get_length(struct insn *insn); 142 + 143 + enum insn_mode { 144 + INSN_MODE_32, 145 + INSN_MODE_64, 146 + /* Mode is determined by the current kernel build. */ 147 + INSN_MODE_KERN, 148 + INSN_NUM_MODES, 149 + }; 150 + 151 + extern int insn_decode(struct insn *insn, const void *kaddr, int buf_len, enum insn_mode m); 152 + 153 + #define insn_decode_kernel(_insn, _ptr) insn_decode((_insn), (_ptr), MAX_INSN_SIZE, INSN_MODE_KERN) 142 154 143 155 /* Attribute will be determined after getting ModRM (for opcode groups) */ 144 156 static inline void insn_get_attribute(struct insn *insn) ··· 160 148 161 149 /* Instruction uses RIP-relative addressing */ 162 150 extern int insn_rip_relative(struct insn *insn); 163 - 164 - /* Init insn for kernel text */ 165 - static inline void kernel_insn_init(struct insn *insn, 166 - const void *kaddr, int buf_len) 167 - { 168 - #ifdef CONFIG_X86_64 169 - insn_init(insn, kaddr, buf_len, 1); 170 - #else /* CONFIG_X86_32 */ 171 - insn_init(insn, kaddr, buf_len, 0); 172 - #endif 173 - } 174 151 175 152 static inline int insn_is_avx(struct insn *insn) 176 153 { ··· 178 177 static inline int insn_has_emulate_prefix(struct insn *insn) 179 178 { 180 179 return !!insn->emulate_prefix_size; 181 - } 182 - 183 - /* Ensure this instruction is decoded completely */ 184 - static inline int insn_complete(struct insn *insn) 185 - { 186 - return insn->opcode.got && insn->modrm.got && insn->sib.got && 187 - insn->displacement.got && insn->immediate.got; 188 180 } 189 181 190 182 static inline insn_byte_t insn_vex_m_bits(struct insn *insn)
+30 -22
arch/x86/include/asm/intel-family.h
··· 32 32 * _EP - 2 socket server parts 33 33 * _EX - 4+ socket server parts 34 34 * 35 - * The #define line may optionally include a comment including platform names. 35 + * The #define line may optionally include a comment including platform or core 36 + * names. An exception is made for skylake/kabylake where steppings seem to have gotten 37 + * their own names :-( 36 38 */ 37 39 38 40 /* Wildcard match for FAM6 so X86_MATCH_INTEL_FAM6_MODEL(ANY) works */ ··· 71 69 #define INTEL_FAM6_BROADWELL_X 0x4F 72 70 #define INTEL_FAM6_BROADWELL_D 0x56 73 71 74 - #define INTEL_FAM6_SKYLAKE_L 0x4E 75 - #define INTEL_FAM6_SKYLAKE 0x5E 76 - #define INTEL_FAM6_SKYLAKE_X 0x55 77 - #define INTEL_FAM6_KABYLAKE_L 0x8E 78 - #define INTEL_FAM6_KABYLAKE 0x9E 72 + #define INTEL_FAM6_SKYLAKE_L 0x4E /* Sky Lake */ 73 + #define INTEL_FAM6_SKYLAKE 0x5E /* Sky Lake */ 74 + #define INTEL_FAM6_SKYLAKE_X 0x55 /* Sky Lake */ 75 + /* CASCADELAKE_X 0x55 Sky Lake -- s: 7 */ 76 + /* COOPERLAKE_X 0x55 Sky Lake -- s: 11 */ 79 77 80 - #define INTEL_FAM6_CANNONLAKE_L 0x66 78 + #define INTEL_FAM6_KABYLAKE_L 0x8E /* Sky Lake */ 79 + /* AMBERLAKE_L 0x8E Sky Lake -- s: 9 */ 80 + /* COFFEELAKE_L 0x8E Sky Lake -- s: 10 */ 81 + /* WHISKEYLAKE_L 0x8E Sky Lake -- s: 11,12 */ 81 82 82 - #define INTEL_FAM6_ICELAKE_X 0x6A 83 - #define INTEL_FAM6_ICELAKE_D 0x6C 84 - #define INTEL_FAM6_ICELAKE 0x7D 85 - #define INTEL_FAM6_ICELAKE_L 0x7E 86 - #define INTEL_FAM6_ICELAKE_NNPI 0x9D 83 + #define INTEL_FAM6_KABYLAKE 0x9E /* Sky Lake */ 84 + /* COFFEELAKE 0x9E Sky Lake -- s: 10-13 */ 87 85 88 - #define INTEL_FAM6_TIGERLAKE_L 0x8C 89 - #define INTEL_FAM6_TIGERLAKE 0x8D 86 + #define INTEL_FAM6_COMETLAKE 0xA5 /* Sky Lake */ 87 + #define INTEL_FAM6_COMETLAKE_L 0xA6 /* Sky Lake */ 90 88 91 - #define INTEL_FAM6_COMETLAKE 0xA5 92 - #define INTEL_FAM6_COMETLAKE_L 0xA6 89 + #define INTEL_FAM6_CANNONLAKE_L 0x66 /* Palm Cove */ 93 90 94 - #define INTEL_FAM6_ROCKETLAKE 0xA7 91 + #define INTEL_FAM6_ICELAKE_X 0x6A /* Sunny Cove */ 92 + #define INTEL_FAM6_ICELAKE_D 0x6C /* Sunny Cove */ 93 + #define INTEL_FAM6_ICELAKE 0x7D /* Sunny Cove */ 94 + #define INTEL_FAM6_ICELAKE_L 0x7E /* Sunny Cove */ 95 + #define INTEL_FAM6_ICELAKE_NNPI 0x9D /* Sunny Cove */ 95 96 96 - #define INTEL_FAM6_SAPPHIRERAPIDS_X 0x8F 97 + #define INTEL_FAM6_LAKEFIELD 0x8A /* Sunny Cove / Tremont */ 97 98 98 - /* Hybrid Core/Atom Processors */ 99 + #define INTEL_FAM6_ROCKETLAKE 0xA7 /* Cypress Cove */ 99 100 100 - #define INTEL_FAM6_LAKEFIELD 0x8A 101 - #define INTEL_FAM6_ALDERLAKE 0x97 102 - #define INTEL_FAM6_ALDERLAKE_L 0x9A 101 + #define INTEL_FAM6_TIGERLAKE_L 0x8C /* Willow Cove */ 102 + #define INTEL_FAM6_TIGERLAKE 0x8D /* Willow Cove */ 103 + #define INTEL_FAM6_SAPPHIRERAPIDS_X 0x8F /* Willow Cove */ 104 + 105 + #define INTEL_FAM6_ALDERLAKE 0x97 /* Golden Cove / Gracemont */ 106 + #define INTEL_FAM6_ALDERLAKE_L 0x9A /* Golden Cove / Gracemont */ 103 107 104 108 /* "Small Core" Processors (Atom) */ 105 109
+3 -9
arch/x86/include/asm/jump_label.h
··· 6 6 7 7 #define JUMP_LABEL_NOP_SIZE 5 8 8 9 - #ifdef CONFIG_X86_64 10 - # define STATIC_KEY_INIT_NOP P6_NOP5_ATOMIC 11 - #else 12 - # define STATIC_KEY_INIT_NOP GENERIC_NOP5_ATOMIC 13 - #endif 14 - 15 9 #include <asm/asm.h> 16 10 #include <asm/nops.h> 17 11 ··· 17 23 static __always_inline bool arch_static_branch(struct static_key *key, bool branch) 18 24 { 19 25 asm_volatile_goto("1:" 20 - ".byte " __stringify(STATIC_KEY_INIT_NOP) "\n\t" 26 + ".byte " __stringify(BYTES_NOP5) "\n\t" 21 27 ".pushsection __jump_table, \"aw\" \n\t" 22 28 _ASM_ALIGN "\n\t" 23 29 ".long 1b - ., %l[l_yes] - . \n\t" ··· 57 63 .long \target - .Lstatic_jump_after_\@ 58 64 .Lstatic_jump_after_\@: 59 65 .else 60 - .byte STATIC_KEY_INIT_NOP 66 + .byte BYTES_NOP5 61 67 .endif 62 68 .pushsection __jump_table, "aw" 63 69 _ASM_ALIGN ··· 69 75 .macro STATIC_JUMP_IF_FALSE target, key, def 70 76 .Lstatic_jump_\@: 71 77 .if \def 72 - .byte STATIC_KEY_INIT_NOP 78 + .byte BYTES_NOP5 73 79 .else 74 80 /* Equivalent to "jmp.d32 \target" */ 75 81 .byte 0xe9
+16 -5
arch/x86/include/asm/kprobes.h
··· 65 65 * a post_handler). 66 66 */ 67 67 unsigned boostable:1; 68 - unsigned if_modifier:1; 69 - unsigned is_call:1; 70 - unsigned is_pushf:1; 71 - unsigned is_abs_ip:1; 68 + unsigned char size; /* The size of insn */ 69 + union { 70 + unsigned char opcode; 71 + struct { 72 + unsigned char type; 73 + } jcc; 74 + struct { 75 + unsigned char type; 76 + unsigned char asize; 77 + } loop; 78 + struct { 79 + unsigned char reg; 80 + } indirect; 81 + }; 82 + s32 rel32; /* relative offset must be s32, s16, or s8 */ 83 + void (*emulate_op)(struct kprobe *p, struct pt_regs *regs); 72 84 /* Number of bytes of text poked */ 73 85 int tp_len; 74 86 }; ··· 119 107 extern int kprobe_exceptions_notify(struct notifier_block *self, 120 108 unsigned long val, void *data); 121 109 extern int kprobe_int3_handler(struct pt_regs *regs); 122 - extern int kprobe_debug_handler(struct pt_regs *regs); 123 110 124 111 #else 125 112
+55 -121
arch/x86/include/asm/nops.h
··· 4 4 5 5 /* 6 6 * Define nops for use with alternative() and for tracing. 7 - * 8 - * *_NOP5_ATOMIC must be a single instruction. 9 7 */ 10 8 11 - #define NOP_DS_PREFIX 0x3e 9 + #ifndef CONFIG_64BIT 12 10 13 - /* generic versions from gas 14 - 1: nop 15 - the following instructions are NOT nops in 64-bit mode, 16 - for 64-bit mode use K8 or P6 nops instead 17 - 2: movl %esi,%esi 18 - 3: leal 0x00(%esi),%esi 19 - 4: leal 0x00(,%esi,1),%esi 20 - 6: leal 0x00000000(%esi),%esi 21 - 7: leal 0x00000000(,%esi,1),%esi 22 - */ 23 - #define GENERIC_NOP1 0x90 24 - #define GENERIC_NOP2 0x89,0xf6 25 - #define GENERIC_NOP3 0x8d,0x76,0x00 26 - #define GENERIC_NOP4 0x8d,0x74,0x26,0x00 27 - #define GENERIC_NOP5 GENERIC_NOP1,GENERIC_NOP4 28 - #define GENERIC_NOP6 0x8d,0xb6,0x00,0x00,0x00,0x00 29 - #define GENERIC_NOP7 0x8d,0xb4,0x26,0x00,0x00,0x00,0x00 30 - #define GENERIC_NOP8 GENERIC_NOP1,GENERIC_NOP7 31 - #define GENERIC_NOP5_ATOMIC NOP_DS_PREFIX,GENERIC_NOP4 11 + /* 12 + * Generic 32bit nops from GAS: 13 + * 14 + * 1: nop 15 + * 2: movl %esi,%esi 16 + * 3: leal 0x0(%esi),%esi 17 + * 4: leal 0x0(%esi,%eiz,1),%esi 18 + * 5: leal %ds:0x0(%esi,%eiz,1),%esi 19 + * 6: leal 0x0(%esi),%esi 20 + * 7: leal 0x0(%esi,%eiz,1),%esi 21 + * 8: leal %ds:0x0(%esi,%eiz,1),%esi 22 + * 23 + * Except 5 and 8, which are DS prefixed 4 and 7 resp, where GAS would emit 2 24 + * nop instructions. 25 + */ 26 + #define BYTES_NOP1 0x90 27 + #define BYTES_NOP2 0x89,0xf6 28 + #define BYTES_NOP3 0x8d,0x76,0x00 29 + #define BYTES_NOP4 0x8d,0x74,0x26,0x00 30 + #define BYTES_NOP5 0x3e,BYTES_NOP4 31 + #define BYTES_NOP6 0x8d,0xb6,0x00,0x00,0x00,0x00 32 + #define BYTES_NOP7 0x8d,0xb4,0x26,0x00,0x00,0x00,0x00 33 + #define BYTES_NOP8 0x3e,BYTES_NOP7 32 34 33 - /* Opteron 64bit nops 34 - 1: nop 35 - 2: osp nop 36 - 3: osp osp nop 37 - 4: osp osp osp nop 38 - */ 39 - #define K8_NOP1 GENERIC_NOP1 40 - #define K8_NOP2 0x66,K8_NOP1 41 - #define K8_NOP3 0x66,K8_NOP2 42 - #define K8_NOP4 0x66,K8_NOP3 43 - #define K8_NOP5 K8_NOP3,K8_NOP2 44 - #define K8_NOP6 K8_NOP3,K8_NOP3 45 - #define K8_NOP7 K8_NOP4,K8_NOP3 46 - #define K8_NOP8 K8_NOP4,K8_NOP4 47 - #define K8_NOP5_ATOMIC 0x66,K8_NOP4 35 + #else 48 36 49 - /* K7 nops 50 - uses eax dependencies (arbitrary choice) 51 - 1: nop 52 - 2: movl %eax,%eax 53 - 3: leal (,%eax,1),%eax 54 - 4: leal 0x00(,%eax,1),%eax 55 - 6: leal 0x00000000(%eax),%eax 56 - 7: leal 0x00000000(,%eax,1),%eax 57 - */ 58 - #define K7_NOP1 GENERIC_NOP1 59 - #define K7_NOP2 0x8b,0xc0 60 - #define K7_NOP3 0x8d,0x04,0x20 61 - #define K7_NOP4 0x8d,0x44,0x20,0x00 62 - #define K7_NOP5 K7_NOP4,K7_NOP1 63 - #define K7_NOP6 0x8d,0x80,0,0,0,0 64 - #define K7_NOP7 0x8D,0x04,0x05,0,0,0,0 65 - #define K7_NOP8 K7_NOP7,K7_NOP1 66 - #define K7_NOP5_ATOMIC NOP_DS_PREFIX,K7_NOP4 37 + /* 38 + * Generic 64bit nops from GAS: 39 + * 40 + * 1: nop 41 + * 2: osp nop 42 + * 3: nopl (%eax) 43 + * 4: nopl 0x00(%eax) 44 + * 5: nopl 0x00(%eax,%eax,1) 45 + * 6: osp nopl 0x00(%eax,%eax,1) 46 + * 7: nopl 0x00000000(%eax) 47 + * 8: nopl 0x00000000(%eax,%eax,1) 48 + */ 49 + #define BYTES_NOP1 0x90 50 + #define BYTES_NOP2 0x66,BYTES_NOP1 51 + #define BYTES_NOP3 0x0f,0x1f,0x00 52 + #define BYTES_NOP4 0x0f,0x1f,0x40,0x00 53 + #define BYTES_NOP5 0x0f,0x1f,0x44,0x00,0x00 54 + #define BYTES_NOP6 0x66,BYTES_NOP5 55 + #define BYTES_NOP7 0x0f,0x1f,0x80,0x00,0x00,0x00,0x00 56 + #define BYTES_NOP8 0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00 67 57 68 - /* P6 nops 69 - uses eax dependencies (Intel-recommended choice) 70 - 1: nop 71 - 2: osp nop 72 - 3: nopl (%eax) 73 - 4: nopl 0x00(%eax) 74 - 5: nopl 0x00(%eax,%eax,1) 75 - 6: osp nopl 0x00(%eax,%eax,1) 76 - 7: nopl 0x00000000(%eax) 77 - 8: nopl 0x00000000(%eax,%eax,1) 78 - Note: All the above are assumed to be a single instruction. 79 - There is kernel code that depends on this. 80 - */ 81 - #define P6_NOP1 GENERIC_NOP1 82 - #define P6_NOP2 0x66,0x90 83 - #define P6_NOP3 0x0f,0x1f,0x00 84 - #define P6_NOP4 0x0f,0x1f,0x40,0 85 - #define P6_NOP5 0x0f,0x1f,0x44,0x00,0 86 - #define P6_NOP6 0x66,0x0f,0x1f,0x44,0x00,0 87 - #define P6_NOP7 0x0f,0x1f,0x80,0,0,0,0 88 - #define P6_NOP8 0x0f,0x1f,0x84,0x00,0,0,0,0 89 - #define P6_NOP5_ATOMIC P6_NOP5 58 + #endif /* CONFIG_64BIT */ 90 59 91 60 #ifdef __ASSEMBLY__ 92 61 #define _ASM_MK_NOP(x) .byte x ··· 63 94 #define _ASM_MK_NOP(x) ".byte " __stringify(x) "\n" 64 95 #endif 65 96 66 - #if defined(CONFIG_MK7) 67 - #define ASM_NOP1 _ASM_MK_NOP(K7_NOP1) 68 - #define ASM_NOP2 _ASM_MK_NOP(K7_NOP2) 69 - #define ASM_NOP3 _ASM_MK_NOP(K7_NOP3) 70 - #define ASM_NOP4 _ASM_MK_NOP(K7_NOP4) 71 - #define ASM_NOP5 _ASM_MK_NOP(K7_NOP5) 72 - #define ASM_NOP6 _ASM_MK_NOP(K7_NOP6) 73 - #define ASM_NOP7 _ASM_MK_NOP(K7_NOP7) 74 - #define ASM_NOP8 _ASM_MK_NOP(K7_NOP8) 75 - #define ASM_NOP5_ATOMIC _ASM_MK_NOP(K7_NOP5_ATOMIC) 76 - #elif defined(CONFIG_X86_P6_NOP) 77 - #define ASM_NOP1 _ASM_MK_NOP(P6_NOP1) 78 - #define ASM_NOP2 _ASM_MK_NOP(P6_NOP2) 79 - #define ASM_NOP3 _ASM_MK_NOP(P6_NOP3) 80 - #define ASM_NOP4 _ASM_MK_NOP(P6_NOP4) 81 - #define ASM_NOP5 _ASM_MK_NOP(P6_NOP5) 82 - #define ASM_NOP6 _ASM_MK_NOP(P6_NOP6) 83 - #define ASM_NOP7 _ASM_MK_NOP(P6_NOP7) 84 - #define ASM_NOP8 _ASM_MK_NOP(P6_NOP8) 85 - #define ASM_NOP5_ATOMIC _ASM_MK_NOP(P6_NOP5_ATOMIC) 86 - #elif defined(CONFIG_X86_64) 87 - #define ASM_NOP1 _ASM_MK_NOP(K8_NOP1) 88 - #define ASM_NOP2 _ASM_MK_NOP(K8_NOP2) 89 - #define ASM_NOP3 _ASM_MK_NOP(K8_NOP3) 90 - #define ASM_NOP4 _ASM_MK_NOP(K8_NOP4) 91 - #define ASM_NOP5 _ASM_MK_NOP(K8_NOP5) 92 - #define ASM_NOP6 _ASM_MK_NOP(K8_NOP6) 93 - #define ASM_NOP7 _ASM_MK_NOP(K8_NOP7) 94 - #define ASM_NOP8 _ASM_MK_NOP(K8_NOP8) 95 - #define ASM_NOP5_ATOMIC _ASM_MK_NOP(K8_NOP5_ATOMIC) 96 - #else 97 - #define ASM_NOP1 _ASM_MK_NOP(GENERIC_NOP1) 98 - #define ASM_NOP2 _ASM_MK_NOP(GENERIC_NOP2) 99 - #define ASM_NOP3 _ASM_MK_NOP(GENERIC_NOP3) 100 - #define ASM_NOP4 _ASM_MK_NOP(GENERIC_NOP4) 101 - #define ASM_NOP5 _ASM_MK_NOP(GENERIC_NOP5) 102 - #define ASM_NOP6 _ASM_MK_NOP(GENERIC_NOP6) 103 - #define ASM_NOP7 _ASM_MK_NOP(GENERIC_NOP7) 104 - #define ASM_NOP8 _ASM_MK_NOP(GENERIC_NOP8) 105 - #define ASM_NOP5_ATOMIC _ASM_MK_NOP(GENERIC_NOP5_ATOMIC) 106 - #endif 97 + #define ASM_NOP1 _ASM_MK_NOP(BYTES_NOP1) 98 + #define ASM_NOP2 _ASM_MK_NOP(BYTES_NOP2) 99 + #define ASM_NOP3 _ASM_MK_NOP(BYTES_NOP3) 100 + #define ASM_NOP4 _ASM_MK_NOP(BYTES_NOP4) 101 + #define ASM_NOP5 _ASM_MK_NOP(BYTES_NOP5) 102 + #define ASM_NOP6 _ASM_MK_NOP(BYTES_NOP6) 103 + #define ASM_NOP7 _ASM_MK_NOP(BYTES_NOP7) 104 + #define ASM_NOP8 _ASM_MK_NOP(BYTES_NOP8) 107 105 108 106 #define ASM_NOP_MAX 8 109 - #define NOP_ATOMIC5 (ASM_NOP_MAX+1) /* Entry for the 5-byte atomic NOP */ 110 107 111 108 #ifndef __ASSEMBLY__ 112 - extern const unsigned char * const *ideal_nops; 113 - extern void arch_init_ideal_nops(void); 109 + extern const unsigned char * const x86_nops[]; 114 110 #endif 115 111 116 112 #endif /* _ASM_X86_NOPS_H */
+3 -3
arch/x86/include/asm/nospec-branch.h
··· 80 80 .macro JMP_NOSPEC reg:req 81 81 #ifdef CONFIG_RETPOLINE 82 82 ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; jmp *%\reg), \ 83 - __stringify(jmp __x86_retpoline_\reg), X86_FEATURE_RETPOLINE, \ 83 + __stringify(jmp __x86_indirect_thunk_\reg), X86_FEATURE_RETPOLINE, \ 84 84 __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; jmp *%\reg), X86_FEATURE_RETPOLINE_AMD 85 85 #else 86 86 jmp *%\reg ··· 90 90 .macro CALL_NOSPEC reg:req 91 91 #ifdef CONFIG_RETPOLINE 92 92 ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; call *%\reg), \ 93 - __stringify(call __x86_retpoline_\reg), X86_FEATURE_RETPOLINE, \ 93 + __stringify(call __x86_indirect_thunk_\reg), X86_FEATURE_RETPOLINE, \ 94 94 __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; call *%\reg), X86_FEATURE_RETPOLINE_AMD 95 95 #else 96 96 call *%\reg ··· 128 128 ALTERNATIVE_2( \ 129 129 ANNOTATE_RETPOLINE_SAFE \ 130 130 "call *%[thunk_target]\n", \ 131 - "call __x86_retpoline_%V[thunk_target]\n", \ 131 + "call __x86_indirect_thunk_%V[thunk_target]\n", \ 132 132 X86_FEATURE_RETPOLINE, \ 133 133 "lfence;\n" \ 134 134 ANNOTATE_RETPOLINE_SAFE \
+4 -11
arch/x86/include/asm/processor.h
··· 429 429 * GCC hardcodes the stack canary as %gs:40. Since the 430 430 * irq_stack is the object at %gs:0, we reserve the bottom 431 431 * 48 bytes of the irq stack for the canary. 432 + * 433 + * Once we are willing to require -mstack-protector-guard-symbol= 434 + * support for x86_64 stackprotector, we can get rid of this. 432 435 */ 433 436 char gs_base[40]; 434 437 unsigned long stack_canary; ··· 453 450 void current_save_fsgs(void); 454 451 #else /* X86_64 */ 455 452 #ifdef CONFIG_STACKPROTECTOR 456 - /* 457 - * Make sure stack canary segment base is cached-aligned: 458 - * "For Intel Atom processors, avoid non zero segment base address 459 - * that is not aligned to cache line boundary at all cost." 460 - * (Optim Ref Manual Assembly/Compiler Coding Rule 15.) 461 - */ 462 - struct stack_canary { 463 - char __pad[20]; /* canary at %gs:20 */ 464 - unsigned long canary; 465 - }; 466 - DECLARE_PER_CPU_ALIGNED(struct stack_canary, stack_canary); 453 + DECLARE_PER_CPU(unsigned long, __stack_chk_guard); 467 454 #endif 468 455 DECLARE_PER_CPU(struct irq_stack *, hardirq_stack_ptr); 469 456 DECLARE_PER_CPU(struct irq_stack *, softirq_stack_ptr);
+4 -1
arch/x86/include/asm/ptrace.h
··· 37 37 unsigned short __esh; 38 38 unsigned short fs; 39 39 unsigned short __fsh; 40 - /* On interrupt, gs and __gsh store the vector number. */ 40 + /* 41 + * On interrupt, gs and __gsh store the vector number. They never 42 + * store gs any more. 43 + */ 41 44 unsigned short gs; 42 45 unsigned short __gsh; 43 46 /* On interrupt, this is the error code. */
+8 -22
arch/x86/include/asm/segment.h
··· 95 95 * 96 96 * 26 - ESPFIX small SS 97 97 * 27 - per-cpu [ offset to per-cpu data area ] 98 - * 28 - stack_canary-20 [ for stack protector ] <=== cacheline #8 98 + * 28 - unused 99 99 * 29 - unused 100 100 * 30 - unused 101 101 * 31 - TSS for double fault handler ··· 118 118 119 119 #define GDT_ENTRY_ESPFIX_SS 26 120 120 #define GDT_ENTRY_PERCPU 27 121 - #define GDT_ENTRY_STACK_CANARY 28 122 121 123 122 #define GDT_ENTRY_DOUBLEFAULT_TSS 31 124 123 ··· 155 156 # define __KERNEL_PERCPU (GDT_ENTRY_PERCPU*8) 156 157 #else 157 158 # define __KERNEL_PERCPU 0 158 - #endif 159 - 160 - #ifdef CONFIG_STACKPROTECTOR 161 - # define __KERNEL_STACK_CANARY (GDT_ENTRY_STACK_CANARY*8) 162 - #else 163 - # define __KERNEL_STACK_CANARY 0 164 159 #endif 165 160 166 161 #else /* 64-bit: */ ··· 357 364 asm("mov %%" #seg ",%0":"=r" (value) : : "memory") 358 365 359 366 /* 360 - * x86-32 user GS accessors: 367 + * x86-32 user GS accessors. This is ugly and could do with some cleaning up. 361 368 */ 362 369 #ifdef CONFIG_X86_32 363 - # ifdef CONFIG_X86_32_LAZY_GS 364 - # define get_user_gs(regs) (u16)({ unsigned long v; savesegment(gs, v); v; }) 365 - # define set_user_gs(regs, v) loadsegment(gs, (unsigned long)(v)) 366 - # define task_user_gs(tsk) ((tsk)->thread.gs) 367 - # define lazy_save_gs(v) savesegment(gs, (v)) 368 - # define lazy_load_gs(v) loadsegment(gs, (v)) 369 - # else /* X86_32_LAZY_GS */ 370 - # define get_user_gs(regs) (u16)((regs)->gs) 371 - # define set_user_gs(regs, v) do { (regs)->gs = (v); } while (0) 372 - # define task_user_gs(tsk) (task_pt_regs(tsk)->gs) 373 - # define lazy_save_gs(v) do { } while (0) 374 - # define lazy_load_gs(v) do { } while (0) 375 - # endif /* X86_32_LAZY_GS */ 370 + # define get_user_gs(regs) (u16)({ unsigned long v; savesegment(gs, v); v; }) 371 + # define set_user_gs(regs, v) loadsegment(gs, (unsigned long)(v)) 372 + # define task_user_gs(tsk) ((tsk)->thread.gs) 373 + # define lazy_save_gs(v) savesegment(gs, (v)) 374 + # define lazy_load_gs(v) loadsegment(gs, (v)) 375 + # define load_gs_index(v) loadsegment(gs, (v)) 376 376 #endif /* X86_32 */ 377 377 378 378 #endif /* !__ASSEMBLY__ */
+2 -2
arch/x86/include/asm/special_insns.h
··· 214 214 215 215 static inline void clflushopt(volatile void *__p) 216 216 { 217 - alternative_io(".byte " __stringify(NOP_DS_PREFIX) "; clflush %P0", 217 + alternative_io(".byte 0x3e; clflush %P0", 218 218 ".byte 0x66; clflush %P0", 219 219 X86_FEATURE_CLFLUSHOPT, 220 220 "+m" (*(volatile char __force *)__p)); ··· 225 225 volatile struct { char x[64]; } *p = __p; 226 226 227 227 asm volatile(ALTERNATIVE_2( 228 - ".byte " __stringify(NOP_DS_PREFIX) "; clflush (%[pax])", 228 + ".byte 0x3e; clflush (%[pax])", 229 229 ".byte 0x66; clflush (%[pax])", /* clflushopt (%%rax) */ 230 230 X86_FEATURE_CLFLUSHOPT, 231 231 ".byte 0x66, 0x0f, 0xae, 0x30", /* clwb (%%rax) */
+16 -63
arch/x86/include/asm/stackprotector.h
··· 5 5 * Stack protector works by putting predefined pattern at the start of 6 6 * the stack frame and verifying that it hasn't been overwritten when 7 7 * returning from the function. The pattern is called stack canary 8 - * and unfortunately gcc requires it to be at a fixed offset from %gs. 9 - * On x86_64, the offset is 40 bytes and on x86_32 20 bytes. x86_64 10 - * and x86_32 use segment registers differently and thus handles this 11 - * requirement differently. 8 + * and unfortunately gcc historically required it to be at a fixed offset 9 + * from the percpu segment base. On x86_64, the offset is 40 bytes. 12 10 * 13 - * On x86_64, %gs is shared by percpu area and stack canary. All 14 - * percpu symbols are zero based and %gs points to the base of percpu 15 - * area. The first occupant of the percpu area is always 16 - * fixed_percpu_data which contains stack_canary at offset 40. Userland 17 - * %gs is always saved and restored on kernel entry and exit using 18 - * swapgs, so stack protector doesn't add any complexity there. 11 + * The same segment is shared by percpu area and stack canary. On 12 + * x86_64, percpu symbols are zero based and %gs (64-bit) points to the 13 + * base of percpu area. The first occupant of the percpu area is always 14 + * fixed_percpu_data which contains stack_canary at the approproate 15 + * offset. On x86_32, the stack canary is just a regular percpu 16 + * variable. 19 17 * 20 - * On x86_32, it's slightly more complicated. As in x86_64, %gs is 21 - * used for userland TLS. Unfortunately, some processors are much 22 - * slower at loading segment registers with different value when 23 - * entering and leaving the kernel, so the kernel uses %fs for percpu 24 - * area and manages %gs lazily so that %gs is switched only when 25 - * necessary, usually during task switch. 18 + * Putting percpu data in %fs on 32-bit is a minor optimization compared to 19 + * using %gs. Since 32-bit userspace normally has %fs == 0, we are likely 20 + * to load 0 into %fs on exit to usermode, whereas with percpu data in 21 + * %gs, we are likely to load a non-null %gs on return to user mode. 26 22 * 27 - * As gcc requires the stack canary at %gs:20, %gs can't be managed 28 - * lazily if stack protector is enabled, so the kernel saves and 29 - * restores userland %gs on kernel entry and exit. This behavior is 30 - * controlled by CONFIG_X86_32_LAZY_GS and accessors are defined in 31 - * system.h to hide the details. 23 + * Once we are willing to require GCC 8.1 or better for 64-bit stackprotector 24 + * support, we can remove some of this complexity. 32 25 */ 33 26 34 27 #ifndef _ASM_STACKPROTECTOR_H ··· 36 43 37 44 #include <linux/random.h> 38 45 #include <linux/sched.h> 39 - 40 - /* 41 - * 24 byte read-only segment initializer for stack canary. Linker 42 - * can't handle the address bit shifting. Address will be set in 43 - * head_32 for boot CPU and setup_per_cpu_areas() for others. 44 - */ 45 - #define GDT_STACK_CANARY_INIT \ 46 - [GDT_ENTRY_STACK_CANARY] = GDT_ENTRY_INIT(0x4090, 0, 0x18), 47 46 48 47 /* 49 48 * Initialize the stackprotector canary value. ··· 71 86 #ifdef CONFIG_X86_64 72 87 this_cpu_write(fixed_percpu_data.stack_canary, canary); 73 88 #else 74 - this_cpu_write(stack_canary.canary, canary); 89 + this_cpu_write(__stack_chk_guard, canary); 75 90 #endif 76 91 } 77 92 ··· 80 95 #ifdef CONFIG_X86_64 81 96 per_cpu(fixed_percpu_data.stack_canary, cpu) = idle->stack_canary; 82 97 #else 83 - per_cpu(stack_canary.canary, cpu) = idle->stack_canary; 84 - #endif 85 - } 86 - 87 - static inline void setup_stack_canary_segment(int cpu) 88 - { 89 - #ifdef CONFIG_X86_32 90 - unsigned long canary = (unsigned long)&per_cpu(stack_canary, cpu); 91 - struct desc_struct *gdt_table = get_cpu_gdt_rw(cpu); 92 - struct desc_struct desc; 93 - 94 - desc = gdt_table[GDT_ENTRY_STACK_CANARY]; 95 - set_desc_base(&desc, canary); 96 - write_gdt_entry(gdt_table, GDT_ENTRY_STACK_CANARY, &desc, DESCTYPE_S); 97 - #endif 98 - } 99 - 100 - static inline void load_stack_canary_segment(void) 101 - { 102 - #ifdef CONFIG_X86_32 103 - asm("mov %0, %%gs" : : "r" (__KERNEL_STACK_CANARY) : "memory"); 98 + per_cpu(__stack_chk_guard, cpu) = idle->stack_canary; 104 99 #endif 105 100 } 106 101 107 102 #else /* STACKPROTECTOR */ 108 103 109 - #define GDT_STACK_CANARY_INIT 110 - 111 104 /* dummy boot_init_stack_canary() is defined in linux/stackprotector.h */ 112 - 113 - static inline void setup_stack_canary_segment(int cpu) 114 - { } 115 105 116 106 static inline void cpu_init_stack_canary(int cpu, struct task_struct *idle) 117 107 { } 118 - 119 - static inline void load_stack_canary_segment(void) 120 - { 121 - #ifdef CONFIG_X86_32 122 - asm volatile ("mov %0, %%gs" : : "r" (0)); 123 - #endif 124 - } 125 108 126 109 #endif /* STACKPROTECTOR */ 127 110 #endif /* _ASM_STACKPROTECTOR_H */
+2 -4
arch/x86/include/asm/suspend_32.h
··· 13 13 /* image of the saved processor state */ 14 14 struct saved_context { 15 15 /* 16 - * On x86_32, all segment registers, with the possible exception of 17 - * gs, are saved at kernel entry in pt_regs. 16 + * On x86_32, all segment registers except gs are saved at kernel 17 + * entry in pt_regs. 18 18 */ 19 - #ifdef CONFIG_X86_32_LAZY_GS 20 19 u16 gs; 21 - #endif 22 20 unsigned long cr0, cr2, cr3, cr4; 23 21 u64 misc_enable; 24 22 bool misc_enable_saved;
+56 -199
arch/x86/kernel/alternative.c
··· 75 75 } \ 76 76 } while (0) 77 77 78 - /* 79 - * Each GENERIC_NOPX is of X bytes, and defined as an array of bytes 80 - * that correspond to that nop. Getting from one nop to the next, we 81 - * add to the array the offset that is equal to the sum of all sizes of 82 - * nops preceding the one we are after. 83 - * 84 - * Note: The GENERIC_NOP5_ATOMIC is at the end, as it breaks the 85 - * nice symmetry of sizes of the previous nops. 86 - */ 87 - #if defined(GENERIC_NOP1) && !defined(CONFIG_X86_64) 88 - static const unsigned char intelnops[] = 78 + const unsigned char x86nops[] = 89 79 { 90 - GENERIC_NOP1, 91 - GENERIC_NOP2, 92 - GENERIC_NOP3, 93 - GENERIC_NOP4, 94 - GENERIC_NOP5, 95 - GENERIC_NOP6, 96 - GENERIC_NOP7, 97 - GENERIC_NOP8, 98 - GENERIC_NOP5_ATOMIC 80 + BYTES_NOP1, 81 + BYTES_NOP2, 82 + BYTES_NOP3, 83 + BYTES_NOP4, 84 + BYTES_NOP5, 85 + BYTES_NOP6, 86 + BYTES_NOP7, 87 + BYTES_NOP8, 99 88 }; 100 - static const unsigned char * const intel_nops[ASM_NOP_MAX+2] = 89 + 90 + const unsigned char * const x86_nops[ASM_NOP_MAX+1] = 101 91 { 102 92 NULL, 103 - intelnops, 104 - intelnops + 1, 105 - intelnops + 1 + 2, 106 - intelnops + 1 + 2 + 3, 107 - intelnops + 1 + 2 + 3 + 4, 108 - intelnops + 1 + 2 + 3 + 4 + 5, 109 - intelnops + 1 + 2 + 3 + 4 + 5 + 6, 110 - intelnops + 1 + 2 + 3 + 4 + 5 + 6 + 7, 111 - intelnops + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8, 93 + x86nops, 94 + x86nops + 1, 95 + x86nops + 1 + 2, 96 + x86nops + 1 + 2 + 3, 97 + x86nops + 1 + 2 + 3 + 4, 98 + x86nops + 1 + 2 + 3 + 4 + 5, 99 + x86nops + 1 + 2 + 3 + 4 + 5 + 6, 100 + x86nops + 1 + 2 + 3 + 4 + 5 + 6 + 7, 112 101 }; 113 - #endif 114 - 115 - #ifdef K8_NOP1 116 - static const unsigned char k8nops[] = 117 - { 118 - K8_NOP1, 119 - K8_NOP2, 120 - K8_NOP3, 121 - K8_NOP4, 122 - K8_NOP5, 123 - K8_NOP6, 124 - K8_NOP7, 125 - K8_NOP8, 126 - K8_NOP5_ATOMIC 127 - }; 128 - static const unsigned char * const k8_nops[ASM_NOP_MAX+2] = 129 - { 130 - NULL, 131 - k8nops, 132 - k8nops + 1, 133 - k8nops + 1 + 2, 134 - k8nops + 1 + 2 + 3, 135 - k8nops + 1 + 2 + 3 + 4, 136 - k8nops + 1 + 2 + 3 + 4 + 5, 137 - k8nops + 1 + 2 + 3 + 4 + 5 + 6, 138 - k8nops + 1 + 2 + 3 + 4 + 5 + 6 + 7, 139 - k8nops + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8, 140 - }; 141 - #endif 142 - 143 - #if defined(K7_NOP1) && !defined(CONFIG_X86_64) 144 - static const unsigned char k7nops[] = 145 - { 146 - K7_NOP1, 147 - K7_NOP2, 148 - K7_NOP3, 149 - K7_NOP4, 150 - K7_NOP5, 151 - K7_NOP6, 152 - K7_NOP7, 153 - K7_NOP8, 154 - K7_NOP5_ATOMIC 155 - }; 156 - static const unsigned char * const k7_nops[ASM_NOP_MAX+2] = 157 - { 158 - NULL, 159 - k7nops, 160 - k7nops + 1, 161 - k7nops + 1 + 2, 162 - k7nops + 1 + 2 + 3, 163 - k7nops + 1 + 2 + 3 + 4, 164 - k7nops + 1 + 2 + 3 + 4 + 5, 165 - k7nops + 1 + 2 + 3 + 4 + 5 + 6, 166 - k7nops + 1 + 2 + 3 + 4 + 5 + 6 + 7, 167 - k7nops + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8, 168 - }; 169 - #endif 170 - 171 - #ifdef P6_NOP1 172 - static const unsigned char p6nops[] = 173 - { 174 - P6_NOP1, 175 - P6_NOP2, 176 - P6_NOP3, 177 - P6_NOP4, 178 - P6_NOP5, 179 - P6_NOP6, 180 - P6_NOP7, 181 - P6_NOP8, 182 - P6_NOP5_ATOMIC 183 - }; 184 - static const unsigned char * const p6_nops[ASM_NOP_MAX+2] = 185 - { 186 - NULL, 187 - p6nops, 188 - p6nops + 1, 189 - p6nops + 1 + 2, 190 - p6nops + 1 + 2 + 3, 191 - p6nops + 1 + 2 + 3 + 4, 192 - p6nops + 1 + 2 + 3 + 4 + 5, 193 - p6nops + 1 + 2 + 3 + 4 + 5 + 6, 194 - p6nops + 1 + 2 + 3 + 4 + 5 + 6 + 7, 195 - p6nops + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8, 196 - }; 197 - #endif 198 - 199 - /* Initialize these to a safe default */ 200 - #ifdef CONFIG_X86_64 201 - const unsigned char * const *ideal_nops = p6_nops; 202 - #else 203 - const unsigned char * const *ideal_nops = intel_nops; 204 - #endif 205 - 206 - void __init arch_init_ideal_nops(void) 207 - { 208 - switch (boot_cpu_data.x86_vendor) { 209 - case X86_VENDOR_INTEL: 210 - /* 211 - * Due to a decoder implementation quirk, some 212 - * specific Intel CPUs actually perform better with 213 - * the "k8_nops" than with the SDM-recommended NOPs. 214 - */ 215 - if (boot_cpu_data.x86 == 6 && 216 - boot_cpu_data.x86_model >= 0x0f && 217 - boot_cpu_data.x86_model != 0x1c && 218 - boot_cpu_data.x86_model != 0x26 && 219 - boot_cpu_data.x86_model != 0x27 && 220 - boot_cpu_data.x86_model < 0x30) { 221 - ideal_nops = k8_nops; 222 - } else if (boot_cpu_has(X86_FEATURE_NOPL)) { 223 - ideal_nops = p6_nops; 224 - } else { 225 - #ifdef CONFIG_X86_64 226 - ideal_nops = k8_nops; 227 - #else 228 - ideal_nops = intel_nops; 229 - #endif 230 - } 231 - break; 232 - 233 - case X86_VENDOR_HYGON: 234 - ideal_nops = p6_nops; 235 - return; 236 - 237 - case X86_VENDOR_AMD: 238 - if (boot_cpu_data.x86 > 0xf) { 239 - ideal_nops = p6_nops; 240 - return; 241 - } 242 - 243 - fallthrough; 244 - 245 - default: 246 - #ifdef CONFIG_X86_64 247 - ideal_nops = k8_nops; 248 - #else 249 - if (boot_cpu_has(X86_FEATURE_K8)) 250 - ideal_nops = k8_nops; 251 - else if (boot_cpu_has(X86_FEATURE_K7)) 252 - ideal_nops = k7_nops; 253 - else 254 - ideal_nops = intel_nops; 255 - #endif 256 - } 257 - } 258 102 259 103 /* Use this to add nops to a buffer, then text_poke the whole buffer. */ 260 104 static void __init_or_module add_nops(void *insns, unsigned int len) ··· 107 263 unsigned int noplen = len; 108 264 if (noplen > ASM_NOP_MAX) 109 265 noplen = ASM_NOP_MAX; 110 - memcpy(insns, ideal_nops[noplen], noplen); 266 + memcpy(insns, x86_nops[noplen], noplen); 111 267 insns += noplen; 112 268 len -= noplen; 113 269 } ··· 189 345 static void __init_or_module noinline optimize_nops(struct alt_instr *a, u8 *instr) 190 346 { 191 347 unsigned long flags; 192 - int i; 348 + struct insn insn; 349 + int nop, i = 0; 193 350 194 - for (i = 0; i < a->padlen; i++) { 195 - if (instr[i] != 0x90) 351 + /* 352 + * Jump over the non-NOP insns, the remaining bytes must be single-byte 353 + * NOPs, optimize them. 354 + */ 355 + for (;;) { 356 + if (insn_decode_kernel(&insn, &instr[i])) 357 + return; 358 + 359 + if (insn.length == 1 && insn.opcode.bytes[0] == 0x90) 360 + break; 361 + 362 + if ((i += insn.length) >= a->instrlen) 363 + return; 364 + } 365 + 366 + for (nop = i; i < a->instrlen; i++) { 367 + if (WARN_ONCE(instr[i] != 0x90, "Not a NOP at 0x%px\n", &instr[i])) 196 368 return; 197 369 } 198 370 199 371 local_irq_save(flags); 200 - add_nops(instr + (a->instrlen - a->padlen), a->padlen); 372 + add_nops(instr + nop, i - nop); 201 373 local_irq_restore(flags); 202 374 203 375 DUMP_BYTES(instr, a->instrlen, "%px: [%d:%d) optimized NOPs: ", 204 - instr, a->instrlen - a->padlen, a->padlen); 376 + instr, nop, a->instrlen); 205 377 } 206 378 207 379 /* ··· 263 403 * - feature not present but ALTINSTR_FLAG_INV is set to mean, 264 404 * patch if feature is *NOT* present. 265 405 */ 266 - if (!boot_cpu_has(feature) == !(a->cpuid & ALTINSTR_FLAG_INV)) { 267 - if (a->padlen > 1) 268 - optimize_nops(a, instr); 406 + if (!boot_cpu_has(feature) == !(a->cpuid & ALTINSTR_FLAG_INV)) 407 + goto next; 269 408 270 - continue; 271 - } 272 - 273 - DPRINTK("feat: %s%d*32+%d, old: (%pS (%px) len: %d), repl: (%px, len: %d), pad: %d", 409 + DPRINTK("feat: %s%d*32+%d, old: (%pS (%px) len: %d), repl: (%px, len: %d)", 274 410 (a->cpuid & ALTINSTR_FLAG_INV) ? "!" : "", 275 411 feature >> 5, 276 412 feature & 0x1f, 277 413 instr, instr, a->instrlen, 278 - replacement, a->replacementlen, a->padlen); 414 + replacement, a->replacementlen); 279 415 280 416 DUMP_BYTES(instr, a->instrlen, "%px: old_insn: ", instr); 281 417 DUMP_BYTES(replacement, a->replacementlen, "%px: rpl_insn: ", replacement); ··· 295 439 if (a->replacementlen && is_jmp(replacement[0])) 296 440 recompute_jump(a, instr, replacement, insn_buff); 297 441 298 - if (a->instrlen > a->replacementlen) { 299 - add_nops(insn_buff + a->replacementlen, 300 - a->instrlen - a->replacementlen); 301 - insn_buff_sz += a->instrlen - a->replacementlen; 302 - } 442 + for (; insn_buff_sz < a->instrlen; insn_buff_sz++) 443 + insn_buff[insn_buff_sz] = 0x90; 444 + 303 445 DUMP_BYTES(insn_buff, insn_buff_sz, "%px: final_insn: ", instr); 304 446 305 447 text_poke_early(instr, insn_buff, insn_buff_sz); 448 + 449 + next: 450 + optimize_nops(a, instr); 306 451 } 307 452 } 308 453 ··· 1167 1310 const void *opcode, size_t len, const void *emulate) 1168 1311 { 1169 1312 struct insn insn; 1313 + int ret; 1170 1314 1171 1315 memcpy((void *)tp->text, opcode, len); 1172 1316 if (!emulate) 1173 1317 emulate = opcode; 1174 1318 1175 - kernel_insn_init(&insn, emulate, MAX_INSN_SIZE); 1176 - insn_get_length(&insn); 1319 + ret = insn_decode_kernel(&insn, emulate); 1177 1320 1178 - BUG_ON(!insn_complete(&insn)); 1321 + BUG_ON(ret < 0); 1179 1322 BUG_ON(len != insn.length); 1180 1323 1181 1324 tp->rel_addr = addr - (void *)_stext; ··· 1195 1338 default: /* assume NOP */ 1196 1339 switch (len) { 1197 1340 case 2: /* NOP2 -- emulate as JMP8+0 */ 1198 - BUG_ON(memcmp(emulate, ideal_nops[len], len)); 1341 + BUG_ON(memcmp(emulate, x86_nops[len], len)); 1199 1342 tp->opcode = JMP8_INSN_OPCODE; 1200 1343 tp->rel32 = 0; 1201 1344 break; 1202 1345 1203 1346 case 5: /* NOP5 -- emulate as JMP32+0 */ 1204 - BUG_ON(memcmp(emulate, ideal_nops[NOP_ATOMIC5], len)); 1347 + BUG_ON(memcmp(emulate, x86_nops[len], len)); 1205 1348 tp->opcode = JMP32_INSN_OPCODE; 1206 1349 tp->rel32 = 0; 1207 1350 break;
-5
arch/x86/kernel/asm-offsets_32.c
··· 53 53 offsetof(struct cpu_entry_area, tss.x86_tss.sp1) - 54 54 offsetofend(struct cpu_entry_area, entry_stack_page.stack)); 55 55 56 - #ifdef CONFIG_STACKPROTECTOR 57 - BLANK(); 58 - OFFSET(stack_canary_offset, stack_canary, canary); 59 - #endif 60 - 61 56 BLANK(); 62 57 DEFINE(EFI_svam, offsetof(efi_runtime_services_t, set_virtual_address_map)); 63 58 }
-5
arch/x86/kernel/cpu/amd.c
··· 628 628 629 629 early_init_amd_mc(c); 630 630 631 - #ifdef CONFIG_X86_32 632 - if (c->x86 == 6) 633 - set_cpu_cap(c, X86_FEATURE_K7); 634 - #endif 635 - 636 631 if (c->x86 >= 0xf) 637 632 set_cpu_cap(c, X86_FEATURE_K8); 638 633
+2 -3
arch/x86/kernel/cpu/common.c
··· 161 161 162 162 [GDT_ENTRY_ESPFIX_SS] = GDT_ENTRY_INIT(0xc092, 0, 0xfffff), 163 163 [GDT_ENTRY_PERCPU] = GDT_ENTRY_INIT(0xc092, 0, 0xfffff), 164 - GDT_STACK_CANARY_INIT 165 164 #endif 166 165 } }; 167 166 EXPORT_PER_CPU_SYMBOL_GPL(gdt_page); ··· 598 599 __loadsegment_simple(gs, 0); 599 600 wrmsrl(MSR_GS_BASE, cpu_kernelmode_gs_base(cpu)); 600 601 #endif 601 - load_stack_canary_segment(); 602 602 } 603 603 604 604 #ifdef CONFIG_X86_32 ··· 1796 1798 EXPORT_PER_CPU_SYMBOL(cpu_current_top_of_stack); 1797 1799 1798 1800 #ifdef CONFIG_STACKPROTECTOR 1799 - DEFINE_PER_CPU_ALIGNED(struct stack_canary, stack_canary); 1801 + DEFINE_PER_CPU(unsigned long, __stack_chk_guard); 1802 + EXPORT_PER_CPU_SYMBOL(__stack_chk_guard); 1800 1803 #endif 1801 1804 1802 1805 #endif /* CONFIG_X86_64 */
+2 -2
arch/x86/kernel/cpu/hygon.c
··· 215 215 u32 ecx; 216 216 217 217 ecx = cpuid_ecx(0x8000001e); 218 - nodes_per_socket = ((ecx >> 8) & 7) + 1; 218 + __max_die_per_package = nodes_per_socket = ((ecx >> 8) & 7) + 1; 219 219 } else if (boot_cpu_has(X86_FEATURE_NODEID_MSR)) { 220 220 u64 value; 221 221 222 222 rdmsrl(MSR_FAM10H_NODE_ID, value); 223 - nodes_per_socket = ((value >> 3) & 7) + 1; 223 + __max_die_per_package = nodes_per_socket = ((value >> 3) & 7) + 1; 224 224 } 225 225 226 226 if (!boot_cpu_has(X86_FEATURE_AMD_SSBD) &&
+1
arch/x86/kernel/cpu/mce/intel.c
··· 486 486 case INTEL_FAM6_BROADWELL_X: 487 487 case INTEL_FAM6_SKYLAKE_X: 488 488 case INTEL_FAM6_ICELAKE_X: 489 + case INTEL_FAM6_SAPPHIRERAPIDS_X: 489 490 case INTEL_FAM6_XEON_PHI_KNL: 490 491 case INTEL_FAM6_XEON_PHI_KNM: 491 492
+4 -8
arch/x86/kernel/cpu/mce/severity.c
··· 218 218 static bool is_copy_from_user(struct pt_regs *regs) 219 219 { 220 220 u8 insn_buf[MAX_INSN_SIZE]; 221 - struct insn insn; 222 221 unsigned long addr; 222 + struct insn insn; 223 + int ret; 223 224 224 225 if (copy_from_kernel_nofault(insn_buf, (void *)regs->ip, MAX_INSN_SIZE)) 225 226 return false; 226 227 227 - kernel_insn_init(&insn, insn_buf, MAX_INSN_SIZE); 228 - insn_get_opcode(&insn); 229 - if (!insn.opcode.got) 228 + ret = insn_decode_kernel(&insn, insn_buf); 229 + if (ret < 0) 230 230 return false; 231 231 232 232 switch (insn.opcode.value) { ··· 234 234 case 0x8A: case 0x8B: 235 235 /* MOVZ mem,reg */ 236 236 case 0xB60F: case 0xB70F: 237 - insn_get_modrm(&insn); 238 - insn_get_sib(&insn); 239 - if (!insn.modrm.got || !insn.sib.got) 240 - return false; 241 237 addr = (unsigned long)insn_get_addr_ref(&insn, regs); 242 238 break; 243 239 /* REP MOVS */
+1 -3
arch/x86/kernel/doublefault_32.c
··· 100 100 .ss = __KERNEL_DS, 101 101 .ds = __USER_DS, 102 102 .fs = __KERNEL_PERCPU, 103 - #ifndef CONFIG_X86_32_LAZY_GS 104 - .gs = __KERNEL_STACK_CANARY, 105 - #endif 103 + .gs = 0, 106 104 107 105 .__cr3 = __pa_nodebug(swapper_pg_dir), 108 106 },
+2 -2
arch/x86/kernel/ftrace.c
··· 66 66 67 67 static const char *ftrace_nop_replace(void) 68 68 { 69 - return ideal_nops[NOP_ATOMIC5]; 69 + return x86_nops[5]; 70 70 } 71 71 72 72 static const char *ftrace_call_replace(unsigned long ip, unsigned long addr) ··· 377 377 ip = trampoline + (jmp_offset - start_offset); 378 378 if (WARN_ON(*(char *)ip != 0x75)) 379 379 goto fail; 380 - ret = copy_from_kernel_nofault(ip, ideal_nops[2], 2); 380 + ret = copy_from_kernel_nofault(ip, x86_nops[2], 2); 381 381 if (ret < 0) 382 382 goto fail; 383 383 }
+2 -16
arch/x86/kernel/head_32.S
··· 318 318 movl $(__KERNEL_PERCPU), %eax 319 319 movl %eax,%fs # set this cpu's percpu 320 320 321 - movl $(__KERNEL_STACK_CANARY),%eax 322 - movl %eax,%gs 321 + xorl %eax,%eax 322 + movl %eax,%gs # clear possible garbage in %gs 323 323 324 324 xorl %eax,%eax # Clear LDT 325 325 lldt %ax ··· 339 339 */ 340 340 __INIT 341 341 setup_once: 342 - #ifdef CONFIG_STACKPROTECTOR 343 - /* 344 - * Configure the stack canary. The linker can't handle this by 345 - * relocation. Manually set base address in stack canary 346 - * segment descriptor. 347 - */ 348 - movl $gdt_page,%eax 349 - movl $stack_canary,%ecx 350 - movw %cx, 8 * GDT_ENTRY_STACK_CANARY + 2(%eax) 351 - shrl $16, %ecx 352 - movb %cl, 8 * GDT_ENTRY_STACK_CANARY + 4(%eax) 353 - movb %ch, 8 * GDT_ENTRY_STACK_CANARY + 7(%eax) 354 - #endif 355 - 356 342 andl $0,setup_once_ref /* Once is enough, thanks */ 357 343 ret 358 344
+6 -26
arch/x86/kernel/jump_label.c
··· 28 28 } 29 29 30 30 static const void * 31 - __jump_label_set_jump_code(struct jump_entry *entry, enum jump_label_type type, int init) 31 + __jump_label_set_jump_code(struct jump_entry *entry, enum jump_label_type type) 32 32 { 33 - const unsigned char default_nop[] = { STATIC_KEY_INIT_NOP }; 34 - const unsigned char *ideal_nop = ideal_nops[NOP_ATOMIC5]; 35 33 const void *expect, *code; 36 34 const void *addr, *dest; 37 35 int line; ··· 39 41 40 42 code = text_gen_insn(JMP32_INSN_OPCODE, addr, dest); 41 43 42 - if (init) { 43 - expect = default_nop; line = __LINE__; 44 - } else if (type == JUMP_LABEL_JMP) { 45 - expect = ideal_nop; line = __LINE__; 44 + if (type == JUMP_LABEL_JMP) { 45 + expect = x86_nops[5]; line = __LINE__; 46 46 } else { 47 47 expect = code; line = __LINE__; 48 48 } ··· 49 53 bug_at(addr, line); 50 54 51 55 if (type == JUMP_LABEL_NOP) 52 - code = ideal_nop; 56 + code = x86_nops[5]; 53 57 54 58 return code; 55 59 } ··· 58 62 enum jump_label_type type, 59 63 int init) 60 64 { 61 - const void *opcode = __jump_label_set_jump_code(entry, type, init); 65 + const void *opcode = __jump_label_set_jump_code(entry, type); 62 66 63 67 /* 64 68 * As long as only a single processor is running and the code is still ··· 109 113 } 110 114 111 115 mutex_lock(&text_mutex); 112 - opcode = __jump_label_set_jump_code(entry, type, 0); 116 + opcode = __jump_label_set_jump_code(entry, type); 113 117 text_poke_queue((void *)jump_entry_code(entry), 114 118 opcode, JUMP_LABEL_NOP_SIZE, NULL); 115 119 mutex_unlock(&text_mutex); ··· 132 136 __init_or_module void arch_jump_label_transform_static(struct jump_entry *entry, 133 137 enum jump_label_type type) 134 138 { 135 - /* 136 - * This function is called at boot up and when modules are 137 - * first loaded. Check if the default nop, the one that is 138 - * inserted at compile time, is the ideal nop. If it is, then 139 - * we do not need to update the nop, and we can leave it as is. 140 - * If it is not, then we need to update the nop to the ideal nop. 141 - */ 142 - if (jlstate == JL_STATE_START) { 143 - const unsigned char default_nop[] = { STATIC_KEY_INIT_NOP }; 144 - const unsigned char *ideal_nop = ideal_nops[NOP_ATOMIC5]; 145 - 146 - if (memcmp(ideal_nop, default_nop, 5) != 0) 147 - jlstate = JL_STATE_UPDATE; 148 - else 149 - jlstate = JL_STATE_NO_UPDATE; 150 - } 151 139 if (jlstate == JL_STATE_UPDATE) 152 140 jump_label_transform(entry, type, 1); 153 141 }
+383 -215
arch/x86/kernel/kprobes/core.c
··· 139 139 int can_boost(struct insn *insn, void *addr) 140 140 { 141 141 kprobe_opcode_t opcode; 142 + insn_byte_t prefix; 143 + int i; 142 144 143 145 if (search_exception_tables((unsigned long)addr)) 144 146 return 0; /* Page fault may occur on this address. */ ··· 153 151 if (insn->opcode.nbytes != 1) 154 152 return 0; 155 153 156 - /* Can't boost Address-size override prefix */ 157 - if (unlikely(inat_is_address_size_prefix(insn->attr))) 158 - return 0; 154 + for_each_insn_prefix(insn, i, prefix) { 155 + insn_attr_t attr; 156 + 157 + attr = inat_get_opcode_attribute(prefix); 158 + /* Can't boost Address-size override prefix and CS override prefix */ 159 + if (prefix == 0x2e || inat_is_address_size_prefix(attr)) 160 + return 0; 161 + } 159 162 160 163 opcode = insn->opcode.bytes[0]; 161 164 162 - switch (opcode & 0xf0) { 163 - case 0x60: 164 - /* can't boost "bound" */ 165 - return (opcode != 0x62); 166 - case 0x70: 167 - return 0; /* can't boost conditional jump */ 168 - case 0x90: 169 - return opcode != 0x9a; /* can't boost call far */ 170 - case 0xc0: 171 - /* can't boost software-interruptions */ 172 - return (0xc1 < opcode && opcode < 0xcc) || opcode == 0xcf; 173 - case 0xd0: 174 - /* can boost AA* and XLAT */ 175 - return (opcode == 0xd4 || opcode == 0xd5 || opcode == 0xd7); 176 - case 0xe0: 177 - /* can boost in/out and absolute jmps */ 178 - return ((opcode & 0x04) || opcode == 0xea); 179 - case 0xf0: 180 - /* clear and set flags are boostable */ 181 - return (opcode == 0xf5 || (0xf7 < opcode && opcode < 0xfe)); 165 + switch (opcode) { 166 + case 0x62: /* bound */ 167 + case 0x70 ... 0x7f: /* Conditional jumps */ 168 + case 0x9a: /* Call far */ 169 + case 0xc0 ... 0xc1: /* Grp2 */ 170 + case 0xcc ... 0xce: /* software exceptions */ 171 + case 0xd0 ... 0xd3: /* Grp2 */ 172 + case 0xd6: /* (UD) */ 173 + case 0xd8 ... 0xdf: /* ESC */ 174 + case 0xe0 ... 0xe3: /* LOOP*, JCXZ */ 175 + case 0xe8 ... 0xe9: /* near Call, JMP */ 176 + case 0xeb: /* Short JMP */ 177 + case 0xf0 ... 0xf4: /* LOCK/REP, HLT */ 178 + case 0xf6 ... 0xf7: /* Grp3 */ 179 + case 0xfe: /* Grp4 */ 180 + /* ... are not boostable */ 181 + return 0; 182 + case 0xff: /* Grp5 */ 183 + /* Only indirect jmp is boostable */ 184 + return X86_MODRM_REG(insn->modrm.bytes[0]) == 4; 182 185 default: 183 - /* CS override prefix and call are not boostable */ 184 - return (opcode != 0x2e && opcode != 0x9a); 186 + return 1; 185 187 } 186 188 } 187 189 ··· 235 229 return 0UL; 236 230 237 231 if (faddr) 238 - memcpy(buf, ideal_nops[NOP_ATOMIC5], 5); 232 + memcpy(buf, x86_nops[5], 5); 239 233 else 240 234 buf[0] = kp->opcode; 241 235 return (unsigned long)buf; ··· 271 265 /* Decode instructions */ 272 266 addr = paddr - offset; 273 267 while (addr < paddr) { 268 + int ret; 269 + 274 270 /* 275 271 * Check if the instruction has been modified by another 276 272 * kprobe, in which case we replace the breakpoint by the ··· 284 276 __addr = recover_probed_instruction(buf, addr); 285 277 if (!__addr) 286 278 return 0; 287 - kernel_insn_init(&insn, (void *)__addr, MAX_INSN_SIZE); 288 - insn_get_length(&insn); 279 + 280 + ret = insn_decode_kernel(&insn, (void *)__addr); 281 + if (ret < 0) 282 + return 0; 289 283 290 284 /* 291 285 * Another debugging subsystem might insert this breakpoint. ··· 311 301 int __copy_instruction(u8 *dest, u8 *src, u8 *real, struct insn *insn) 312 302 { 313 303 kprobe_opcode_t buf[MAX_INSN_SIZE]; 314 - unsigned long recovered_insn = 315 - recover_probed_instruction(buf, (unsigned long)src); 304 + unsigned long recovered_insn = recover_probed_instruction(buf, (unsigned long)src); 305 + int ret; 316 306 317 307 if (!recovered_insn || !insn) 318 308 return 0; ··· 322 312 MAX_INSN_SIZE)) 323 313 return 0; 324 314 325 - kernel_insn_init(insn, dest, MAX_INSN_SIZE); 326 - insn_get_length(insn); 315 + ret = insn_decode_kernel(insn, dest); 316 + if (ret < 0) 317 + return 0; 327 318 328 319 /* We can not probe force emulate prefixed instruction */ 329 320 if (insn_has_emulate_prefix(insn)) ··· 368 357 return insn->length; 369 358 } 370 359 371 - /* Prepare reljump right after instruction to boost */ 372 - static int prepare_boost(kprobe_opcode_t *buf, struct kprobe *p, 373 - struct insn *insn) 360 + /* Prepare reljump or int3 right after instruction */ 361 + static int prepare_singlestep(kprobe_opcode_t *buf, struct kprobe *p, 362 + struct insn *insn) 374 363 { 375 364 int len = insn->length; 376 365 377 - if (can_boost(insn, p->addr) && 366 + if (!IS_ENABLED(CONFIG_PREEMPTION) && 367 + !p->post_handler && can_boost(insn, p->addr) && 378 368 MAX_INSN_SIZE - len >= JMP32_INSN_SIZE) { 379 369 /* 380 370 * These instructions can be executed directly if it ··· 386 374 len += JMP32_INSN_SIZE; 387 375 p->ainsn.boostable = 1; 388 376 } else { 389 - p->ainsn.boostable = 0; 377 + /* Otherwise, put an int3 for trapping singlestep */ 378 + if (MAX_INSN_SIZE - len < INT3_INSN_SIZE) 379 + return -ENOSPC; 380 + 381 + buf[len] = INT3_INSN_OPCODE; 382 + len += INT3_INSN_SIZE; 390 383 } 391 384 392 385 return len; ··· 428 411 module_memfree(page); 429 412 } 430 413 431 - static void set_resume_flags(struct kprobe *p, struct insn *insn) 414 + /* Kprobe x86 instruction emulation - only regs->ip or IF flag modifiers */ 415 + 416 + static void kprobe_emulate_ifmodifiers(struct kprobe *p, struct pt_regs *regs) 417 + { 418 + switch (p->ainsn.opcode) { 419 + case 0xfa: /* cli */ 420 + regs->flags &= ~(X86_EFLAGS_IF); 421 + break; 422 + case 0xfb: /* sti */ 423 + regs->flags |= X86_EFLAGS_IF; 424 + break; 425 + case 0x9c: /* pushf */ 426 + int3_emulate_push(regs, regs->flags); 427 + break; 428 + case 0x9d: /* popf */ 429 + regs->flags = int3_emulate_pop(regs); 430 + break; 431 + } 432 + regs->ip = regs->ip - INT3_INSN_SIZE + p->ainsn.size; 433 + } 434 + NOKPROBE_SYMBOL(kprobe_emulate_ifmodifiers); 435 + 436 + static void kprobe_emulate_ret(struct kprobe *p, struct pt_regs *regs) 437 + { 438 + int3_emulate_ret(regs); 439 + } 440 + NOKPROBE_SYMBOL(kprobe_emulate_ret); 441 + 442 + static void kprobe_emulate_call(struct kprobe *p, struct pt_regs *regs) 443 + { 444 + unsigned long func = regs->ip - INT3_INSN_SIZE + p->ainsn.size; 445 + 446 + func += p->ainsn.rel32; 447 + int3_emulate_call(regs, func); 448 + } 449 + NOKPROBE_SYMBOL(kprobe_emulate_call); 450 + 451 + static nokprobe_inline 452 + void __kprobe_emulate_jmp(struct kprobe *p, struct pt_regs *regs, bool cond) 453 + { 454 + unsigned long ip = regs->ip - INT3_INSN_SIZE + p->ainsn.size; 455 + 456 + if (cond) 457 + ip += p->ainsn.rel32; 458 + int3_emulate_jmp(regs, ip); 459 + } 460 + 461 + static void kprobe_emulate_jmp(struct kprobe *p, struct pt_regs *regs) 462 + { 463 + __kprobe_emulate_jmp(p, regs, true); 464 + } 465 + NOKPROBE_SYMBOL(kprobe_emulate_jmp); 466 + 467 + static const unsigned long jcc_mask[6] = { 468 + [0] = X86_EFLAGS_OF, 469 + [1] = X86_EFLAGS_CF, 470 + [2] = X86_EFLAGS_ZF, 471 + [3] = X86_EFLAGS_CF | X86_EFLAGS_ZF, 472 + [4] = X86_EFLAGS_SF, 473 + [5] = X86_EFLAGS_PF, 474 + }; 475 + 476 + static void kprobe_emulate_jcc(struct kprobe *p, struct pt_regs *regs) 477 + { 478 + bool invert = p->ainsn.jcc.type & 1; 479 + bool match; 480 + 481 + if (p->ainsn.jcc.type < 0xc) { 482 + match = regs->flags & jcc_mask[p->ainsn.jcc.type >> 1]; 483 + } else { 484 + match = ((regs->flags & X86_EFLAGS_SF) >> X86_EFLAGS_SF_BIT) ^ 485 + ((regs->flags & X86_EFLAGS_OF) >> X86_EFLAGS_OF_BIT); 486 + if (p->ainsn.jcc.type >= 0xe) 487 + match = match && (regs->flags & X86_EFLAGS_ZF); 488 + } 489 + __kprobe_emulate_jmp(p, regs, (match && !invert) || (!match && invert)); 490 + } 491 + NOKPROBE_SYMBOL(kprobe_emulate_jcc); 492 + 493 + static void kprobe_emulate_loop(struct kprobe *p, struct pt_regs *regs) 494 + { 495 + bool match; 496 + 497 + if (p->ainsn.loop.type != 3) { /* LOOP* */ 498 + if (p->ainsn.loop.asize == 32) 499 + match = ((*(u32 *)&regs->cx)--) != 0; 500 + #ifdef CONFIG_X86_64 501 + else if (p->ainsn.loop.asize == 64) 502 + match = ((*(u64 *)&regs->cx)--) != 0; 503 + #endif 504 + else 505 + match = ((*(u16 *)&regs->cx)--) != 0; 506 + } else { /* JCXZ */ 507 + if (p->ainsn.loop.asize == 32) 508 + match = *(u32 *)(&regs->cx) == 0; 509 + #ifdef CONFIG_X86_64 510 + else if (p->ainsn.loop.asize == 64) 511 + match = *(u64 *)(&regs->cx) == 0; 512 + #endif 513 + else 514 + match = *(u16 *)(&regs->cx) == 0; 515 + } 516 + 517 + if (p->ainsn.loop.type == 0) /* LOOPNE */ 518 + match = match && !(regs->flags & X86_EFLAGS_ZF); 519 + else if (p->ainsn.loop.type == 1) /* LOOPE */ 520 + match = match && (regs->flags & X86_EFLAGS_ZF); 521 + 522 + __kprobe_emulate_jmp(p, regs, match); 523 + } 524 + NOKPROBE_SYMBOL(kprobe_emulate_loop); 525 + 526 + static const int addrmode_regoffs[] = { 527 + offsetof(struct pt_regs, ax), 528 + offsetof(struct pt_regs, cx), 529 + offsetof(struct pt_regs, dx), 530 + offsetof(struct pt_regs, bx), 531 + offsetof(struct pt_regs, sp), 532 + offsetof(struct pt_regs, bp), 533 + offsetof(struct pt_regs, si), 534 + offsetof(struct pt_regs, di), 535 + #ifdef CONFIG_X86_64 536 + offsetof(struct pt_regs, r8), 537 + offsetof(struct pt_regs, r9), 538 + offsetof(struct pt_regs, r10), 539 + offsetof(struct pt_regs, r11), 540 + offsetof(struct pt_regs, r12), 541 + offsetof(struct pt_regs, r13), 542 + offsetof(struct pt_regs, r14), 543 + offsetof(struct pt_regs, r15), 544 + #endif 545 + }; 546 + 547 + static void kprobe_emulate_call_indirect(struct kprobe *p, struct pt_regs *regs) 548 + { 549 + unsigned long offs = addrmode_regoffs[p->ainsn.indirect.reg]; 550 + 551 + int3_emulate_call(regs, regs_get_register(regs, offs)); 552 + } 553 + NOKPROBE_SYMBOL(kprobe_emulate_call_indirect); 554 + 555 + static void kprobe_emulate_jmp_indirect(struct kprobe *p, struct pt_regs *regs) 556 + { 557 + unsigned long offs = addrmode_regoffs[p->ainsn.indirect.reg]; 558 + 559 + int3_emulate_jmp(regs, regs_get_register(regs, offs)); 560 + } 561 + NOKPROBE_SYMBOL(kprobe_emulate_jmp_indirect); 562 + 563 + static int prepare_emulation(struct kprobe *p, struct insn *insn) 432 564 { 433 565 insn_byte_t opcode = insn->opcode.bytes[0]; 434 566 435 567 switch (opcode) { 436 568 case 0xfa: /* cli */ 437 569 case 0xfb: /* sti */ 570 + case 0x9c: /* pushfl */ 438 571 case 0x9d: /* popf/popfd */ 439 - /* Check whether the instruction modifies Interrupt Flag or not */ 440 - p->ainsn.if_modifier = 1; 572 + /* 573 + * IF modifiers must be emulated since it will enable interrupt while 574 + * int3 single stepping. 575 + */ 576 + p->ainsn.emulate_op = kprobe_emulate_ifmodifiers; 577 + p->ainsn.opcode = opcode; 441 578 break; 442 - case 0x9c: /* pushfl */ 443 - p->ainsn.is_pushf = 1; 444 - break; 445 - case 0xcf: /* iret */ 446 - p->ainsn.if_modifier = 1; 447 - fallthrough; 448 579 case 0xc2: /* ret/lret */ 449 580 case 0xc3: 450 581 case 0xca: 451 582 case 0xcb: 452 - case 0xea: /* jmp absolute -- ip is correct */ 453 - /* ip is already adjusted, no more changes required */ 454 - p->ainsn.is_abs_ip = 1; 455 - /* Without resume jump, this is boostable */ 456 - p->ainsn.boostable = 1; 583 + p->ainsn.emulate_op = kprobe_emulate_ret; 457 584 break; 458 - case 0xe8: /* call relative - Fix return addr */ 459 - p->ainsn.is_call = 1; 585 + case 0x9a: /* far call absolute -- segment is not supported */ 586 + case 0xea: /* far jmp absolute -- segment is not supported */ 587 + case 0xcc: /* int3 */ 588 + case 0xcf: /* iret -- in-kernel IRET is not supported */ 589 + return -EOPNOTSUPP; 460 590 break; 461 - #ifdef CONFIG_X86_32 462 - case 0x9a: /* call absolute -- same as call absolute, indirect */ 463 - p->ainsn.is_call = 1; 464 - p->ainsn.is_abs_ip = 1; 591 + case 0xe8: /* near call relative */ 592 + p->ainsn.emulate_op = kprobe_emulate_call; 593 + if (insn->immediate.nbytes == 2) 594 + p->ainsn.rel32 = *(s16 *)&insn->immediate.value; 595 + else 596 + p->ainsn.rel32 = *(s32 *)&insn->immediate.value; 465 597 break; 466 - #endif 467 - case 0xff: 598 + case 0xeb: /* short jump relative */ 599 + case 0xe9: /* near jump relative */ 600 + p->ainsn.emulate_op = kprobe_emulate_jmp; 601 + if (insn->immediate.nbytes == 1) 602 + p->ainsn.rel32 = *(s8 *)&insn->immediate.value; 603 + else if (insn->immediate.nbytes == 2) 604 + p->ainsn.rel32 = *(s16 *)&insn->immediate.value; 605 + else 606 + p->ainsn.rel32 = *(s32 *)&insn->immediate.value; 607 + break; 608 + case 0x70 ... 0x7f: 609 + /* 1 byte conditional jump */ 610 + p->ainsn.emulate_op = kprobe_emulate_jcc; 611 + p->ainsn.jcc.type = opcode & 0xf; 612 + p->ainsn.rel32 = *(char *)insn->immediate.bytes; 613 + break; 614 + case 0x0f: 468 615 opcode = insn->opcode.bytes[1]; 469 - if ((opcode & 0x30) == 0x10) { 470 - /* 471 - * call absolute, indirect 472 - * Fix return addr; ip is correct. 473 - * But this is not boostable 474 - */ 475 - p->ainsn.is_call = 1; 476 - p->ainsn.is_abs_ip = 1; 477 - break; 478 - } else if (((opcode & 0x31) == 0x20) || 479 - ((opcode & 0x31) == 0x21)) { 480 - /* 481 - * jmp near and far, absolute indirect 482 - * ip is correct. 483 - */ 484 - p->ainsn.is_abs_ip = 1; 485 - /* Without resume jump, this is boostable */ 486 - p->ainsn.boostable = 1; 616 + if ((opcode & 0xf0) == 0x80) { 617 + /* 2 bytes Conditional Jump */ 618 + p->ainsn.emulate_op = kprobe_emulate_jcc; 619 + p->ainsn.jcc.type = opcode & 0xf; 620 + if (insn->immediate.nbytes == 2) 621 + p->ainsn.rel32 = *(s16 *)&insn->immediate.value; 622 + else 623 + p->ainsn.rel32 = *(s32 *)&insn->immediate.value; 624 + } else if (opcode == 0x01 && 625 + X86_MODRM_REG(insn->modrm.bytes[0]) == 0 && 626 + X86_MODRM_MOD(insn->modrm.bytes[0]) == 3) { 627 + /* VM extensions - not supported */ 628 + return -EOPNOTSUPP; 487 629 } 488 630 break; 631 + case 0xe0: /* Loop NZ */ 632 + case 0xe1: /* Loop */ 633 + case 0xe2: /* Loop */ 634 + case 0xe3: /* J*CXZ */ 635 + p->ainsn.emulate_op = kprobe_emulate_loop; 636 + p->ainsn.loop.type = opcode & 0x3; 637 + p->ainsn.loop.asize = insn->addr_bytes * 8; 638 + p->ainsn.rel32 = *(s8 *)&insn->immediate.value; 639 + break; 640 + case 0xff: 641 + /* 642 + * Since the 0xff is an extended group opcode, the instruction 643 + * is determined by the MOD/RM byte. 644 + */ 645 + opcode = insn->modrm.bytes[0]; 646 + if ((opcode & 0x30) == 0x10) { 647 + if ((opcode & 0x8) == 0x8) 648 + return -EOPNOTSUPP; /* far call */ 649 + /* call absolute, indirect */ 650 + p->ainsn.emulate_op = kprobe_emulate_call_indirect; 651 + } else if ((opcode & 0x30) == 0x20) { 652 + if ((opcode & 0x8) == 0x8) 653 + return -EOPNOTSUPP; /* far jmp */ 654 + /* jmp near absolute indirect */ 655 + p->ainsn.emulate_op = kprobe_emulate_jmp_indirect; 656 + } else 657 + break; 658 + 659 + if (insn->addr_bytes != sizeof(unsigned long)) 660 + return -EOPNOTSUPP; /* Don't support differnt size */ 661 + if (X86_MODRM_MOD(opcode) != 3) 662 + return -EOPNOTSUPP; /* TODO: support memory addressing */ 663 + 664 + p->ainsn.indirect.reg = X86_MODRM_RM(opcode); 665 + #ifdef CONFIG_X86_64 666 + if (X86_REX_B(insn->rex_prefix.value)) 667 + p->ainsn.indirect.reg += 8; 668 + #endif 669 + break; 670 + default: 671 + break; 489 672 } 673 + p->ainsn.size = insn->length; 674 + 675 + return 0; 490 676 } 491 677 492 678 static int arch_copy_kprobe(struct kprobe *p) 493 679 { 494 680 struct insn insn; 495 681 kprobe_opcode_t buf[MAX_INSN_SIZE]; 496 - int len; 682 + int ret, len; 497 683 498 684 /* Copy an instruction with recovering if other optprobe modifies it.*/ 499 685 len = __copy_instruction(buf, p->addr, p->ainsn.insn, &insn); 500 686 if (!len) 501 687 return -EINVAL; 502 688 503 - /* 504 - * __copy_instruction can modify the displacement of the instruction, 505 - * but it doesn't affect boostable check. 506 - */ 507 - len = prepare_boost(buf, p, &insn); 689 + /* Analyze the opcode and setup emulate functions */ 690 + ret = prepare_emulation(p, &insn); 691 + if (ret < 0) 692 + return ret; 508 693 509 - /* Analyze the opcode and set resume flags */ 510 - set_resume_flags(p, &insn); 694 + /* Add int3 for single-step or booster jmp */ 695 + len = prepare_singlestep(buf, p, &insn); 696 + if (len < 0) 697 + return len; 511 698 512 699 /* Also, displacement change doesn't affect the first byte */ 513 700 p->opcode = buf[0]; ··· 804 583 { 805 584 __this_cpu_write(current_kprobe, p); 806 585 kcb->kprobe_saved_flags = kcb->kprobe_old_flags 807 - = (regs->flags & (X86_EFLAGS_TF | X86_EFLAGS_IF)); 808 - if (p->ainsn.if_modifier) 809 - kcb->kprobe_saved_flags &= ~X86_EFLAGS_IF; 810 - } 811 - 812 - static nokprobe_inline void clear_btf(void) 813 - { 814 - if (test_thread_flag(TIF_BLOCKSTEP)) { 815 - unsigned long debugctl = get_debugctlmsr(); 816 - 817 - debugctl &= ~DEBUGCTLMSR_BTF; 818 - update_debugctlmsr(debugctl); 819 - } 820 - } 821 - 822 - static nokprobe_inline void restore_btf(void) 823 - { 824 - if (test_thread_flag(TIF_BLOCKSTEP)) { 825 - unsigned long debugctl = get_debugctlmsr(); 826 - 827 - debugctl |= DEBUGCTLMSR_BTF; 828 - update_debugctlmsr(debugctl); 829 - } 586 + = (regs->flags & X86_EFLAGS_IF); 830 587 } 831 588 832 589 void arch_prepare_kretprobe(struct kretprobe_instance *ri, struct pt_regs *regs) ··· 819 620 } 820 621 NOKPROBE_SYMBOL(arch_prepare_kretprobe); 821 622 623 + static void kprobe_post_process(struct kprobe *cur, struct pt_regs *regs, 624 + struct kprobe_ctlblk *kcb) 625 + { 626 + if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) { 627 + kcb->kprobe_status = KPROBE_HIT_SSDONE; 628 + cur->post_handler(cur, regs, 0); 629 + } 630 + 631 + /* Restore back the original saved kprobes variables and continue. */ 632 + if (kcb->kprobe_status == KPROBE_REENTER) 633 + restore_previous_kprobe(kcb); 634 + else 635 + reset_current_kprobe(); 636 + } 637 + NOKPROBE_SYMBOL(kprobe_post_process); 638 + 822 639 static void setup_singlestep(struct kprobe *p, struct pt_regs *regs, 823 640 struct kprobe_ctlblk *kcb, int reenter) 824 641 { ··· 842 627 return; 843 628 844 629 #if !defined(CONFIG_PREEMPTION) 845 - if (p->ainsn.boostable && !p->post_handler) { 630 + if (p->ainsn.boostable) { 846 631 /* Boost up -- we can execute copied instructions directly */ 847 632 if (!reenter) 848 633 reset_current_kprobe(); ··· 861 646 kcb->kprobe_status = KPROBE_REENTER; 862 647 } else 863 648 kcb->kprobe_status = KPROBE_HIT_SS; 864 - /* Prepare real single stepping */ 865 - clear_btf(); 866 - regs->flags |= X86_EFLAGS_TF; 649 + 650 + if (p->ainsn.emulate_op) { 651 + p->ainsn.emulate_op(p, regs); 652 + kprobe_post_process(p, regs, kcb); 653 + return; 654 + } 655 + 656 + /* Disable interrupt, and set ip register on trampoline */ 867 657 regs->flags &= ~X86_EFLAGS_IF; 868 - /* single step inline if the instruction is an int3 */ 869 - if (p->opcode == INT3_INSN_OPCODE) 870 - regs->ip = (unsigned long)p->addr; 871 - else 872 - regs->ip = (unsigned long)p->ainsn.insn; 658 + regs->ip = (unsigned long)p->ainsn.insn; 873 659 } 874 660 NOKPROBE_SYMBOL(setup_singlestep); 661 + 662 + /* 663 + * Called after single-stepping. p->addr is the address of the 664 + * instruction whose first byte has been replaced by the "int3" 665 + * instruction. To avoid the SMP problems that can occur when we 666 + * temporarily put back the original opcode to single-step, we 667 + * single-stepped a copy of the instruction. The address of this 668 + * copy is p->ainsn.insn. We also doesn't use trap, but "int3" again 669 + * right after the copied instruction. 670 + * Different from the trap single-step, "int3" single-step can not 671 + * handle the instruction which changes the ip register, e.g. jmp, 672 + * call, conditional jmp, and the instructions which changes the IF 673 + * flags because interrupt must be disabled around the single-stepping. 674 + * Such instructions are software emulated, but others are single-stepped 675 + * using "int3". 676 + * 677 + * When the 2nd "int3" handled, the regs->ip and regs->flags needs to 678 + * be adjusted, so that we can resume execution on correct code. 679 + */ 680 + static void resume_singlestep(struct kprobe *p, struct pt_regs *regs, 681 + struct kprobe_ctlblk *kcb) 682 + { 683 + unsigned long copy_ip = (unsigned long)p->ainsn.insn; 684 + unsigned long orig_ip = (unsigned long)p->addr; 685 + 686 + /* Restore saved interrupt flag and ip register */ 687 + regs->flags |= kcb->kprobe_saved_flags; 688 + /* Note that regs->ip is executed int3 so must be a step back */ 689 + regs->ip += (orig_ip - copy_ip) - INT3_INSN_SIZE; 690 + } 691 + NOKPROBE_SYMBOL(resume_singlestep); 875 692 876 693 /* 877 694 * We have reentered the kprobe_handler(), since another probe was hit while ··· 939 692 return 1; 940 693 } 941 694 NOKPROBE_SYMBOL(reenter_kprobe); 695 + 696 + static nokprobe_inline int kprobe_is_ss(struct kprobe_ctlblk *kcb) 697 + { 698 + return (kcb->kprobe_status == KPROBE_HIT_SS || 699 + kcb->kprobe_status == KPROBE_REENTER); 700 + } 942 701 943 702 /* 944 703 * Interrupts are disabled on entry as trap3 is an interrupt gate and they ··· 990 737 reset_current_kprobe(); 991 738 return 1; 992 739 } 993 - } else if (*addr != INT3_INSN_OPCODE) { 740 + } else if (kprobe_is_ss(kcb)) { 741 + p = kprobe_running(); 742 + if ((unsigned long)p->ainsn.insn < regs->ip && 743 + (unsigned long)p->ainsn.insn + MAX_INSN_SIZE > regs->ip) { 744 + /* Most provably this is the second int3 for singlestep */ 745 + resume_singlestep(p, regs, kcb); 746 + kprobe_post_process(p, regs, kcb); 747 + return 1; 748 + } 749 + } 750 + 751 + if (*addr != INT3_INSN_OPCODE) { 994 752 /* 995 753 * The breakpoint instruction was removed right 996 754 * after we hit it. Another cpu has removed ··· 1074 810 } 1075 811 NOKPROBE_SYMBOL(trampoline_handler); 1076 812 1077 - /* 1078 - * Called after single-stepping. p->addr is the address of the 1079 - * instruction whose first byte has been replaced by the "int 3" 1080 - * instruction. To avoid the SMP problems that can occur when we 1081 - * temporarily put back the original opcode to single-step, we 1082 - * single-stepped a copy of the instruction. The address of this 1083 - * copy is p->ainsn.insn. 1084 - * 1085 - * This function prepares to return from the post-single-step 1086 - * interrupt. We have to fix up the stack as follows: 1087 - * 1088 - * 0) Except in the case of absolute or indirect jump or call instructions, 1089 - * the new ip is relative to the copied instruction. We need to make 1090 - * it relative to the original instruction. 1091 - * 1092 - * 1) If the single-stepped instruction was pushfl, then the TF and IF 1093 - * flags are set in the just-pushed flags, and may need to be cleared. 1094 - * 1095 - * 2) If the single-stepped instruction was a call, the return address 1096 - * that is atop the stack is the address following the copied instruction. 1097 - * We need to make it the address following the original instruction. 1098 - */ 1099 - static void resume_execution(struct kprobe *p, struct pt_regs *regs, 1100 - struct kprobe_ctlblk *kcb) 1101 - { 1102 - unsigned long *tos = stack_addr(regs); 1103 - unsigned long copy_ip = (unsigned long)p->ainsn.insn; 1104 - unsigned long orig_ip = (unsigned long)p->addr; 1105 - 1106 - regs->flags &= ~X86_EFLAGS_TF; 1107 - 1108 - /* Fixup the contents of top of stack */ 1109 - if (p->ainsn.is_pushf) { 1110 - *tos &= ~(X86_EFLAGS_TF | X86_EFLAGS_IF); 1111 - *tos |= kcb->kprobe_old_flags; 1112 - } else if (p->ainsn.is_call) { 1113 - *tos = orig_ip + (*tos - copy_ip); 1114 - } 1115 - 1116 - if (!p->ainsn.is_abs_ip) 1117 - regs->ip += orig_ip - copy_ip; 1118 - 1119 - restore_btf(); 1120 - } 1121 - NOKPROBE_SYMBOL(resume_execution); 1122 - 1123 - /* 1124 - * Interrupts are disabled on entry as trap1 is an interrupt gate and they 1125 - * remain disabled throughout this function. 1126 - */ 1127 - int kprobe_debug_handler(struct pt_regs *regs) 1128 - { 1129 - struct kprobe *cur = kprobe_running(); 1130 - struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); 1131 - 1132 - if (!cur) 1133 - return 0; 1134 - 1135 - resume_execution(cur, regs, kcb); 1136 - regs->flags |= kcb->kprobe_saved_flags; 1137 - 1138 - if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) { 1139 - kcb->kprobe_status = KPROBE_HIT_SSDONE; 1140 - cur->post_handler(cur, regs, 0); 1141 - } 1142 - 1143 - /* Restore back the original saved kprobes variables and continue. */ 1144 - if (kcb->kprobe_status == KPROBE_REENTER) { 1145 - restore_previous_kprobe(kcb); 1146 - goto out; 1147 - } 1148 - reset_current_kprobe(); 1149 - out: 1150 - /* 1151 - * if somebody else is singlestepping across a probe point, flags 1152 - * will have TF set, in which case, continue the remaining processing 1153 - * of do_debug, as if this is not a probe hit. 1154 - */ 1155 - if (regs->flags & X86_EFLAGS_TF) 1156 - return 0; 1157 - 1158 - return 1; 1159 - } 1160 - NOKPROBE_SYMBOL(kprobe_debug_handler); 1161 - 1162 813 int kprobe_fault_handler(struct pt_regs *regs, int trapnr) 1163 814 { 1164 815 struct kprobe *cur = kprobe_running(); ··· 1091 912 * normal page fault. 1092 913 */ 1093 914 regs->ip = (unsigned long)cur->addr; 1094 - /* 1095 - * Trap flag (TF) has been set here because this fault 1096 - * happened where the single stepping will be done. 1097 - * So clear it by resetting the current kprobe: 1098 - */ 1099 - regs->flags &= ~X86_EFLAGS_TF; 1100 - /* 1101 - * Since the single step (trap) has been cancelled, 1102 - * we need to restore BTF here. 1103 - */ 1104 - restore_btf(); 1105 915 1106 916 /* 1107 - * If the TF flag was set before the kprobe hit, 917 + * If the IF flag was set before the kprobe hit, 1108 918 * don't touch it: 1109 919 */ 1110 920 regs->flags |= kcb->kprobe_old_flags;
+7 -2
arch/x86/kernel/kprobes/opt.c
··· 312 312 addr = paddr - offset; 313 313 while (addr < paddr - offset + size) { /* Decode until function end */ 314 314 unsigned long recovered_insn; 315 + int ret; 316 + 315 317 if (search_exception_tables(addr)) 316 318 /* 317 319 * Since some fixup code will jumps into this function, ··· 323 321 recovered_insn = recover_probed_instruction(buf, addr); 324 322 if (!recovered_insn) 325 323 return 0; 326 - kernel_insn_init(&insn, (void *)recovered_insn, MAX_INSN_SIZE); 327 - insn_get_length(&insn); 324 + 325 + ret = insn_decode_kernel(&insn, (void *)recovered_insn); 326 + if (ret < 0) 327 + return 0; 328 + 328 329 /* 329 330 * In the case of detecting unknown breakpoint, this could be 330 331 * a padding INT3 between functions. Let's check that all the
-1
arch/x86/kernel/setup.c
··· 822 822 823 823 idt_setup_early_traps(); 824 824 early_cpu_init(); 825 - arch_init_ideal_nops(); 826 825 jump_label_init(); 827 826 static_call_init(); 828 827 early_ioremap_init();
-1
arch/x86/kernel/setup_percpu.c
··· 224 224 per_cpu(this_cpu_off, cpu) = per_cpu_offset(cpu); 225 225 per_cpu(cpu_number, cpu) = cpu; 226 226 setup_percpu_segment(cpu); 227 - setup_stack_canary_segment(cpu); 228 227 /* 229 228 * Copy data used in early init routines from the 230 229 * initial arrays to the per cpu data areas. These
+41 -26
arch/x86/kernel/sev-es.c
··· 263 263 return copy_from_kernel_nofault(buffer, (unsigned char *)ctxt->regs->ip, MAX_INSN_SIZE); 264 264 } 265 265 266 - static enum es_result vc_decode_insn(struct es_em_ctxt *ctxt) 266 + static enum es_result __vc_decode_user_insn(struct es_em_ctxt *ctxt) 267 267 { 268 268 char buffer[MAX_INSN_SIZE]; 269 - enum es_result ret; 270 269 int res; 271 270 272 - if (user_mode(ctxt->regs)) { 273 - res = insn_fetch_from_user_inatomic(ctxt->regs, buffer); 274 - if (!res) { 275 - ctxt->fi.vector = X86_TRAP_PF; 276 - ctxt->fi.error_code = X86_PF_INSTR | X86_PF_USER; 277 - ctxt->fi.cr2 = ctxt->regs->ip; 278 - return ES_EXCEPTION; 279 - } 280 - 281 - if (!insn_decode(&ctxt->insn, ctxt->regs, buffer, res)) 282 - return ES_DECODE_FAILED; 283 - } else { 284 - res = vc_fetch_insn_kernel(ctxt, buffer); 285 - if (res) { 286 - ctxt->fi.vector = X86_TRAP_PF; 287 - ctxt->fi.error_code = X86_PF_INSTR; 288 - ctxt->fi.cr2 = ctxt->regs->ip; 289 - return ES_EXCEPTION; 290 - } 291 - 292 - insn_init(&ctxt->insn, buffer, MAX_INSN_SIZE, 1); 293 - insn_get_length(&ctxt->insn); 271 + res = insn_fetch_from_user_inatomic(ctxt->regs, buffer); 272 + if (!res) { 273 + ctxt->fi.vector = X86_TRAP_PF; 274 + ctxt->fi.error_code = X86_PF_INSTR | X86_PF_USER; 275 + ctxt->fi.cr2 = ctxt->regs->ip; 276 + return ES_EXCEPTION; 294 277 } 295 278 296 - ret = ctxt->insn.immediate.got ? ES_OK : ES_DECODE_FAILED; 279 + if (!insn_decode_from_regs(&ctxt->insn, ctxt->regs, buffer, res)) 280 + return ES_DECODE_FAILED; 297 281 298 - return ret; 282 + if (ctxt->insn.immediate.got) 283 + return ES_OK; 284 + else 285 + return ES_DECODE_FAILED; 286 + } 287 + 288 + static enum es_result __vc_decode_kern_insn(struct es_em_ctxt *ctxt) 289 + { 290 + char buffer[MAX_INSN_SIZE]; 291 + int res, ret; 292 + 293 + res = vc_fetch_insn_kernel(ctxt, buffer); 294 + if (res) { 295 + ctxt->fi.vector = X86_TRAP_PF; 296 + ctxt->fi.error_code = X86_PF_INSTR; 297 + ctxt->fi.cr2 = ctxt->regs->ip; 298 + return ES_EXCEPTION; 299 + } 300 + 301 + ret = insn_decode(&ctxt->insn, buffer, MAX_INSN_SIZE, INSN_MODE_64); 302 + if (ret < 0) 303 + return ES_DECODE_FAILED; 304 + else 305 + return ES_OK; 306 + } 307 + 308 + static enum es_result vc_decode_insn(struct es_em_ctxt *ctxt) 309 + { 310 + if (user_mode(ctxt->regs)) 311 + return __vc_decode_user_insn(ctxt); 312 + else 313 + return __vc_decode_kern_insn(ctxt); 299 314 } 300 315 301 316 static enum es_result vc_write_mem(struct es_em_ctxt *ctxt,
+58 -56
arch/x86/kernel/smpboot.c
··· 458 458 return false; 459 459 } 460 460 461 - /* 462 - * Define snc_cpu[] for SNC (Sub-NUMA Cluster) CPUs. 463 - * 464 - * These are Intel CPUs that enumerate an LLC that is shared by 465 - * multiple NUMA nodes. The LLC on these systems is shared for 466 - * off-package data access but private to the NUMA node (half 467 - * of the package) for on-package access. 468 - * 469 - * CPUID (the source of the information about the LLC) can only 470 - * enumerate the cache as being shared *or* unshared, but not 471 - * this particular configuration. The CPU in this case enumerates 472 - * the cache to be shared across the entire package (spanning both 473 - * NUMA nodes). 474 - */ 475 - 476 - static const struct x86_cpu_id snc_cpu[] = { 477 - X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_X, NULL), 478 - {} 479 - }; 480 - 481 - static bool match_llc(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o) 461 + static bool match_die(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o) 482 462 { 483 - int cpu1 = c->cpu_index, cpu2 = o->cpu_index; 484 - 485 - /* Do not match if we do not have a valid APICID for cpu: */ 486 - if (per_cpu(cpu_llc_id, cpu1) == BAD_APICID) 487 - return false; 488 - 489 - /* Do not match if LLC id does not match: */ 490 - if (per_cpu(cpu_llc_id, cpu1) != per_cpu(cpu_llc_id, cpu2)) 491 - return false; 492 - 493 - /* 494 - * Allow the SNC topology without warning. Return of false 495 - * means 'c' does not share the LLC of 'o'. This will be 496 - * reflected to userspace. 497 - */ 498 - if (!topology_same_node(c, o) && x86_match_cpu(snc_cpu)) 499 - return false; 500 - 501 - return topology_sane(c, o, "llc"); 463 + if (c->phys_proc_id == o->phys_proc_id && 464 + c->cpu_die_id == o->cpu_die_id) 465 + return true; 466 + return false; 502 467 } 503 468 504 469 /* ··· 478 513 return false; 479 514 } 480 515 481 - static bool match_die(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o) 516 + /* 517 + * Define intel_cod_cpu[] for Intel COD (Cluster-on-Die) CPUs. 518 + * 519 + * Any Intel CPU that has multiple nodes per package and does not 520 + * match intel_cod_cpu[] has the SNC (Sub-NUMA Cluster) topology. 521 + * 522 + * When in SNC mode, these CPUs enumerate an LLC that is shared 523 + * by multiple NUMA nodes. The LLC is shared for off-package data 524 + * access but private to the NUMA node (half of the package) for 525 + * on-package access. CPUID (the source of the information about 526 + * the LLC) can only enumerate the cache as shared or unshared, 527 + * but not this particular configuration. 528 + */ 529 + 530 + static const struct x86_cpu_id intel_cod_cpu[] = { 531 + X86_MATCH_INTEL_FAM6_MODEL(HASWELL_X, 0), /* COD */ 532 + X86_MATCH_INTEL_FAM6_MODEL(BROADWELL_X, 0), /* COD */ 533 + X86_MATCH_INTEL_FAM6_MODEL(ANY, 1), /* SNC */ 534 + {} 535 + }; 536 + 537 + static bool match_llc(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o) 482 538 { 483 - if ((c->phys_proc_id == o->phys_proc_id) && 484 - (c->cpu_die_id == o->cpu_die_id)) 485 - return true; 486 - return false; 539 + const struct x86_cpu_id *id = x86_match_cpu(intel_cod_cpu); 540 + int cpu1 = c->cpu_index, cpu2 = o->cpu_index; 541 + bool intel_snc = id && id->driver_data; 542 + 543 + /* Do not match if we do not have a valid APICID for cpu: */ 544 + if (per_cpu(cpu_llc_id, cpu1) == BAD_APICID) 545 + return false; 546 + 547 + /* Do not match if LLC id does not match: */ 548 + if (per_cpu(cpu_llc_id, cpu1) != per_cpu(cpu_llc_id, cpu2)) 549 + return false; 550 + 551 + /* 552 + * Allow the SNC topology without warning. Return of false 553 + * means 'c' does not share the LLC of 'o'. This will be 554 + * reflected to userspace. 555 + */ 556 + if (match_pkg(c, o) && !topology_same_node(c, o) && intel_snc) 557 + return false; 558 + 559 + return topology_sane(c, o, "llc"); 487 560 } 488 561 489 562 ··· 595 592 for_each_cpu(i, cpu_sibling_setup_mask) { 596 593 o = &cpu_data(i); 597 594 595 + if (match_pkg(c, o) && !topology_same_node(c, o)) 596 + x86_has_numa_in_package = true; 597 + 598 598 if ((i == cpu) || (has_smt && match_smt(c, o))) 599 599 link_mask(topology_sibling_cpumask, cpu, i); 600 600 601 601 if ((i == cpu) || (has_mp && match_llc(c, o))) 602 602 link_mask(cpu_llc_shared_mask, cpu, i); 603 603 604 + if ((i == cpu) || (has_mp && match_die(c, o))) 605 + link_mask(topology_die_cpumask, cpu, i); 604 606 } 607 + 608 + threads = cpumask_weight(topology_sibling_cpumask(cpu)); 609 + if (threads > __max_smt_threads) 610 + __max_smt_threads = threads; 605 611 606 612 /* 607 613 * This needs a separate iteration over the cpus because we rely on all ··· 625 613 /* 626 614 * Does this new cpu bringup a new core? 627 615 */ 628 - if (cpumask_weight( 629 - topology_sibling_cpumask(cpu)) == 1) { 616 + if (threads == 1) { 630 617 /* 631 618 * for each core in package, increment 632 619 * the booted_cores for this new cpu ··· 642 631 } else if (i != cpu && !c->booted_cores) 643 632 c->booted_cores = cpu_data(i).booted_cores; 644 633 } 645 - if (match_pkg(c, o) && !topology_same_node(c, o)) 646 - x86_has_numa_in_package = true; 647 - 648 - if ((i == cpu) || (has_mp && match_die(c, o))) 649 - link_mask(topology_die_cpumask, cpu, i); 650 634 } 651 - 652 - threads = cpumask_weight(topology_sibling_cpumask(cpu)); 653 - if (threads > __max_smt_threads) 654 - __max_smt_threads = threads; 655 635 } 656 636 657 637 /* maps the cpu to the sched domain representing multi-core */
+2 -2
arch/x86/kernel/static_call.c
··· 34 34 break; 35 35 36 36 case NOP: 37 - code = ideal_nops[NOP_ATOMIC5]; 37 + code = x86_nops[5]; 38 38 break; 39 39 40 40 case JMP: ··· 66 66 return; 67 67 } else { 68 68 if (opcode == CALL_INSN_OPCODE || 69 - !memcmp(insn, ideal_nops[NOP_ATOMIC5], 5) || 69 + !memcmp(insn, x86_nops[5], 5) || 70 70 !memcmp(insn, xor5rax, 5)) 71 71 return; 72 72 }
+1 -7
arch/x86/kernel/tls.c
··· 164 164 savesegment(fs, sel); 165 165 if (sel == modified_sel) 166 166 loadsegment(fs, sel); 167 + #endif 167 168 168 169 savesegment(gs, sel); 169 170 if (sel == modified_sel) 170 171 load_gs_index(sel); 171 - #endif 172 - 173 - #ifdef CONFIG_X86_32_LAZY_GS 174 - savesegment(gs, sel); 175 - if (sel == modified_sel) 176 - loadsegment(gs, sel); 177 - #endif 178 172 } else { 179 173 #ifdef CONFIG_X86_64 180 174 if (p->thread.fsindex == modified_sel)
+4 -6
arch/x86/kernel/traps.c
··· 498 498 { 499 499 u8 insn_buf[MAX_INSN_SIZE]; 500 500 struct insn insn; 501 + int ret; 501 502 502 503 if (copy_from_kernel_nofault(insn_buf, (void *)regs->ip, 503 504 MAX_INSN_SIZE)) 504 505 return GP_NO_HINT; 505 506 506 - kernel_insn_init(&insn, insn_buf, MAX_INSN_SIZE); 507 - insn_get_modrm(&insn); 508 - insn_get_sib(&insn); 507 + ret = insn_decode_kernel(&insn, insn_buf); 508 + if (ret < 0) 509 + return GP_NO_HINT; 509 510 510 511 *addr = (unsigned long)insn_get_addr_ref(&insn, regs); 511 512 if (*addr == -1UL) ··· 889 888 */ 890 889 if ((dr6 & DR_STEP) && is_sysenter_singlestep(regs)) 891 890 dr6 &= ~DR_STEP; 892 - 893 - if (kprobe_debug_handler(regs)) 894 - goto out; 895 891 896 892 /* 897 893 * The kernel doesn't use INT1
+1 -1
arch/x86/kernel/umip.c
··· 356 356 if (!nr_copied) 357 357 return false; 358 358 359 - if (!insn_decode(&insn, regs, buf, nr_copied)) 359 + if (!insn_decode_from_regs(&insn, regs, buf, nr_copied)) 360 360 return false; 361 361 362 362 umip_inst = identify_insn(&insn);
+4 -4
arch/x86/kernel/uprobes.c
··· 276 276 277 277 static int uprobe_init_insn(struct arch_uprobe *auprobe, struct insn *insn, bool x86_64) 278 278 { 279 + enum insn_mode m = x86_64 ? INSN_MODE_64 : INSN_MODE_32; 279 280 u32 volatile *good_insns; 281 + int ret; 280 282 281 - insn_init(insn, auprobe->insn, sizeof(auprobe->insn), x86_64); 282 - /* has the side-effect of processing the entire instruction */ 283 - insn_get_length(insn); 284 - if (!insn_complete(insn)) 283 + ret = insn_decode(insn, auprobe->insn, sizeof(auprobe->insn), m); 284 + if (ret < 0) 285 285 return -ENOEXEC; 286 286 287 287 if (is_prefix_bad(insn))
+1 -1
arch/x86/lib/inat.c
··· 4 4 * 5 5 * Written by Masami Hiramatsu <mhiramat@redhat.com> 6 6 */ 7 - #include <asm/insn.h> 7 + #include <asm/insn.h> /* __ignore_sync_check__ */ 8 8 9 9 /* Attribute tables are generated from opcode map */ 10 10 #include "inat-tables.c"
+24 -20
arch/x86/lib/insn-eval.c
··· 404 404 case INAT_SEG_REG_FS: 405 405 return (unsigned short)(regs->fs & 0xffff); 406 406 case INAT_SEG_REG_GS: 407 - /* 408 - * GS may or may not be in regs as per CONFIG_X86_32_LAZY_GS. 409 - * The macro below takes care of both cases. 410 - */ 411 407 return get_user_gs(regs); 412 408 case INAT_SEG_REG_IGNORE: 413 409 default: ··· 924 928 static int get_eff_addr_reg(struct insn *insn, struct pt_regs *regs, 925 929 int *regoff, long *eff_addr) 926 930 { 927 - insn_get_modrm(insn); 931 + int ret; 928 932 929 - if (!insn->modrm.nbytes) 930 - return -EINVAL; 933 + ret = insn_get_modrm(insn); 934 + if (ret) 935 + return ret; 931 936 932 937 if (X86_MODRM_MOD(insn->modrm.value) != 3) 933 938 return -EINVAL; ··· 974 977 int *regoff, long *eff_addr) 975 978 { 976 979 long tmp; 980 + int ret; 977 981 978 982 if (insn->addr_bytes != 8 && insn->addr_bytes != 4) 979 983 return -EINVAL; 980 984 981 - insn_get_modrm(insn); 982 - 983 - if (!insn->modrm.nbytes) 984 - return -EINVAL; 985 + ret = insn_get_modrm(insn); 986 + if (ret) 987 + return ret; 985 988 986 989 if (X86_MODRM_MOD(insn->modrm.value) > 2) 987 990 return -EINVAL; ··· 1103 1106 * @base_offset will have a register, as an offset from the base of pt_regs, 1104 1107 * that can be used to resolve the associated segment. 1105 1108 * 1106 - * -EINVAL on error. 1109 + * Negative value on error. 1107 1110 */ 1108 1111 static int get_eff_addr_sib(struct insn *insn, struct pt_regs *regs, 1109 1112 int *base_offset, long *eff_addr) 1110 1113 { 1111 1114 long base, indx; 1112 1115 int indx_offset; 1116 + int ret; 1113 1117 1114 1118 if (insn->addr_bytes != 8 && insn->addr_bytes != 4) 1115 1119 return -EINVAL; 1116 1120 1117 - insn_get_modrm(insn); 1121 + ret = insn_get_modrm(insn); 1122 + if (ret) 1123 + return ret; 1118 1124 1119 1125 if (!insn->modrm.nbytes) 1120 1126 return -EINVAL; ··· 1125 1125 if (X86_MODRM_MOD(insn->modrm.value) > 2) 1126 1126 return -EINVAL; 1127 1127 1128 - insn_get_sib(insn); 1128 + ret = insn_get_sib(insn); 1129 + if (ret) 1130 + return ret; 1129 1131 1130 1132 if (!insn->sib.nbytes) 1131 1133 return -EINVAL; ··· 1196 1194 short eff_addr; 1197 1195 long tmp; 1198 1196 1199 - insn_get_modrm(insn); 1200 - insn_get_displacement(insn); 1197 + if (insn_get_displacement(insn)) 1198 + goto out; 1201 1199 1202 1200 if (insn->addr_bytes != 2) 1203 1201 goto out; ··· 1494 1492 } 1495 1493 1496 1494 /** 1497 - * insn_decode() - Decode an instruction 1495 + * insn_decode_from_regs() - Decode an instruction 1498 1496 * @insn: Structure to store decoded instruction 1499 1497 * @regs: Structure with register values as seen when entering kernel mode 1500 1498 * @buf: Buffer containing the instruction bytes ··· 1507 1505 * 1508 1506 * True if instruction was decoded, False otherwise. 1509 1507 */ 1510 - bool insn_decode(struct insn *insn, struct pt_regs *regs, 1511 - unsigned char buf[MAX_INSN_SIZE], int buf_size) 1508 + bool insn_decode_from_regs(struct insn *insn, struct pt_regs *regs, 1509 + unsigned char buf[MAX_INSN_SIZE], int buf_size) 1512 1510 { 1513 1511 int seg_defs; 1514 1512 ··· 1531 1529 insn->addr_bytes = INSN_CODE_SEG_ADDR_SZ(seg_defs); 1532 1530 insn->opnd_bytes = INSN_CODE_SEG_OPND_SZ(seg_defs); 1533 1531 1534 - insn_get_length(insn); 1532 + if (insn_get_length(insn)) 1533 + return false; 1534 + 1535 1535 if (buf_size < insn->length) 1536 1536 return false; 1537 1537
+182 -48
arch/x86/lib/insn.c
··· 11 11 #else 12 12 #include <string.h> 13 13 #endif 14 - #include <asm/inat.h> 15 - #include <asm/insn.h> 14 + #include <asm/inat.h> /*__ignore_sync_check__ */ 15 + #include <asm/insn.h> /* __ignore_sync_check__ */ 16 16 17 - #include <asm/emulate_prefix.h> 17 + #include <linux/errno.h> 18 + #include <linux/kconfig.h> 19 + 20 + #include <asm/emulate_prefix.h> /* __ignore_sync_check__ */ 18 21 19 22 #define leXX_to_cpu(t, r) \ 20 23 ({ \ ··· 54 51 * insn_init() - initialize struct insn 55 52 * @insn: &struct insn to be initialized 56 53 * @kaddr: address (in kernel memory) of instruction (or copy thereof) 54 + * @buf_len: length of the insn buffer at @kaddr 57 55 * @x86_64: !0 for 64-bit kernel or 64-bit app 58 56 */ 59 57 void insn_init(struct insn *insn, const void *kaddr, int buf_len, int x86_64) ··· 115 111 * Populates the @insn->prefixes bitmap, and updates @insn->next_byte 116 112 * to point to the (first) opcode. No effect if @insn->prefixes.got 117 113 * is already set. 114 + * 115 + * * Returns: 116 + * 0: on success 117 + * < 0: on error 118 118 */ 119 - void insn_get_prefixes(struct insn *insn) 119 + int insn_get_prefixes(struct insn *insn) 120 120 { 121 121 struct insn_field *prefixes = &insn->prefixes; 122 122 insn_attr_t attr; ··· 128 120 int i, nb; 129 121 130 122 if (prefixes->got) 131 - return; 123 + return 0; 132 124 133 125 insn_get_emulate_prefix(insn); 134 126 ··· 238 230 239 231 prefixes->got = 1; 240 232 233 + return 0; 234 + 241 235 err_out: 242 - return; 236 + return -ENODATA; 243 237 } 244 238 245 239 /** ··· 253 243 * If necessary, first collects any preceding (prefix) bytes. 254 244 * Sets @insn->opcode.value = opcode1. No effect if @insn->opcode.got 255 245 * is already 1. 246 + * 247 + * Returns: 248 + * 0: on success 249 + * < 0: on error 256 250 */ 257 - void insn_get_opcode(struct insn *insn) 251 + int insn_get_opcode(struct insn *insn) 258 252 { 259 253 struct insn_field *opcode = &insn->opcode; 254 + int pfx_id, ret; 260 255 insn_byte_t op; 261 - int pfx_id; 256 + 262 257 if (opcode->got) 263 - return; 264 - if (!insn->prefixes.got) 265 - insn_get_prefixes(insn); 258 + return 0; 259 + 260 + if (!insn->prefixes.got) { 261 + ret = insn_get_prefixes(insn); 262 + if (ret) 263 + return ret; 264 + } 266 265 267 266 /* Get first opcode */ 268 267 op = get_next(insn_byte_t, insn); ··· 286 267 insn->attr = inat_get_avx_attribute(op, m, p); 287 268 if ((inat_must_evex(insn->attr) && !insn_is_evex(insn)) || 288 269 (!inat_accept_vex(insn->attr) && 289 - !inat_is_group(insn->attr))) 290 - insn->attr = 0; /* This instruction is bad */ 291 - goto end; /* VEX has only 1 byte for opcode */ 270 + !inat_is_group(insn->attr))) { 271 + /* This instruction is bad */ 272 + insn->attr = 0; 273 + return -EINVAL; 274 + } 275 + /* VEX has only 1 byte for opcode */ 276 + goto end; 292 277 } 293 278 294 279 insn->attr = inat_get_opcode_attribute(op); ··· 303 280 pfx_id = insn_last_prefix_id(insn); 304 281 insn->attr = inat_get_escape_attribute(op, pfx_id, insn->attr); 305 282 } 306 - if (inat_must_vex(insn->attr)) 307 - insn->attr = 0; /* This instruction is bad */ 283 + 284 + if (inat_must_vex(insn->attr)) { 285 + /* This instruction is bad */ 286 + insn->attr = 0; 287 + return -EINVAL; 288 + } 308 289 end: 309 290 opcode->got = 1; 291 + return 0; 310 292 311 293 err_out: 312 - return; 294 + return -ENODATA; 313 295 } 314 296 315 297 /** ··· 324 296 * Populates @insn->modrm and updates @insn->next_byte to point past the 325 297 * ModRM byte, if any. If necessary, first collects the preceding bytes 326 298 * (prefixes and opcode(s)). No effect if @insn->modrm.got is already 1. 299 + * 300 + * Returns: 301 + * 0: on success 302 + * < 0: on error 327 303 */ 328 - void insn_get_modrm(struct insn *insn) 304 + int insn_get_modrm(struct insn *insn) 329 305 { 330 306 struct insn_field *modrm = &insn->modrm; 331 307 insn_byte_t pfx_id, mod; 308 + int ret; 309 + 332 310 if (modrm->got) 333 - return; 334 - if (!insn->opcode.got) 335 - insn_get_opcode(insn); 311 + return 0; 312 + 313 + if (!insn->opcode.got) { 314 + ret = insn_get_opcode(insn); 315 + if (ret) 316 + return ret; 317 + } 336 318 337 319 if (inat_has_modrm(insn->attr)) { 338 320 mod = get_next(insn_byte_t, insn); ··· 351 313 pfx_id = insn_last_prefix_id(insn); 352 314 insn->attr = inat_get_group_attribute(mod, pfx_id, 353 315 insn->attr); 354 - if (insn_is_avx(insn) && !inat_accept_vex(insn->attr)) 355 - insn->attr = 0; /* This is bad */ 316 + if (insn_is_avx(insn) && !inat_accept_vex(insn->attr)) { 317 + /* Bad insn */ 318 + insn->attr = 0; 319 + return -EINVAL; 320 + } 356 321 } 357 322 } 358 323 359 324 if (insn->x86_64 && inat_is_force64(insn->attr)) 360 325 insn->opnd_bytes = 8; 326 + 361 327 modrm->got = 1; 328 + return 0; 362 329 363 330 err_out: 364 - return; 331 + return -ENODATA; 365 332 } 366 333 367 334 ··· 380 337 int insn_rip_relative(struct insn *insn) 381 338 { 382 339 struct insn_field *modrm = &insn->modrm; 340 + int ret; 383 341 384 342 if (!insn->x86_64) 385 343 return 0; 386 - if (!modrm->got) 387 - insn_get_modrm(insn); 344 + 345 + if (!modrm->got) { 346 + ret = insn_get_modrm(insn); 347 + if (ret) 348 + return 0; 349 + } 388 350 /* 389 351 * For rip-relative instructions, the mod field (top 2 bits) 390 352 * is zero and the r/m field (bottom 3 bits) is 0x5. ··· 403 355 * 404 356 * If necessary, first collects the instruction up to and including the 405 357 * ModRM byte. 358 + * 359 + * Returns: 360 + * 0: if decoding succeeded 361 + * < 0: otherwise. 406 362 */ 407 - void insn_get_sib(struct insn *insn) 363 + int insn_get_sib(struct insn *insn) 408 364 { 409 365 insn_byte_t modrm; 366 + int ret; 410 367 411 368 if (insn->sib.got) 412 - return; 413 - if (!insn->modrm.got) 414 - insn_get_modrm(insn); 369 + return 0; 370 + 371 + if (!insn->modrm.got) { 372 + ret = insn_get_modrm(insn); 373 + if (ret) 374 + return ret; 375 + } 376 + 415 377 if (insn->modrm.nbytes) { 416 378 modrm = insn->modrm.bytes[0]; 417 379 if (insn->addr_bytes != 2 && ··· 432 374 } 433 375 insn->sib.got = 1; 434 376 377 + return 0; 378 + 435 379 err_out: 436 - return; 380 + return -ENODATA; 437 381 } 438 382 439 383 ··· 446 386 * If necessary, first collects the instruction up to and including the 447 387 * SIB byte. 448 388 * Displacement value is sign-expanded. 389 + * 390 + * * Returns: 391 + * 0: if decoding succeeded 392 + * < 0: otherwise. 449 393 */ 450 - void insn_get_displacement(struct insn *insn) 394 + int insn_get_displacement(struct insn *insn) 451 395 { 452 396 insn_byte_t mod, rm, base; 397 + int ret; 453 398 454 399 if (insn->displacement.got) 455 - return; 456 - if (!insn->sib.got) 457 - insn_get_sib(insn); 400 + return 0; 401 + 402 + if (!insn->sib.got) { 403 + ret = insn_get_sib(insn); 404 + if (ret) 405 + return ret; 406 + } 407 + 458 408 if (insn->modrm.nbytes) { 459 409 /* 460 410 * Interpreting the modrm byte: ··· 506 436 } 507 437 out: 508 438 insn->displacement.got = 1; 439 + return 0; 509 440 510 441 err_out: 511 - return; 442 + return -ENODATA; 512 443 } 513 444 514 445 /* Decode moffset16/32/64. Return 0 if failed */ ··· 608 537 } 609 538 610 539 /** 611 - * insn_get_immediate() - Get the immediates of instruction 540 + * insn_get_immediate() - Get the immediate in an instruction 612 541 * @insn: &struct insn containing instruction 613 542 * 614 543 * If necessary, first collects the instruction up to and including the 615 544 * displacement bytes. 616 545 * Basically, most of immediates are sign-expanded. Unsigned-value can be 617 - * get by bit masking with ((1 << (nbytes * 8)) - 1) 546 + * computed by bit masking with ((1 << (nbytes * 8)) - 1) 547 + * 548 + * Returns: 549 + * 0: on success 550 + * < 0: on error 618 551 */ 619 - void insn_get_immediate(struct insn *insn) 552 + int insn_get_immediate(struct insn *insn) 620 553 { 554 + int ret; 555 + 621 556 if (insn->immediate.got) 622 - return; 623 - if (!insn->displacement.got) 624 - insn_get_displacement(insn); 557 + return 0; 558 + 559 + if (!insn->displacement.got) { 560 + ret = insn_get_displacement(insn); 561 + if (ret) 562 + return ret; 563 + } 625 564 626 565 if (inat_has_moffset(insn->attr)) { 627 566 if (!__get_moffset(insn)) ··· 678 597 } 679 598 done: 680 599 insn->immediate.got = 1; 600 + return 0; 681 601 682 602 err_out: 683 - return; 603 + return -ENODATA; 684 604 } 685 605 686 606 /** ··· 690 608 * 691 609 * If necessary, first collects the instruction up to and including the 692 610 * immediates bytes. 693 - */ 694 - void insn_get_length(struct insn *insn) 611 + * 612 + * Returns: 613 + * - 0 on success 614 + * - < 0 on error 615 + */ 616 + int insn_get_length(struct insn *insn) 695 617 { 618 + int ret; 619 + 696 620 if (insn->length) 697 - return; 698 - if (!insn->immediate.got) 699 - insn_get_immediate(insn); 621 + return 0; 622 + 623 + if (!insn->immediate.got) { 624 + ret = insn_get_immediate(insn); 625 + if (ret) 626 + return ret; 627 + } 628 + 700 629 insn->length = (unsigned char)((unsigned long)insn->next_byte 701 630 - (unsigned long)insn->kaddr); 631 + 632 + return 0; 633 + } 634 + 635 + /* Ensure this instruction is decoded completely */ 636 + static inline int insn_complete(struct insn *insn) 637 + { 638 + return insn->opcode.got && insn->modrm.got && insn->sib.got && 639 + insn->displacement.got && insn->immediate.got; 640 + } 641 + 642 + /** 643 + * insn_decode() - Decode an x86 instruction 644 + * @insn: &struct insn to be initialized 645 + * @kaddr: address (in kernel memory) of instruction (or copy thereof) 646 + * @buf_len: length of the insn buffer at @kaddr 647 + * @m: insn mode, see enum insn_mode 648 + * 649 + * Returns: 650 + * 0: if decoding succeeded 651 + * < 0: otherwise. 652 + */ 653 + int insn_decode(struct insn *insn, const void *kaddr, int buf_len, enum insn_mode m) 654 + { 655 + int ret; 656 + 657 + /* #define INSN_MODE_KERN -1 __ignore_sync_check__ mode is only valid in the kernel */ 658 + 659 + if (m == INSN_MODE_KERN) 660 + insn_init(insn, kaddr, buf_len, IS_ENABLED(CONFIG_X86_64)); 661 + else 662 + insn_init(insn, kaddr, buf_len, m == INSN_MODE_64); 663 + 664 + ret = insn_get_length(insn); 665 + if (ret) 666 + return ret; 667 + 668 + if (insn_complete(insn)) 669 + return 0; 670 + 671 + return -EINVAL; 702 672 }
+52 -13
arch/x86/lib/retpoline.S
··· 10 10 #include <asm/unwind_hints.h> 11 11 #include <asm/frame.h> 12 12 13 - .macro THUNK reg 14 13 .section .text.__x86.indirect_thunk 15 14 16 - .align 32 17 - SYM_FUNC_START(__x86_indirect_thunk_\reg) 18 - JMP_NOSPEC \reg 19 - SYM_FUNC_END(__x86_indirect_thunk_\reg) 20 - 21 - SYM_FUNC_START_NOALIGN(__x86_retpoline_\reg) 15 + .macro RETPOLINE reg 22 16 ANNOTATE_INTRA_FUNCTION_CALL 23 - call .Ldo_rop_\@ 17 + call .Ldo_rop_\@ 24 18 .Lspec_trap_\@: 25 19 UNWIND_HINT_EMPTY 26 20 pause 27 21 lfence 28 - jmp .Lspec_trap_\@ 22 + jmp .Lspec_trap_\@ 29 23 .Ldo_rop_\@: 30 - mov %\reg, (%_ASM_SP) 24 + mov %\reg, (%_ASM_SP) 31 25 UNWIND_HINT_FUNC 32 26 ret 33 - SYM_FUNC_END(__x86_retpoline_\reg) 27 + .endm 28 + 29 + .macro THUNK reg 30 + 31 + .align 32 32 + 33 + SYM_FUNC_START(__x86_indirect_thunk_\reg) 34 + 35 + ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; jmp *%\reg), \ 36 + __stringify(RETPOLINE \reg), X86_FEATURE_RETPOLINE, \ 37 + __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; jmp *%\reg), X86_FEATURE_RETPOLINE_AMD 38 + 39 + SYM_FUNC_END(__x86_indirect_thunk_\reg) 40 + 41 + .endm 42 + 43 + /* 44 + * This generates .altinstr_replacement symbols for use by objtool. They, 45 + * however, must not actually live in .altinstr_replacement since that will be 46 + * discarded after init, but module alternatives will also reference these 47 + * symbols. 48 + * 49 + * Their names matches the "__x86_indirect_" prefix to mark them as retpolines. 50 + */ 51 + .macro ALT_THUNK reg 52 + 53 + .align 1 54 + 55 + SYM_FUNC_START_NOALIGN(__x86_indirect_alt_call_\reg) 56 + ANNOTATE_RETPOLINE_SAFE 57 + 1: call *%\reg 58 + 2: .skip 5-(2b-1b), 0x90 59 + SYM_FUNC_END(__x86_indirect_alt_call_\reg) 60 + 61 + SYM_FUNC_START_NOALIGN(__x86_indirect_alt_jmp_\reg) 62 + ANNOTATE_RETPOLINE_SAFE 63 + 1: jmp *%\reg 64 + 2: .skip 5-(2b-1b), 0x90 65 + SYM_FUNC_END(__x86_indirect_alt_jmp_\reg) 34 66 35 67 .endm 36 68 ··· 80 48 81 49 #define __EXPORT_THUNK(sym) _ASM_NOKPROBE(sym); EXPORT_SYMBOL(sym) 82 50 #define EXPORT_THUNK(reg) __EXPORT_THUNK(__x86_indirect_thunk_ ## reg) 83 - #define EXPORT_RETPOLINE(reg) __EXPORT_THUNK(__x86_retpoline_ ## reg) 84 51 85 52 #undef GEN 86 53 #define GEN(reg) THUNK reg ··· 90 59 #include <asm/GEN-for-each-reg.h> 91 60 92 61 #undef GEN 93 - #define GEN(reg) EXPORT_RETPOLINE(reg) 62 + #define GEN(reg) ALT_THUNK reg 63 + #include <asm/GEN-for-each-reg.h> 64 + 65 + #undef GEN 66 + #define GEN(reg) __EXPORT_THUNK(__x86_indirect_alt_call_ ## reg) 67 + #include <asm/GEN-for-each-reg.h> 68 + 69 + #undef GEN 70 + #define GEN(reg) __EXPORT_THUNK(__x86_indirect_alt_jmp_ ## reg) 94 71 #include <asm/GEN-for-each-reg.h>
+5 -5
arch/x86/net/bpf_jit_comp.c
··· 282 282 /* BPF trampoline can be made to work without these nops, 283 283 * but let's waste 5 bytes for now and optimize later 284 284 */ 285 - memcpy(prog, ideal_nops[NOP_ATOMIC5], cnt); 285 + memcpy(prog, x86_nops[5], cnt); 286 286 prog += cnt; 287 287 if (!ebpf_from_cbpf) { 288 288 if (tail_call_reachable && !is_subprog) ··· 330 330 void *old_addr, void *new_addr, 331 331 const bool text_live) 332 332 { 333 - const u8 *nop_insn = ideal_nops[NOP_ATOMIC5]; 333 + const u8 *nop_insn = x86_nops[5]; 334 334 u8 old_insn[X86_PATCH_SIZE]; 335 335 u8 new_insn[X86_PATCH_SIZE]; 336 336 u8 *prog; ··· 560 560 if (stack_depth) 561 561 EMIT3_off32(0x48, 0x81, 0xC4, round_up(stack_depth, 8)); 562 562 563 - memcpy(prog, ideal_nops[NOP_ATOMIC5], X86_PATCH_SIZE); 563 + memcpy(prog, x86_nops[5], X86_PATCH_SIZE); 564 564 prog += X86_PATCH_SIZE; 565 565 /* out: */ 566 566 ··· 881 881 noplen = ASM_NOP_MAX; 882 882 883 883 for (i = 0; i < noplen; i++) 884 - EMIT1(ideal_nops[noplen][i]); 884 + EMIT1(x86_nops[noplen][i]); 885 885 len -= noplen; 886 886 } 887 887 ··· 2021 2021 /* remember return value in a stack for bpf prog to access */ 2022 2022 emit_stx(&prog, BPF_DW, BPF_REG_FP, BPF_REG_0, -8); 2023 2023 im->ip_after_call = prog; 2024 - memcpy(prog, ideal_nops[NOP_ATOMIC5], X86_PATCH_SIZE); 2024 + memcpy(prog, x86_nops[5], X86_PATCH_SIZE); 2025 2025 prog += X86_PATCH_SIZE; 2026 2026 } 2027 2027
-14
arch/x86/platform/pvh/head.S
··· 46 46 47 47 #define PVH_GDT_ENTRY_CS 1 48 48 #define PVH_GDT_ENTRY_DS 2 49 - #define PVH_GDT_ENTRY_CANARY 3 50 49 #define PVH_CS_SEL (PVH_GDT_ENTRY_CS * 8) 51 50 #define PVH_DS_SEL (PVH_GDT_ENTRY_DS * 8) 52 - #define PVH_CANARY_SEL (PVH_GDT_ENTRY_CANARY * 8) 53 51 54 52 SYM_CODE_START_LOCAL(pvh_start_xen) 55 53 cld ··· 109 111 110 112 #else /* CONFIG_X86_64 */ 111 113 112 - /* Set base address in stack canary descriptor. */ 113 - movl $_pa(gdt_start),%eax 114 - movl $_pa(canary),%ecx 115 - movw %cx, (PVH_GDT_ENTRY_CANARY * 8) + 2(%eax) 116 - shrl $16, %ecx 117 - movb %cl, (PVH_GDT_ENTRY_CANARY * 8) + 4(%eax) 118 - movb %ch, (PVH_GDT_ENTRY_CANARY * 8) + 7(%eax) 119 - 120 - mov $PVH_CANARY_SEL,%eax 121 - mov %eax,%gs 122 - 123 114 call mk_early_pgtbl_32 124 115 125 116 mov $_pa(initial_page_table), %eax ··· 152 165 .quad GDT_ENTRY(0xc09a, 0, 0xfffff) /* PVH_CS_SEL */ 153 166 #endif 154 167 .quad GDT_ENTRY(0xc092, 0, 0xfffff) /* PVH_DS_SEL */ 155 - .quad GDT_ENTRY(0x4090, 0, 0x18) /* PVH_CANARY_SEL */ 156 168 SYM_DATA_END_LABEL(gdt_start, SYM_L_LOCAL, gdt_end) 157 169 158 170 .balign 16
+1 -5
arch/x86/power/cpu.c
··· 99 99 /* 100 100 * segment registers 101 101 */ 102 - #ifdef CONFIG_X86_32_LAZY_GS 103 102 savesegment(gs, ctxt->gs); 104 - #endif 105 103 #ifdef CONFIG_X86_64 106 - savesegment(gs, ctxt->gs); 107 104 savesegment(fs, ctxt->fs); 108 105 savesegment(ds, ctxt->ds); 109 106 savesegment(es, ctxt->es); ··· 229 232 wrmsrl(MSR_GS_BASE, ctxt->kernelmode_gs_base); 230 233 #else 231 234 loadsegment(fs, __KERNEL_PERCPU); 232 - loadsegment(gs, __KERNEL_STACK_CANARY); 233 235 #endif 234 236 235 237 /* Restore the TSS, RO GDT, LDT, and usermode-relevant MSRs. */ ··· 251 255 */ 252 256 wrmsrl(MSR_FS_BASE, ctxt->fs_base); 253 257 wrmsrl(MSR_KERNEL_GS_BASE, ctxt->usermode_gs_base); 254 - #elif defined(CONFIG_X86_32_LAZY_GS) 258 + #else 255 259 loadsegment(gs, ctxt->gs); 256 260 #endif 257 261
+6 -4
arch/x86/tools/insn_decoder_test.c
··· 120 120 121 121 while (fgets(line, BUFSIZE, stdin)) { 122 122 char copy[BUFSIZE], *s, *tab1, *tab2; 123 - int nb = 0; 123 + int nb = 0, ret; 124 124 unsigned int b; 125 125 126 126 if (line[0] == '<') { ··· 148 148 } else 149 149 break; 150 150 } 151 + 151 152 /* Decode an instruction */ 152 - insn_init(&insn, insn_buff, sizeof(insn_buff), x86_64); 153 - insn_get_length(&insn); 154 - if (insn.length != nb) { 153 + ret = insn_decode(&insn, insn_buff, sizeof(insn_buff), 154 + x86_64 ? INSN_MODE_64 : INSN_MODE_32); 155 + 156 + if (ret < 0 || insn.length != nb) { 155 157 warnings++; 156 158 pr_warn("Found an x86 instruction decoder bug, " 157 159 "please report this.\n", sym);
+4 -4
arch/x86/tools/insn_sanity.c
··· 218 218 219 219 int main(int argc, char **argv) 220 220 { 221 + int insns = 0, ret; 221 222 struct insn insn; 222 - int insns = 0; 223 223 int errors = 0; 224 224 unsigned long i; 225 225 unsigned char insn_buff[MAX_INSN_SIZE * 2]; ··· 237 237 continue; 238 238 239 239 /* Decode an instruction */ 240 - insn_init(&insn, insn_buff, sizeof(insn_buff), x86_64); 241 - insn_get_length(&insn); 240 + ret = insn_decode(&insn, insn_buff, sizeof(insn_buff), 241 + x86_64 ? INSN_MODE_64 : INSN_MODE_32); 242 242 243 243 if (insn.next_byte <= insn.kaddr || 244 244 insn.kaddr + MAX_INSN_SIZE < insn.next_byte) { 245 245 /* Access out-of-range memory */ 246 246 dump_stream(stderr, "Error: Found an access violation", i, insn_buff, &insn); 247 247 errors++; 248 - } else if (verbose && !insn_complete(&insn)) 248 + } else if (verbose && ret < 0) 249 249 dump_stream(stdout, "Info: Found an undecodable input", i, insn_buff, &insn); 250 250 else if (verbose >= 2) 251 251 dump_insn(stdout, &insn);
-1
arch/x86/xen/enlighten_pv.c
··· 1202 1202 pv_ops.cpu.write_gdt_entry = xen_write_gdt_entry_boot; 1203 1203 pv_ops.cpu.load_gdt = xen_load_gdt_boot; 1204 1204 1205 - setup_stack_canary_segment(cpu); 1206 1205 switch_to_new_gdt(cpu); 1207 1206 1208 1207 pv_ops.cpu.write_gdt_entry = xen_write_gdt_entry;
+5 -1
scripts/gcc-x86_32-has-stack-protector.sh
··· 1 1 #!/bin/sh 2 2 # SPDX-License-Identifier: GPL-2.0 3 3 4 - echo "int foo(void) { char X[200]; return 3; }" | $* -S -x c -c -m32 -O0 -fstack-protector - -o - 2> /dev/null | grep -q "%gs" 4 + # This requires GCC 8.1 or better. Specifically, we require 5 + # -mstack-protector-guard-reg, added by 6 + # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81708 7 + 8 + echo "int foo(void) { char X[200]; return 3; }" | $* -S -x c -c -m32 -O0 -fstack-protector -mstack-protector-guard-reg=fs -mstack-protector-guard-symbol=__stack_chk_guard - -o - 2> /dev/null | grep -q "%fs"
+1 -1
tools/arch/x86/include/asm/inat.h
··· 6 6 * 7 7 * Written by Masami Hiramatsu <mhiramat@redhat.com> 8 8 */ 9 - #include "inat_types.h" 9 + #include "inat_types.h" /* __ignore_sync_check__ */ 10 10 11 11 /* 12 12 * Internal bits. Don't use bitmasks directly, because these bits are
+20 -26
tools/arch/x86/include/asm/insn.h
··· 9 9 10 10 #include <asm/byteorder.h> 11 11 /* insn_attr_t is defined in inat.h */ 12 - #include "inat.h" 12 + #include "inat.h" /* __ignore_sync_check__ */ 13 13 14 14 #if defined(__BYTE_ORDER) ? __BYTE_ORDER == __LITTLE_ENDIAN : defined(__LITTLE_ENDIAN) 15 15 ··· 132 132 #define X86_VEX_M_MAX 0x1f /* VEX3.M Maximum value */ 133 133 134 134 extern void insn_init(struct insn *insn, const void *kaddr, int buf_len, int x86_64); 135 - extern void insn_get_prefixes(struct insn *insn); 136 - extern void insn_get_opcode(struct insn *insn); 137 - extern void insn_get_modrm(struct insn *insn); 138 - extern void insn_get_sib(struct insn *insn); 139 - extern void insn_get_displacement(struct insn *insn); 140 - extern void insn_get_immediate(struct insn *insn); 141 - extern void insn_get_length(struct insn *insn); 135 + extern int insn_get_prefixes(struct insn *insn); 136 + extern int insn_get_opcode(struct insn *insn); 137 + extern int insn_get_modrm(struct insn *insn); 138 + extern int insn_get_sib(struct insn *insn); 139 + extern int insn_get_displacement(struct insn *insn); 140 + extern int insn_get_immediate(struct insn *insn); 141 + extern int insn_get_length(struct insn *insn); 142 + 143 + enum insn_mode { 144 + INSN_MODE_32, 145 + INSN_MODE_64, 146 + /* Mode is determined by the current kernel build. */ 147 + INSN_MODE_KERN, 148 + INSN_NUM_MODES, 149 + }; 150 + 151 + extern int insn_decode(struct insn *insn, const void *kaddr, int buf_len, enum insn_mode m); 152 + 153 + #define insn_decode_kernel(_insn, _ptr) insn_decode((_insn), (_ptr), MAX_INSN_SIZE, INSN_MODE_KERN) 142 154 143 155 /* Attribute will be determined after getting ModRM (for opcode groups) */ 144 156 static inline void insn_get_attribute(struct insn *insn) ··· 160 148 161 149 /* Instruction uses RIP-relative addressing */ 162 150 extern int insn_rip_relative(struct insn *insn); 163 - 164 - /* Init insn for kernel text */ 165 - static inline void kernel_insn_init(struct insn *insn, 166 - const void *kaddr, int buf_len) 167 - { 168 - #ifdef CONFIG_X86_64 169 - insn_init(insn, kaddr, buf_len, 1); 170 - #else /* CONFIG_X86_32 */ 171 - insn_init(insn, kaddr, buf_len, 0); 172 - #endif 173 - } 174 151 175 152 static inline int insn_is_avx(struct insn *insn) 176 153 { ··· 178 177 static inline int insn_has_emulate_prefix(struct insn *insn) 179 178 { 180 179 return !!insn->emulate_prefix_size; 181 - } 182 - 183 - /* Ensure this instruction is decoded completely */ 184 - static inline int insn_complete(struct insn *insn) 185 - { 186 - return insn->opcode.got && insn->modrm.got && insn->sib.got && 187 - insn->displacement.got && insn->immediate.got; 188 180 } 189 181 190 182 static inline insn_byte_t insn_vex_m_bits(struct insn *insn)
+81
tools/arch/x86/include/asm/nops.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef _ASM_X86_NOPS_H 3 + #define _ASM_X86_NOPS_H 4 + 5 + /* 6 + * Define nops for use with alternative() and for tracing. 7 + */ 8 + 9 + #ifndef CONFIG_64BIT 10 + 11 + /* 12 + * Generic 32bit nops from GAS: 13 + * 14 + * 1: nop 15 + * 2: movl %esi,%esi 16 + * 3: leal 0x0(%esi),%esi 17 + * 4: leal 0x0(%esi,%eiz,1),%esi 18 + * 5: leal %ds:0x0(%esi,%eiz,1),%esi 19 + * 6: leal 0x0(%esi),%esi 20 + * 7: leal 0x0(%esi,%eiz,1),%esi 21 + * 8: leal %ds:0x0(%esi,%eiz,1),%esi 22 + * 23 + * Except 5 and 8, which are DS prefixed 4 and 7 resp, where GAS would emit 2 24 + * nop instructions. 25 + */ 26 + #define BYTES_NOP1 0x90 27 + #define BYTES_NOP2 0x89,0xf6 28 + #define BYTES_NOP3 0x8d,0x76,0x00 29 + #define BYTES_NOP4 0x8d,0x74,0x26,0x00 30 + #define BYTES_NOP5 0x3e,BYTES_NOP4 31 + #define BYTES_NOP6 0x8d,0xb6,0x00,0x00,0x00,0x00 32 + #define BYTES_NOP7 0x8d,0xb4,0x26,0x00,0x00,0x00,0x00 33 + #define BYTES_NOP8 0x3e,BYTES_NOP7 34 + 35 + #else 36 + 37 + /* 38 + * Generic 64bit nops from GAS: 39 + * 40 + * 1: nop 41 + * 2: osp nop 42 + * 3: nopl (%eax) 43 + * 4: nopl 0x00(%eax) 44 + * 5: nopl 0x00(%eax,%eax,1) 45 + * 6: osp nopl 0x00(%eax,%eax,1) 46 + * 7: nopl 0x00000000(%eax) 47 + * 8: nopl 0x00000000(%eax,%eax,1) 48 + */ 49 + #define BYTES_NOP1 0x90 50 + #define BYTES_NOP2 0x66,BYTES_NOP1 51 + #define BYTES_NOP3 0x0f,0x1f,0x00 52 + #define BYTES_NOP4 0x0f,0x1f,0x40,0x00 53 + #define BYTES_NOP5 0x0f,0x1f,0x44,0x00,0x00 54 + #define BYTES_NOP6 0x66,BYTES_NOP5 55 + #define BYTES_NOP7 0x0f,0x1f,0x80,0x00,0x00,0x00,0x00 56 + #define BYTES_NOP8 0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00 57 + 58 + #endif /* CONFIG_64BIT */ 59 + 60 + #ifdef __ASSEMBLY__ 61 + #define _ASM_MK_NOP(x) .byte x 62 + #else 63 + #define _ASM_MK_NOP(x) ".byte " __stringify(x) "\n" 64 + #endif 65 + 66 + #define ASM_NOP1 _ASM_MK_NOP(BYTES_NOP1) 67 + #define ASM_NOP2 _ASM_MK_NOP(BYTES_NOP2) 68 + #define ASM_NOP3 _ASM_MK_NOP(BYTES_NOP3) 69 + #define ASM_NOP4 _ASM_MK_NOP(BYTES_NOP4) 70 + #define ASM_NOP5 _ASM_MK_NOP(BYTES_NOP5) 71 + #define ASM_NOP6 _ASM_MK_NOP(BYTES_NOP6) 72 + #define ASM_NOP7 _ASM_MK_NOP(BYTES_NOP7) 73 + #define ASM_NOP8 _ASM_MK_NOP(BYTES_NOP8) 74 + 75 + #define ASM_NOP_MAX 8 76 + 77 + #ifndef __ASSEMBLY__ 78 + extern const unsigned char * const x86_nops[]; 79 + #endif 80 + 81 + #endif /* _ASM_X86_NOPS_H */
+1 -1
tools/arch/x86/lib/inat.c
··· 4 4 * 5 5 * Written by Masami Hiramatsu <mhiramat@redhat.com> 6 6 */ 7 - #include "../include/asm/insn.h" 7 + #include "../include/asm/insn.h" /* __ignore_sync_check__ */ 8 8 9 9 /* Attribute tables are generated from opcode map */ 10 10 #include "inat-tables.c"
+182 -48
tools/arch/x86/lib/insn.c
··· 11 11 #else 12 12 #include <string.h> 13 13 #endif 14 - #include "../include/asm/inat.h" 15 - #include "../include/asm/insn.h" 14 + #include "../include/asm/inat.h" /* __ignore_sync_check__ */ 15 + #include "../include/asm/insn.h" /* __ignore_sync_check__ */ 16 16 17 - #include "../include/asm/emulate_prefix.h" 17 + #include <linux/errno.h> 18 + #include <linux/kconfig.h> 19 + 20 + #include "../include/asm/emulate_prefix.h" /* __ignore_sync_check__ */ 18 21 19 22 #define leXX_to_cpu(t, r) \ 20 23 ({ \ ··· 54 51 * insn_init() - initialize struct insn 55 52 * @insn: &struct insn to be initialized 56 53 * @kaddr: address (in kernel memory) of instruction (or copy thereof) 54 + * @buf_len: length of the insn buffer at @kaddr 57 55 * @x86_64: !0 for 64-bit kernel or 64-bit app 58 56 */ 59 57 void insn_init(struct insn *insn, const void *kaddr, int buf_len, int x86_64) ··· 115 111 * Populates the @insn->prefixes bitmap, and updates @insn->next_byte 116 112 * to point to the (first) opcode. No effect if @insn->prefixes.got 117 113 * is already set. 114 + * 115 + * * Returns: 116 + * 0: on success 117 + * < 0: on error 118 118 */ 119 - void insn_get_prefixes(struct insn *insn) 119 + int insn_get_prefixes(struct insn *insn) 120 120 { 121 121 struct insn_field *prefixes = &insn->prefixes; 122 122 insn_attr_t attr; ··· 128 120 int i, nb; 129 121 130 122 if (prefixes->got) 131 - return; 123 + return 0; 132 124 133 125 insn_get_emulate_prefix(insn); 134 126 ··· 238 230 239 231 prefixes->got = 1; 240 232 233 + return 0; 234 + 241 235 err_out: 242 - return; 236 + return -ENODATA; 243 237 } 244 238 245 239 /** ··· 253 243 * If necessary, first collects any preceding (prefix) bytes. 254 244 * Sets @insn->opcode.value = opcode1. No effect if @insn->opcode.got 255 245 * is already 1. 246 + * 247 + * Returns: 248 + * 0: on success 249 + * < 0: on error 256 250 */ 257 - void insn_get_opcode(struct insn *insn) 251 + int insn_get_opcode(struct insn *insn) 258 252 { 259 253 struct insn_field *opcode = &insn->opcode; 254 + int pfx_id, ret; 260 255 insn_byte_t op; 261 - int pfx_id; 256 + 262 257 if (opcode->got) 263 - return; 264 - if (!insn->prefixes.got) 265 - insn_get_prefixes(insn); 258 + return 0; 259 + 260 + if (!insn->prefixes.got) { 261 + ret = insn_get_prefixes(insn); 262 + if (ret) 263 + return ret; 264 + } 266 265 267 266 /* Get first opcode */ 268 267 op = get_next(insn_byte_t, insn); ··· 286 267 insn->attr = inat_get_avx_attribute(op, m, p); 287 268 if ((inat_must_evex(insn->attr) && !insn_is_evex(insn)) || 288 269 (!inat_accept_vex(insn->attr) && 289 - !inat_is_group(insn->attr))) 290 - insn->attr = 0; /* This instruction is bad */ 291 - goto end; /* VEX has only 1 byte for opcode */ 270 + !inat_is_group(insn->attr))) { 271 + /* This instruction is bad */ 272 + insn->attr = 0; 273 + return -EINVAL; 274 + } 275 + /* VEX has only 1 byte for opcode */ 276 + goto end; 292 277 } 293 278 294 279 insn->attr = inat_get_opcode_attribute(op); ··· 303 280 pfx_id = insn_last_prefix_id(insn); 304 281 insn->attr = inat_get_escape_attribute(op, pfx_id, insn->attr); 305 282 } 306 - if (inat_must_vex(insn->attr)) 307 - insn->attr = 0; /* This instruction is bad */ 283 + 284 + if (inat_must_vex(insn->attr)) { 285 + /* This instruction is bad */ 286 + insn->attr = 0; 287 + return -EINVAL; 288 + } 308 289 end: 309 290 opcode->got = 1; 291 + return 0; 310 292 311 293 err_out: 312 - return; 294 + return -ENODATA; 313 295 } 314 296 315 297 /** ··· 324 296 * Populates @insn->modrm and updates @insn->next_byte to point past the 325 297 * ModRM byte, if any. If necessary, first collects the preceding bytes 326 298 * (prefixes and opcode(s)). No effect if @insn->modrm.got is already 1. 299 + * 300 + * Returns: 301 + * 0: on success 302 + * < 0: on error 327 303 */ 328 - void insn_get_modrm(struct insn *insn) 304 + int insn_get_modrm(struct insn *insn) 329 305 { 330 306 struct insn_field *modrm = &insn->modrm; 331 307 insn_byte_t pfx_id, mod; 308 + int ret; 309 + 332 310 if (modrm->got) 333 - return; 334 - if (!insn->opcode.got) 335 - insn_get_opcode(insn); 311 + return 0; 312 + 313 + if (!insn->opcode.got) { 314 + ret = insn_get_opcode(insn); 315 + if (ret) 316 + return ret; 317 + } 336 318 337 319 if (inat_has_modrm(insn->attr)) { 338 320 mod = get_next(insn_byte_t, insn); ··· 351 313 pfx_id = insn_last_prefix_id(insn); 352 314 insn->attr = inat_get_group_attribute(mod, pfx_id, 353 315 insn->attr); 354 - if (insn_is_avx(insn) && !inat_accept_vex(insn->attr)) 355 - insn->attr = 0; /* This is bad */ 316 + if (insn_is_avx(insn) && !inat_accept_vex(insn->attr)) { 317 + /* Bad insn */ 318 + insn->attr = 0; 319 + return -EINVAL; 320 + } 356 321 } 357 322 } 358 323 359 324 if (insn->x86_64 && inat_is_force64(insn->attr)) 360 325 insn->opnd_bytes = 8; 326 + 361 327 modrm->got = 1; 328 + return 0; 362 329 363 330 err_out: 364 - return; 331 + return -ENODATA; 365 332 } 366 333 367 334 ··· 380 337 int insn_rip_relative(struct insn *insn) 381 338 { 382 339 struct insn_field *modrm = &insn->modrm; 340 + int ret; 383 341 384 342 if (!insn->x86_64) 385 343 return 0; 386 - if (!modrm->got) 387 - insn_get_modrm(insn); 344 + 345 + if (!modrm->got) { 346 + ret = insn_get_modrm(insn); 347 + if (ret) 348 + return 0; 349 + } 388 350 /* 389 351 * For rip-relative instructions, the mod field (top 2 bits) 390 352 * is zero and the r/m field (bottom 3 bits) is 0x5. ··· 403 355 * 404 356 * If necessary, first collects the instruction up to and including the 405 357 * ModRM byte. 358 + * 359 + * Returns: 360 + * 0: if decoding succeeded 361 + * < 0: otherwise. 406 362 */ 407 - void insn_get_sib(struct insn *insn) 363 + int insn_get_sib(struct insn *insn) 408 364 { 409 365 insn_byte_t modrm; 366 + int ret; 410 367 411 368 if (insn->sib.got) 412 - return; 413 - if (!insn->modrm.got) 414 - insn_get_modrm(insn); 369 + return 0; 370 + 371 + if (!insn->modrm.got) { 372 + ret = insn_get_modrm(insn); 373 + if (ret) 374 + return ret; 375 + } 376 + 415 377 if (insn->modrm.nbytes) { 416 378 modrm = insn->modrm.bytes[0]; 417 379 if (insn->addr_bytes != 2 && ··· 432 374 } 433 375 insn->sib.got = 1; 434 376 377 + return 0; 378 + 435 379 err_out: 436 - return; 380 + return -ENODATA; 437 381 } 438 382 439 383 ··· 446 386 * If necessary, first collects the instruction up to and including the 447 387 * SIB byte. 448 388 * Displacement value is sign-expanded. 389 + * 390 + * * Returns: 391 + * 0: if decoding succeeded 392 + * < 0: otherwise. 449 393 */ 450 - void insn_get_displacement(struct insn *insn) 394 + int insn_get_displacement(struct insn *insn) 451 395 { 452 396 insn_byte_t mod, rm, base; 397 + int ret; 453 398 454 399 if (insn->displacement.got) 455 - return; 456 - if (!insn->sib.got) 457 - insn_get_sib(insn); 400 + return 0; 401 + 402 + if (!insn->sib.got) { 403 + ret = insn_get_sib(insn); 404 + if (ret) 405 + return ret; 406 + } 407 + 458 408 if (insn->modrm.nbytes) { 459 409 /* 460 410 * Interpreting the modrm byte: ··· 506 436 } 507 437 out: 508 438 insn->displacement.got = 1; 439 + return 0; 509 440 510 441 err_out: 511 - return; 442 + return -ENODATA; 512 443 } 513 444 514 445 /* Decode moffset16/32/64. Return 0 if failed */ ··· 608 537 } 609 538 610 539 /** 611 - * insn_get_immediate() - Get the immediates of instruction 540 + * insn_get_immediate() - Get the immediate in an instruction 612 541 * @insn: &struct insn containing instruction 613 542 * 614 543 * If necessary, first collects the instruction up to and including the 615 544 * displacement bytes. 616 545 * Basically, most of immediates are sign-expanded. Unsigned-value can be 617 - * get by bit masking with ((1 << (nbytes * 8)) - 1) 546 + * computed by bit masking with ((1 << (nbytes * 8)) - 1) 547 + * 548 + * Returns: 549 + * 0: on success 550 + * < 0: on error 618 551 */ 619 - void insn_get_immediate(struct insn *insn) 552 + int insn_get_immediate(struct insn *insn) 620 553 { 554 + int ret; 555 + 621 556 if (insn->immediate.got) 622 - return; 623 - if (!insn->displacement.got) 624 - insn_get_displacement(insn); 557 + return 0; 558 + 559 + if (!insn->displacement.got) { 560 + ret = insn_get_displacement(insn); 561 + if (ret) 562 + return ret; 563 + } 625 564 626 565 if (inat_has_moffset(insn->attr)) { 627 566 if (!__get_moffset(insn)) ··· 678 597 } 679 598 done: 680 599 insn->immediate.got = 1; 600 + return 0; 681 601 682 602 err_out: 683 - return; 603 + return -ENODATA; 684 604 } 685 605 686 606 /** ··· 690 608 * 691 609 * If necessary, first collects the instruction up to and including the 692 610 * immediates bytes. 693 - */ 694 - void insn_get_length(struct insn *insn) 611 + * 612 + * Returns: 613 + * - 0 on success 614 + * - < 0 on error 615 + */ 616 + int insn_get_length(struct insn *insn) 695 617 { 618 + int ret; 619 + 696 620 if (insn->length) 697 - return; 698 - if (!insn->immediate.got) 699 - insn_get_immediate(insn); 621 + return 0; 622 + 623 + if (!insn->immediate.got) { 624 + ret = insn_get_immediate(insn); 625 + if (ret) 626 + return ret; 627 + } 628 + 700 629 insn->length = (unsigned char)((unsigned long)insn->next_byte 701 630 - (unsigned long)insn->kaddr); 631 + 632 + return 0; 633 + } 634 + 635 + /* Ensure this instruction is decoded completely */ 636 + static inline int insn_complete(struct insn *insn) 637 + { 638 + return insn->opcode.got && insn->modrm.got && insn->sib.got && 639 + insn->displacement.got && insn->immediate.got; 640 + } 641 + 642 + /** 643 + * insn_decode() - Decode an x86 instruction 644 + * @insn: &struct insn to be initialized 645 + * @kaddr: address (in kernel memory) of instruction (or copy thereof) 646 + * @buf_len: length of the insn buffer at @kaddr 647 + * @m: insn mode, see enum insn_mode 648 + * 649 + * Returns: 650 + * 0: if decoding succeeded 651 + * < 0: otherwise. 652 + */ 653 + int insn_decode(struct insn *insn, const void *kaddr, int buf_len, enum insn_mode m) 654 + { 655 + int ret; 656 + 657 + #define INSN_MODE_KERN (enum insn_mode)-1 /* __ignore_sync_check__ mode is only valid in the kernel */ 658 + 659 + if (m == INSN_MODE_KERN) 660 + insn_init(insn, kaddr, buf_len, IS_ENABLED(CONFIG_X86_64)); 661 + else 662 + insn_init(insn, kaddr, buf_len, m == INSN_MODE_64); 663 + 664 + ret = insn_get_length(insn); 665 + if (ret) 666 + return ret; 667 + 668 + if (insn_complete(insn)) 669 + return 0; 670 + 671 + return -EINVAL; 702 672 }
+73
tools/include/linux/kconfig.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef _TOOLS_LINUX_KCONFIG_H 3 + #define _TOOLS_LINUX_KCONFIG_H 4 + 5 + /* CONFIG_CC_VERSION_TEXT (Do not delete this comment. See help in Kconfig) */ 6 + 7 + #ifdef CONFIG_CPU_BIG_ENDIAN 8 + #define __BIG_ENDIAN 4321 9 + #else 10 + #define __LITTLE_ENDIAN 1234 11 + #endif 12 + 13 + #define __ARG_PLACEHOLDER_1 0, 14 + #define __take_second_arg(__ignored, val, ...) val 15 + 16 + /* 17 + * The use of "&&" / "||" is limited in certain expressions. 18 + * The following enable to calculate "and" / "or" with macro expansion only. 19 + */ 20 + #define __and(x, y) ___and(x, y) 21 + #define ___and(x, y) ____and(__ARG_PLACEHOLDER_##x, y) 22 + #define ____and(arg1_or_junk, y) __take_second_arg(arg1_or_junk y, 0) 23 + 24 + #define __or(x, y) ___or(x, y) 25 + #define ___or(x, y) ____or(__ARG_PLACEHOLDER_##x, y) 26 + #define ____or(arg1_or_junk, y) __take_second_arg(arg1_or_junk 1, y) 27 + 28 + /* 29 + * Helper macros to use CONFIG_ options in C/CPP expressions. Note that 30 + * these only work with boolean and tristate options. 31 + */ 32 + 33 + /* 34 + * Getting something that works in C and CPP for an arg that may or may 35 + * not be defined is tricky. Here, if we have "#define CONFIG_BOOGER 1" 36 + * we match on the placeholder define, insert the "0," for arg1 and generate 37 + * the triplet (0, 1, 0). Then the last step cherry picks the 2nd arg (a one). 38 + * When CONFIG_BOOGER is not defined, we generate a (... 1, 0) pair, and when 39 + * the last step cherry picks the 2nd arg, we get a zero. 40 + */ 41 + #define __is_defined(x) ___is_defined(x) 42 + #define ___is_defined(val) ____is_defined(__ARG_PLACEHOLDER_##val) 43 + #define ____is_defined(arg1_or_junk) __take_second_arg(arg1_or_junk 1, 0) 44 + 45 + /* 46 + * IS_BUILTIN(CONFIG_FOO) evaluates to 1 if CONFIG_FOO is set to 'y', 0 47 + * otherwise. For boolean options, this is equivalent to 48 + * IS_ENABLED(CONFIG_FOO). 49 + */ 50 + #define IS_BUILTIN(option) __is_defined(option) 51 + 52 + /* 53 + * IS_MODULE(CONFIG_FOO) evaluates to 1 if CONFIG_FOO is set to 'm', 0 54 + * otherwise. 55 + */ 56 + #define IS_MODULE(option) __is_defined(option##_MODULE) 57 + 58 + /* 59 + * IS_REACHABLE(CONFIG_FOO) evaluates to 1 if the currently compiled 60 + * code can call a function defined in code compiled based on CONFIG_FOO. 61 + * This is similar to IS_ENABLED(), but returns false when invoked from 62 + * built-in code when CONFIG_FOO is set to 'm'. 63 + */ 64 + #define IS_REACHABLE(option) __or(IS_BUILTIN(option), \ 65 + __and(IS_MODULE(option), __is_defined(MODULE))) 66 + 67 + /* 68 + * IS_ENABLED(CONFIG_FOO) evaluates to 1 if CONFIG_FOO is set to 'y' or 'm', 69 + * 0 otherwise. 70 + */ 71 + #define IS_ENABLED(option) __or(IS_BUILTIN(option), IS_MODULE(option)) 72 + 73 + #endif /* _TOOLS_LINUX_KCONFIG_H */
+134 -10
tools/objtool/arch/x86/decode.c
··· 11 11 #include "../../../arch/x86/lib/inat.c" 12 12 #include "../../../arch/x86/lib/insn.c" 13 13 14 + #define CONFIG_64BIT 1 15 + #include <asm/nops.h> 16 + 14 17 #include <asm/orc_types.h> 15 18 #include <objtool/check.h> 16 19 #include <objtool/elf.h> 17 20 #include <objtool/arch.h> 18 21 #include <objtool/warn.h> 22 + #include <arch/elf.h> 19 23 20 24 static unsigned char op_to_cfi_reg[][2] = { 21 25 {CFI_AX, CFI_R8}, ··· 94 90 struct list_head *ops_list) 95 91 { 96 92 struct insn insn; 97 - int x86_64, sign; 93 + int x86_64, sign, ret; 98 94 unsigned char op1, op2, rex = 0, rex_b = 0, rex_r = 0, rex_w = 0, 99 95 rex_x = 0, modrm = 0, modrm_mod = 0, modrm_rm = 0, 100 96 modrm_reg = 0, sib = 0; ··· 105 101 if (x86_64 == -1) 106 102 return -1; 107 103 108 - insn_init(&insn, sec->data->d_buf + offset, maxlen, x86_64); 109 - insn_get_length(&insn); 110 - 111 - if (!insn_complete(&insn)) { 104 + ret = insn_decode(&insn, sec->data->d_buf + offset, maxlen, 105 + x86_64 ? INSN_MODE_64 : INSN_MODE_32); 106 + if (ret < 0) { 112 107 WARN("can't decode instruction at %s:0x%lx", sec->name, offset); 113 108 return -1; 114 109 } ··· 599 596 const char *arch_nop_insn(int len) 600 597 { 601 598 static const char nops[5][5] = { 602 - /* 1 */ { 0x90 }, 603 - /* 2 */ { 0x66, 0x90 }, 604 - /* 3 */ { 0x0f, 0x1f, 0x00 }, 605 - /* 4 */ { 0x0f, 0x1f, 0x40, 0x00 }, 606 - /* 5 */ { 0x0f, 0x1f, 0x44, 0x00, 0x00 }, 599 + { BYTES_NOP1 }, 600 + { BYTES_NOP2 }, 601 + { BYTES_NOP3 }, 602 + { BYTES_NOP4 }, 603 + { BYTES_NOP5 }, 607 604 }; 608 605 609 606 if (len < 1 || len > 5) { ··· 612 609 } 613 610 614 611 return nops[len-1]; 612 + } 613 + 614 + /* asm/alternative.h ? */ 615 + 616 + #define ALTINSTR_FLAG_INV (1 << 15) 617 + #define ALT_NOT(feat) ((feat) | ALTINSTR_FLAG_INV) 618 + 619 + struct alt_instr { 620 + s32 instr_offset; /* original instruction */ 621 + s32 repl_offset; /* offset to replacement instruction */ 622 + u16 cpuid; /* cpuid bit set for replacement */ 623 + u8 instrlen; /* length of original instruction */ 624 + u8 replacementlen; /* length of new instruction */ 625 + } __packed; 626 + 627 + static int elf_add_alternative(struct elf *elf, 628 + struct instruction *orig, struct symbol *sym, 629 + int cpuid, u8 orig_len, u8 repl_len) 630 + { 631 + const int size = sizeof(struct alt_instr); 632 + struct alt_instr *alt; 633 + struct section *sec; 634 + Elf_Scn *s; 635 + 636 + sec = find_section_by_name(elf, ".altinstructions"); 637 + if (!sec) { 638 + sec = elf_create_section(elf, ".altinstructions", 639 + SHF_WRITE, size, 0); 640 + 641 + if (!sec) { 642 + WARN_ELF("elf_create_section"); 643 + return -1; 644 + } 645 + } 646 + 647 + s = elf_getscn(elf->elf, sec->idx); 648 + if (!s) { 649 + WARN_ELF("elf_getscn"); 650 + return -1; 651 + } 652 + 653 + sec->data = elf_newdata(s); 654 + if (!sec->data) { 655 + WARN_ELF("elf_newdata"); 656 + return -1; 657 + } 658 + 659 + sec->data->d_size = size; 660 + sec->data->d_align = 1; 661 + 662 + alt = sec->data->d_buf = malloc(size); 663 + if (!sec->data->d_buf) { 664 + perror("malloc"); 665 + return -1; 666 + } 667 + memset(sec->data->d_buf, 0, size); 668 + 669 + if (elf_add_reloc_to_insn(elf, sec, sec->sh.sh_size, 670 + R_X86_64_PC32, orig->sec, orig->offset)) { 671 + WARN("elf_create_reloc: alt_instr::instr_offset"); 672 + return -1; 673 + } 674 + 675 + if (elf_add_reloc(elf, sec, sec->sh.sh_size + 4, 676 + R_X86_64_PC32, sym, 0)) { 677 + WARN("elf_create_reloc: alt_instr::repl_offset"); 678 + return -1; 679 + } 680 + 681 + alt->cpuid = cpuid; 682 + alt->instrlen = orig_len; 683 + alt->replacementlen = repl_len; 684 + 685 + sec->sh.sh_size += size; 686 + sec->changed = true; 687 + 688 + return 0; 689 + } 690 + 691 + #define X86_FEATURE_RETPOLINE ( 7*32+12) 692 + 693 + int arch_rewrite_retpolines(struct objtool_file *file) 694 + { 695 + struct instruction *insn; 696 + struct reloc *reloc; 697 + struct symbol *sym; 698 + char name[32] = ""; 699 + 700 + list_for_each_entry(insn, &file->retpoline_call_list, call_node) { 701 + 702 + if (!strcmp(insn->sec->name, ".text.__x86.indirect_thunk")) 703 + continue; 704 + 705 + reloc = insn->reloc; 706 + 707 + sprintf(name, "__x86_indirect_alt_%s_%s", 708 + insn->type == INSN_JUMP_DYNAMIC ? "jmp" : "call", 709 + reloc->sym->name + 21); 710 + 711 + sym = find_symbol_by_name(file->elf, name); 712 + if (!sym) { 713 + sym = elf_create_undef_symbol(file->elf, name); 714 + if (!sym) { 715 + WARN("elf_create_undef_symbol"); 716 + return -1; 717 + } 718 + } 719 + 720 + if (elf_add_alternative(file->elf, insn, sym, 721 + ALT_NOT(X86_FEATURE_RETPOLINE), 5, 5)) { 722 + WARN("elf_add_alternative"); 723 + return -1; 724 + } 725 + } 726 + 727 + return 0; 615 728 } 616 729 617 730 int arch_decode_hint_reg(struct instruction *insn, u8 sp_reg) ··· 764 645 } 765 646 766 647 return 0; 648 + } 649 + 650 + bool arch_is_retpoline(struct symbol *sym) 651 + { 652 + return !strncmp(sym->name, "__x86_indirect_", 15); 767 653 }
+1 -1
tools/objtool/arch/x86/include/arch/special.h
··· 10 10 #define JUMP_ORIG_OFFSET 0 11 11 #define JUMP_NEW_OFFSET 4 12 12 13 - #define ALT_ENTRY_SIZE 13 13 + #define ALT_ENTRY_SIZE 12 14 14 #define ALT_ORIG_OFFSET 0 15 15 #define ALT_NEW_OFFSET 4 16 16 #define ALT_FEATURE_OFFSET 8
+94 -89
tools/objtool/check.c
··· 433 433 434 434 static int create_static_call_sections(struct objtool_file *file) 435 435 { 436 - struct section *sec, *reloc_sec; 437 - struct reloc *reloc; 436 + struct section *sec; 438 437 struct static_call_site *site; 439 438 struct instruction *insn; 440 439 struct symbol *key_sym; ··· 451 452 return 0; 452 453 453 454 idx = 0; 454 - list_for_each_entry(insn, &file->static_call_list, static_call_node) 455 + list_for_each_entry(insn, &file->static_call_list, call_node) 455 456 idx++; 456 457 457 458 sec = elf_create_section(file->elf, ".static_call_sites", SHF_WRITE, ··· 459 460 if (!sec) 460 461 return -1; 461 462 462 - reloc_sec = elf_create_reloc_section(file->elf, sec, SHT_RELA); 463 - if (!reloc_sec) 464 - return -1; 465 - 466 463 idx = 0; 467 - list_for_each_entry(insn, &file->static_call_list, static_call_node) { 464 + list_for_each_entry(insn, &file->static_call_list, call_node) { 468 465 469 466 site = (struct static_call_site *)sec->data->d_buf + idx; 470 467 memset(site, 0, sizeof(struct static_call_site)); 471 468 472 469 /* populate reloc for 'addr' */ 473 - reloc = malloc(sizeof(*reloc)); 474 - 475 - if (!reloc) { 476 - perror("malloc"); 470 + if (elf_add_reloc_to_insn(file->elf, sec, 471 + idx * sizeof(struct static_call_site), 472 + R_X86_64_PC32, 473 + insn->sec, insn->offset)) 477 474 return -1; 478 - } 479 - memset(reloc, 0, sizeof(*reloc)); 480 - 481 - insn_to_reloc_sym_addend(insn->sec, insn->offset, reloc); 482 - if (!reloc->sym) { 483 - WARN_FUNC("static call tramp: missing containing symbol", 484 - insn->sec, insn->offset); 485 - return -1; 486 - } 487 - 488 - reloc->type = R_X86_64_PC32; 489 - reloc->offset = idx * sizeof(struct static_call_site); 490 - reloc->sec = reloc_sec; 491 - elf_add_reloc(file->elf, reloc); 492 475 493 476 /* find key symbol */ 494 477 key_name = strdup(insn->call_dest->name); ··· 507 526 free(key_name); 508 527 509 528 /* populate reloc for 'key' */ 510 - reloc = malloc(sizeof(*reloc)); 511 - if (!reloc) { 512 - perror("malloc"); 529 + if (elf_add_reloc(file->elf, sec, 530 + idx * sizeof(struct static_call_site) + 4, 531 + R_X86_64_PC32, key_sym, 532 + is_sibling_call(insn) * STATIC_CALL_SITE_TAIL)) 513 533 return -1; 514 - } 515 - memset(reloc, 0, sizeof(*reloc)); 516 - reloc->sym = key_sym; 517 - reloc->addend = is_sibling_call(insn) ? STATIC_CALL_SITE_TAIL : 0; 518 - reloc->type = R_X86_64_PC32; 519 - reloc->offset = idx * sizeof(struct static_call_site) + 4; 520 - reloc->sec = reloc_sec; 521 - elf_add_reloc(file->elf, reloc); 522 534 523 535 idx++; 524 536 } 525 - 526 - if (elf_rebuild_reloc_section(file->elf, reloc_sec)) 527 - return -1; 528 537 529 538 return 0; 530 539 } 531 540 532 541 static int create_mcount_loc_sections(struct objtool_file *file) 533 542 { 534 - struct section *sec, *reloc_sec; 535 - struct reloc *reloc; 543 + struct section *sec; 536 544 unsigned long *loc; 537 545 struct instruction *insn; 538 546 int idx; ··· 544 574 if (!sec) 545 575 return -1; 546 576 547 - reloc_sec = elf_create_reloc_section(file->elf, sec, SHT_RELA); 548 - if (!reloc_sec) 549 - return -1; 550 - 551 577 idx = 0; 552 578 list_for_each_entry(insn, &file->mcount_loc_list, mcount_loc_node) { 553 579 554 580 loc = (unsigned long *)sec->data->d_buf + idx; 555 581 memset(loc, 0, sizeof(unsigned long)); 556 582 557 - reloc = malloc(sizeof(*reloc)); 558 - if (!reloc) { 559 - perror("malloc"); 583 + if (elf_add_reloc_to_insn(file->elf, sec, 584 + idx * sizeof(unsigned long), 585 + R_X86_64_64, 586 + insn->sec, insn->offset)) 560 587 return -1; 561 - } 562 - memset(reloc, 0, sizeof(*reloc)); 563 - 564 - if (insn->sec->sym) { 565 - reloc->sym = insn->sec->sym; 566 - reloc->addend = insn->offset; 567 - } else { 568 - reloc->sym = find_symbol_containing(insn->sec, insn->offset); 569 - 570 - if (!reloc->sym) { 571 - WARN("missing symbol for insn at offset 0x%lx\n", 572 - insn->offset); 573 - return -1; 574 - } 575 - 576 - reloc->addend = insn->offset - reloc->sym->offset; 577 - } 578 - 579 - reloc->type = R_X86_64_64; 580 - reloc->offset = idx * sizeof(unsigned long); 581 - reloc->sec = reloc_sec; 582 - elf_add_reloc(file->elf, reloc); 583 588 584 589 idx++; 585 590 } 586 - 587 - if (elf_rebuild_reloc_section(file->elf, reloc_sec)) 588 - return -1; 589 591 590 592 return 0; 591 593 } ··· 792 850 return 0; 793 851 } 794 852 853 + __weak bool arch_is_retpoline(struct symbol *sym) 854 + { 855 + return false; 856 + } 857 + 858 + #define NEGATIVE_RELOC ((void *)-1L) 859 + 860 + static struct reloc *insn_reloc(struct objtool_file *file, struct instruction *insn) 861 + { 862 + if (insn->reloc == NEGATIVE_RELOC) 863 + return NULL; 864 + 865 + if (!insn->reloc) { 866 + insn->reloc = find_reloc_by_dest_range(file->elf, insn->sec, 867 + insn->offset, insn->len); 868 + if (!insn->reloc) { 869 + insn->reloc = NEGATIVE_RELOC; 870 + return NULL; 871 + } 872 + } 873 + 874 + return insn->reloc; 875 + } 876 + 795 877 /* 796 878 * Find the destination instructions for all jumps. 797 879 */ ··· 830 864 if (!is_static_jump(insn)) 831 865 continue; 832 866 833 - reloc = find_reloc_by_dest_range(file->elf, insn->sec, 834 - insn->offset, insn->len); 867 + reloc = insn_reloc(file, insn); 835 868 if (!reloc) { 836 869 dest_sec = insn->sec; 837 870 dest_off = arch_jump_destination(insn); 838 871 } else if (reloc->sym->type == STT_SECTION) { 839 872 dest_sec = reloc->sym->sec; 840 873 dest_off = arch_dest_reloc_offset(reloc->addend); 841 - } else if (!strncmp(reloc->sym->name, "__x86_indirect_thunk_", 21) || 842 - !strncmp(reloc->sym->name, "__x86_retpoline_", 16)) { 874 + } else if (arch_is_retpoline(reloc->sym)) { 843 875 /* 844 876 * Retpoline jumps are really dynamic jumps in 845 877 * disguise, so convert them accordingly. ··· 847 883 else 848 884 insn->type = INSN_JUMP_DYNAMIC_CONDITIONAL; 849 885 886 + list_add_tail(&insn->call_node, 887 + &file->retpoline_call_list); 888 + 850 889 insn->retpoline_safe = true; 851 890 continue; 852 891 } else if (insn->func) { 853 892 /* internal or external sibling call (with reloc) */ 854 893 insn->call_dest = reloc->sym; 855 894 if (insn->call_dest->static_call_tramp) { 856 - list_add_tail(&insn->static_call_node, 895 + list_add_tail(&insn->call_node, 857 896 &file->static_call_list); 858 897 } 859 898 continue; ··· 918 951 /* internal sibling call (without reloc) */ 919 952 insn->call_dest = insn->jump_dest->func; 920 953 if (insn->call_dest->static_call_tramp) { 921 - list_add_tail(&insn->static_call_node, 954 + list_add_tail(&insn->call_node, 922 955 &file->static_call_list); 923 956 } 924 957 } ··· 962 995 if (insn->type != INSN_CALL) 963 996 continue; 964 997 965 - reloc = find_reloc_by_dest_range(file->elf, insn->sec, 966 - insn->offset, insn->len); 998 + reloc = insn_reloc(file, insn); 967 999 if (!reloc) { 968 1000 dest_off = arch_jump_destination(insn); 969 1001 insn->call_dest = find_call_destination(insn->sec, dest_off); ··· 992 1026 dest_off); 993 1027 return -1; 994 1028 } 1029 + 1030 + } else if (arch_is_retpoline(reloc->sym)) { 1031 + /* 1032 + * Retpoline calls are really dynamic calls in 1033 + * disguise, so convert them accordingly. 1034 + */ 1035 + insn->type = INSN_CALL_DYNAMIC; 1036 + insn->retpoline_safe = true; 1037 + 1038 + list_add_tail(&insn->call_node, 1039 + &file->retpoline_call_list); 1040 + 1041 + remove_insn_ops(insn); 1042 + continue; 1043 + 995 1044 } else 996 1045 insn->call_dest = reloc->sym; 1046 + 1047 + if (insn->call_dest && insn->call_dest->static_call_tramp) { 1048 + list_add_tail(&insn->call_node, 1049 + &file->static_call_list); 1050 + } 997 1051 998 1052 /* 999 1053 * Many compilers cannot disable KCOV with a function attribute ··· 1161 1175 * alternatives code can adjust the relative offsets 1162 1176 * accordingly. 1163 1177 */ 1164 - alt_reloc = find_reloc_by_dest_range(file->elf, insn->sec, 1165 - insn->offset, insn->len); 1178 + alt_reloc = insn_reloc(file, insn); 1166 1179 if (alt_reloc && 1167 1180 !arch_support_alt_relocation(special_alt, insn, alt_reloc)) { 1168 1181 ··· 1736 1751 file->rodata = found; 1737 1752 } 1738 1753 1754 + __weak int arch_rewrite_retpolines(struct objtool_file *file) 1755 + { 1756 + return 0; 1757 + } 1758 + 1739 1759 static int decode_sections(struct objtool_file *file) 1740 1760 { 1741 1761 int ret; ··· 1762 1772 if (ret) 1763 1773 return ret; 1764 1774 1775 + /* 1776 + * Must be before add_{jump_call}_destination. 1777 + */ 1765 1778 ret = read_static_call_tramps(file); 1766 1779 if (ret) 1767 1780 return ret; 1768 1781 1782 + /* 1783 + * Must be before add_special_section_alts() as that depends on 1784 + * jump_dest being set. 1785 + */ 1769 1786 ret = add_jump_destinations(file); 1770 1787 if (ret) 1771 1788 return ret; ··· 1781 1784 if (ret) 1782 1785 return ret; 1783 1786 1787 + /* 1788 + * Must be before add_call_destination(); it changes INSN_CALL to 1789 + * INSN_JUMP. 1790 + */ 1784 1791 ret = read_intra_function_calls(file); 1785 1792 if (ret) 1786 1793 return ret; ··· 1806 1805 return ret; 1807 1806 1808 1807 ret = read_instr_hints(file); 1808 + if (ret) 1809 + return ret; 1810 + 1811 + /* 1812 + * Must be after add_special_section_alts(), since this will emit 1813 + * alternatives. Must be after add_{jump,call}_destination(), since 1814 + * those create the call insn lists. 1815 + */ 1816 + ret = arch_rewrite_retpolines(file); 1809 1817 if (ret) 1810 1818 return ret; 1811 1819 ··· 2755 2745 2756 2746 if (dead_end_function(file, insn->call_dest)) 2757 2747 return 0; 2758 - 2759 - if (insn->type == INSN_CALL && insn->call_dest->static_call_tramp) { 2760 - list_add_tail(&insn->static_call_node, 2761 - &file->static_call_list); 2762 - } 2763 2748 2764 2749 break; 2765 2750
+207 -84
tools/objtool/elf.c
··· 211 211 return find_reloc_by_dest_range(elf, sec, offset, 1); 212 212 } 213 213 214 - void insn_to_reloc_sym_addend(struct section *sec, unsigned long offset, 215 - struct reloc *reloc) 216 - { 217 - if (sec->sym) { 218 - reloc->sym = sec->sym; 219 - reloc->addend = offset; 220 - return; 221 - } 222 - 223 - /* 224 - * The Clang assembler strips section symbols, so we have to reference 225 - * the function symbol instead: 226 - */ 227 - reloc->sym = find_symbol_containing(sec, offset); 228 - if (!reloc->sym) { 229 - /* 230 - * Hack alert. This happens when we need to reference the NOP 231 - * pad insn immediately after the function. 232 - */ 233 - reloc->sym = find_symbol_containing(sec, offset - 1); 234 - } 235 - 236 - if (reloc->sym) 237 - reloc->addend = offset - reloc->sym->offset; 238 - } 239 - 240 214 static int read_sections(struct elf *elf) 241 215 { 242 216 Elf_Scn *s = NULL; ··· 290 316 return 0; 291 317 } 292 318 319 + static void elf_add_symbol(struct elf *elf, struct symbol *sym) 320 + { 321 + struct list_head *entry; 322 + struct rb_node *pnode; 323 + 324 + sym->type = GELF_ST_TYPE(sym->sym.st_info); 325 + sym->bind = GELF_ST_BIND(sym->sym.st_info); 326 + 327 + sym->offset = sym->sym.st_value; 328 + sym->len = sym->sym.st_size; 329 + 330 + rb_add(&sym->node, &sym->sec->symbol_tree, symbol_to_offset); 331 + pnode = rb_prev(&sym->node); 332 + if (pnode) 333 + entry = &rb_entry(pnode, struct symbol, node)->list; 334 + else 335 + entry = &sym->sec->symbol_list; 336 + list_add(&sym->list, entry); 337 + elf_hash_add(elf->symbol_hash, &sym->hash, sym->idx); 338 + elf_hash_add(elf->symbol_name_hash, &sym->name_hash, str_hash(sym->name)); 339 + 340 + /* 341 + * Don't store empty STT_NOTYPE symbols in the rbtree. They 342 + * can exist within a function, confusing the sorting. 343 + */ 344 + if (!sym->len) 345 + rb_erase(&sym->node, &sym->sec->symbol_tree); 346 + } 347 + 293 348 static int read_symbols(struct elf *elf) 294 349 { 295 350 struct section *symtab, *symtab_shndx, *sec; 296 351 struct symbol *sym, *pfunc; 297 - struct list_head *entry; 298 - struct rb_node *pnode; 299 352 int symbols_nr, i; 300 353 char *coldstr; 301 354 Elf_Data *shndx_data = NULL; ··· 367 366 goto err; 368 367 } 369 368 370 - sym->type = GELF_ST_TYPE(sym->sym.st_info); 371 - sym->bind = GELF_ST_BIND(sym->sym.st_info); 372 - 373 369 if ((sym->sym.st_shndx > SHN_UNDEF && 374 370 sym->sym.st_shndx < SHN_LORESERVE) || 375 371 (shndx_data && sym->sym.st_shndx == SHN_XINDEX)) { ··· 379 381 sym->name); 380 382 goto err; 381 383 } 382 - if (sym->type == STT_SECTION) { 384 + if (GELF_ST_TYPE(sym->sym.st_info) == STT_SECTION) { 383 385 sym->name = sym->sec->name; 384 386 sym->sec->sym = sym; 385 387 } 386 388 } else 387 389 sym->sec = find_section_by_index(elf, 0); 388 390 389 - sym->offset = sym->sym.st_value; 390 - sym->len = sym->sym.st_size; 391 - 392 - rb_add(&sym->node, &sym->sec->symbol_tree, symbol_to_offset); 393 - pnode = rb_prev(&sym->node); 394 - if (pnode) 395 - entry = &rb_entry(pnode, struct symbol, node)->list; 396 - else 397 - entry = &sym->sec->symbol_list; 398 - list_add(&sym->list, entry); 399 - elf_hash_add(elf->symbol_hash, &sym->hash, sym->idx); 400 - elf_hash_add(elf->symbol_name_hash, &sym->name_hash, str_hash(sym->name)); 401 - 402 - /* 403 - * Don't store empty STT_NOTYPE symbols in the rbtree. They 404 - * can exist within a function, confusing the sorting. 405 - */ 406 - if (!sym->len) 407 - rb_erase(&sym->node, &sym->sec->symbol_tree); 391 + elf_add_symbol(elf, sym); 408 392 } 409 393 410 394 if (stats) ··· 453 473 return -1; 454 474 } 455 475 456 - void elf_add_reloc(struct elf *elf, struct reloc *reloc) 457 - { 458 - struct section *sec = reloc->sec; 476 + static struct section *elf_create_reloc_section(struct elf *elf, 477 + struct section *base, 478 + int reltype); 459 479 460 - list_add_tail(&reloc->list, &sec->reloc_list); 480 + int elf_add_reloc(struct elf *elf, struct section *sec, unsigned long offset, 481 + unsigned int type, struct symbol *sym, int addend) 482 + { 483 + struct reloc *reloc; 484 + 485 + if (!sec->reloc && !elf_create_reloc_section(elf, sec, SHT_RELA)) 486 + return -1; 487 + 488 + reloc = malloc(sizeof(*reloc)); 489 + if (!reloc) { 490 + perror("malloc"); 491 + return -1; 492 + } 493 + memset(reloc, 0, sizeof(*reloc)); 494 + 495 + reloc->sec = sec->reloc; 496 + reloc->offset = offset; 497 + reloc->type = type; 498 + reloc->sym = sym; 499 + reloc->addend = addend; 500 + 501 + list_add_tail(&reloc->list, &sec->reloc->reloc_list); 461 502 elf_hash_add(elf->reloc_hash, &reloc->hash, reloc_hash(reloc)); 503 + 504 + sec->reloc->changed = true; 505 + 506 + return 0; 507 + } 508 + 509 + int elf_add_reloc_to_insn(struct elf *elf, struct section *sec, 510 + unsigned long offset, unsigned int type, 511 + struct section *insn_sec, unsigned long insn_off) 512 + { 513 + struct symbol *sym; 514 + int addend; 515 + 516 + if (insn_sec->sym) { 517 + sym = insn_sec->sym; 518 + addend = insn_off; 519 + 520 + } else { 521 + /* 522 + * The Clang assembler strips section symbols, so we have to 523 + * reference the function symbol instead: 524 + */ 525 + sym = find_symbol_containing(insn_sec, insn_off); 526 + if (!sym) { 527 + /* 528 + * Hack alert. This happens when we need to reference 529 + * the NOP pad insn immediately after the function. 530 + */ 531 + sym = find_symbol_containing(insn_sec, insn_off - 1); 532 + } 533 + 534 + if (!sym) { 535 + WARN("can't find symbol containing %s+0x%lx", insn_sec->name, insn_off); 536 + return -1; 537 + } 538 + 539 + addend = insn_off - sym->offset; 540 + } 541 + 542 + return elf_add_reloc(elf, sec, offset, type, sym, addend); 462 543 } 463 544 464 545 static int read_rel_reloc(struct section *sec, int i, struct reloc *reloc, unsigned int *symndx) ··· 599 558 return -1; 600 559 } 601 560 602 - elf_add_reloc(elf, reloc); 561 + list_add_tail(&reloc->list, &sec->reloc_list); 562 + elf_hash_add(elf->reloc_hash, &reloc->hash, reloc_hash(reloc)); 563 + 603 564 nr_reloc++; 604 565 } 605 566 max_reloc = max(max_reloc, nr_reloc); ··· 679 636 return NULL; 680 637 } 681 638 639 + static int elf_add_string(struct elf *elf, struct section *strtab, char *str) 640 + { 641 + Elf_Data *data; 642 + Elf_Scn *s; 643 + int len; 644 + 645 + if (!strtab) 646 + strtab = find_section_by_name(elf, ".strtab"); 647 + if (!strtab) { 648 + WARN("can't find .strtab section"); 649 + return -1; 650 + } 651 + 652 + s = elf_getscn(elf->elf, strtab->idx); 653 + if (!s) { 654 + WARN_ELF("elf_getscn"); 655 + return -1; 656 + } 657 + 658 + data = elf_newdata(s); 659 + if (!data) { 660 + WARN_ELF("elf_newdata"); 661 + return -1; 662 + } 663 + 664 + data->d_buf = str; 665 + data->d_size = strlen(str) + 1; 666 + data->d_align = 1; 667 + 668 + len = strtab->len; 669 + strtab->len += data->d_size; 670 + strtab->changed = true; 671 + 672 + return len; 673 + } 674 + 675 + struct symbol *elf_create_undef_symbol(struct elf *elf, const char *name) 676 + { 677 + struct section *symtab; 678 + struct symbol *sym; 679 + Elf_Data *data; 680 + Elf_Scn *s; 681 + 682 + sym = malloc(sizeof(*sym)); 683 + if (!sym) { 684 + perror("malloc"); 685 + return NULL; 686 + } 687 + memset(sym, 0, sizeof(*sym)); 688 + 689 + sym->name = strdup(name); 690 + 691 + sym->sym.st_name = elf_add_string(elf, NULL, sym->name); 692 + if (sym->sym.st_name == -1) 693 + return NULL; 694 + 695 + sym->sym.st_info = GELF_ST_INFO(STB_GLOBAL, STT_NOTYPE); 696 + // st_other 0 697 + // st_shndx 0 698 + // st_value 0 699 + // st_size 0 700 + 701 + symtab = find_section_by_name(elf, ".symtab"); 702 + if (!symtab) { 703 + WARN("can't find .symtab"); 704 + return NULL; 705 + } 706 + 707 + s = elf_getscn(elf->elf, symtab->idx); 708 + if (!s) { 709 + WARN_ELF("elf_getscn"); 710 + return NULL; 711 + } 712 + 713 + data = elf_newdata(s); 714 + if (!data) { 715 + WARN_ELF("elf_newdata"); 716 + return NULL; 717 + } 718 + 719 + data->d_buf = &sym->sym; 720 + data->d_size = sizeof(sym->sym); 721 + data->d_align = 1; 722 + 723 + sym->idx = symtab->len / sizeof(sym->sym); 724 + 725 + symtab->len += data->d_size; 726 + symtab->changed = true; 727 + 728 + sym->sec = find_section_by_index(elf, 0); 729 + 730 + elf_add_symbol(elf, sym); 731 + 732 + return sym; 733 + } 734 + 682 735 struct section *elf_create_section(struct elf *elf, const char *name, 683 736 unsigned int sh_flags, size_t entsize, int nr) 684 737 { 685 738 struct section *sec, *shstrtab; 686 739 size_t size = entsize * nr; 687 740 Elf_Scn *s; 688 - Elf_Data *data; 689 741 690 742 sec = malloc(sizeof(*sec)); 691 743 if (!sec) { ··· 837 699 sec->sh.sh_addralign = 1; 838 700 sec->sh.sh_flags = SHF_ALLOC | sh_flags; 839 701 840 - 841 702 /* Add section name to .shstrtab (or .strtab for Clang) */ 842 703 shstrtab = find_section_by_name(elf, ".shstrtab"); 843 704 if (!shstrtab) ··· 845 708 WARN("can't find .shstrtab or .strtab section"); 846 709 return NULL; 847 710 } 848 - 849 - s = elf_getscn(elf->elf, shstrtab->idx); 850 - if (!s) { 851 - WARN_ELF("elf_getscn"); 711 + sec->sh.sh_name = elf_add_string(elf, shstrtab, sec->name); 712 + if (sec->sh.sh_name == -1) 852 713 return NULL; 853 - } 854 - 855 - data = elf_newdata(s); 856 - if (!data) { 857 - WARN_ELF("elf_newdata"); 858 - return NULL; 859 - } 860 - 861 - data->d_buf = sec->name; 862 - data->d_size = strlen(name) + 1; 863 - data->d_align = 1; 864 - 865 - sec->sh.sh_name = shstrtab->len; 866 - 867 - shstrtab->len += strlen(name) + 1; 868 - shstrtab->changed = true; 869 714 870 715 list_add_tail(&sec->list, &elf->sections); 871 716 elf_hash_add(elf->section_hash, &sec->hash, sec->idx); ··· 918 799 return sec; 919 800 } 920 801 921 - struct section *elf_create_reloc_section(struct elf *elf, 802 + static struct section *elf_create_reloc_section(struct elf *elf, 922 803 struct section *base, 923 804 int reltype) 924 805 { ··· 992 873 return 0; 993 874 } 994 875 995 - int elf_rebuild_reloc_section(struct elf *elf, struct section *sec) 876 + static int elf_rebuild_reloc_section(struct elf *elf, struct section *sec) 996 877 { 997 878 struct reloc *reloc; 998 879 int nr; 999 - 1000 - sec->changed = true; 1001 - elf->changed = true; 1002 880 1003 881 nr = 0; 1004 882 list_for_each_entry(reloc, &sec->reloc_list, list) ··· 1060 944 struct section *sec; 1061 945 Elf_Scn *s; 1062 946 1063 - /* Update section headers for changed sections: */ 947 + /* Update changed relocation sections and section headers: */ 1064 948 list_for_each_entry(sec, &elf->sections, list) { 1065 949 if (sec->changed) { 950 + if (sec->base && 951 + elf_rebuild_reloc_section(elf, sec)) { 952 + WARN("elf_rebuild_reloc_section"); 953 + return -1; 954 + } 955 + 1066 956 s = elf_getscn(elf->elf, sec->idx); 1067 957 if (!s) { 1068 958 WARN_ELF("elf_getscn"); ··· 1080 958 } 1081 959 1082 960 sec->changed = false; 961 + elf->changed = true; 1083 962 } 1084 963 } 1085 964
+4
tools/objtool/include/objtool/arch.h
··· 86 86 87 87 int arch_decode_hint_reg(struct instruction *insn, u8 sp_reg); 88 88 89 + bool arch_is_retpoline(struct symbol *sym); 90 + 91 + int arch_rewrite_retpolines(struct objtool_file *file); 92 + 89 93 #endif /* _ARCH_H */
+2 -1
tools/objtool/include/objtool/check.h
··· 39 39 struct instruction { 40 40 struct list_head list; 41 41 struct hlist_node hash; 42 - struct list_head static_call_node; 42 + struct list_head call_node; 43 43 struct list_head mcount_loc_node; 44 44 struct section *sec; 45 45 unsigned long offset; ··· 56 56 struct instruction *jump_dest; 57 57 struct instruction *first_jump_src; 58 58 struct reloc *jump_table; 59 + struct reloc *reloc; 59 60 struct list_head alts; 60 61 struct symbol *func; 61 62 struct list_head stack_ops;
+8 -5
tools/objtool/include/objtool/elf.h
··· 122 122 123 123 struct elf *elf_open_read(const char *name, int flags); 124 124 struct section *elf_create_section(struct elf *elf, const char *name, unsigned int sh_flags, size_t entsize, int nr); 125 - struct section *elf_create_reloc_section(struct elf *elf, struct section *base, int reltype); 126 - void elf_add_reloc(struct elf *elf, struct reloc *reloc); 125 + 126 + int elf_add_reloc(struct elf *elf, struct section *sec, unsigned long offset, 127 + unsigned int type, struct symbol *sym, int addend); 128 + int elf_add_reloc_to_insn(struct elf *elf, struct section *sec, 129 + unsigned long offset, unsigned int type, 130 + struct section *insn_sec, unsigned long insn_off); 131 + 127 132 int elf_write_insn(struct elf *elf, struct section *sec, 128 133 unsigned long offset, unsigned int len, 129 134 const char *insn); 130 135 int elf_write_reloc(struct elf *elf, struct reloc *reloc); 136 + struct symbol *elf_create_undef_symbol(struct elf *elf, const char *name); 131 137 int elf_write(struct elf *elf); 132 138 void elf_close(struct elf *elf); 133 139 ··· 146 140 struct reloc *find_reloc_by_dest_range(const struct elf *elf, struct section *sec, 147 141 unsigned long offset, unsigned int len); 148 142 struct symbol *find_func_containing(struct section *sec, unsigned long offset); 149 - void insn_to_reloc_sym_addend(struct section *sec, unsigned long offset, 150 - struct reloc *reloc); 151 - int elf_rebuild_reloc_section(struct elf *elf, struct section *sec); 152 143 153 144 #define for_each_sec(file, sec) \ 154 145 list_for_each_entry(sec, &file->elf->sections, list)
+1
tools/objtool/include/objtool/objtool.h
··· 18 18 struct elf *elf; 19 19 struct list_head insn_list; 20 20 DECLARE_HASHTABLE(insn_hash, 20); 21 + struct list_head retpoline_call_list; 21 22 struct list_head static_call_list; 22 23 struct list_head mcount_loc_list; 23 24 bool ignore_unreachables, c_file, hints, rodata;
+1
tools/objtool/objtool.c
··· 61 61 62 62 INIT_LIST_HEAD(&file.insn_list); 63 63 hash_init(file.insn_hash); 64 + INIT_LIST_HEAD(&file.retpoline_call_list); 64 65 INIT_LIST_HEAD(&file.static_call_list); 65 66 INIT_LIST_HEAD(&file.mcount_loc_list); 66 67 file.c_file = !vmlinux && find_section_by_name(file.elf, ".comment");
+5 -28
tools/objtool/orc_gen.c
··· 82 82 } 83 83 84 84 static int write_orc_entry(struct elf *elf, struct section *orc_sec, 85 - struct section *ip_rsec, unsigned int idx, 85 + struct section *ip_sec, unsigned int idx, 86 86 struct section *insn_sec, unsigned long insn_off, 87 87 struct orc_entry *o) 88 88 { 89 89 struct orc_entry *orc; 90 - struct reloc *reloc; 91 90 92 91 /* populate ORC data */ 93 92 orc = (struct orc_entry *)orc_sec->data->d_buf + idx; ··· 95 96 orc->bp_offset = bswap_if_needed(orc->bp_offset); 96 97 97 98 /* populate reloc for ip */ 98 - reloc = malloc(sizeof(*reloc)); 99 - if (!reloc) { 100 - perror("malloc"); 99 + if (elf_add_reloc_to_insn(elf, ip_sec, idx * sizeof(int), R_X86_64_PC32, 100 + insn_sec, insn_off)) 101 101 return -1; 102 - } 103 - memset(reloc, 0, sizeof(*reloc)); 104 - 105 - insn_to_reloc_sym_addend(insn_sec, insn_off, reloc); 106 - if (!reloc->sym) { 107 - WARN("missing symbol for insn at offset 0x%lx", 108 - insn_off); 109 - return -1; 110 - } 111 - 112 - reloc->type = R_X86_64_PC32; 113 - reloc->offset = idx * sizeof(int); 114 - reloc->sec = ip_rsec; 115 - 116 - elf_add_reloc(elf, reloc); 117 102 118 103 return 0; 119 104 } ··· 136 153 137 154 int orc_create(struct objtool_file *file) 138 155 { 139 - struct section *sec, *ip_rsec, *orc_sec; 156 + struct section *sec, *orc_sec; 140 157 unsigned int nr = 0, idx = 0; 141 158 struct orc_list_entry *entry; 142 159 struct list_head orc_list; ··· 225 242 sec = elf_create_section(file->elf, ".orc_unwind_ip", 0, sizeof(int), nr); 226 243 if (!sec) 227 244 return -1; 228 - ip_rsec = elf_create_reloc_section(file->elf, sec, SHT_RELA); 229 - if (!ip_rsec) 230 - return -1; 231 245 232 246 /* Write ORC entries to sections: */ 233 247 list_for_each_entry(entry, &orc_list, list) { 234 - if (write_orc_entry(file->elf, orc_sec, ip_rsec, idx++, 248 + if (write_orc_entry(file->elf, orc_sec, sec, idx++, 235 249 entry->insn_sec, entry->insn_off, 236 250 &entry->orc)) 237 251 return -1; 238 252 } 239 - 240 - if (elf_rebuild_reloc_section(file->elf, ip_rsec)) 241 - return -1; 242 253 243 254 return 0; 244 255 }
+11 -1
tools/objtool/special.c
··· 106 106 return -1; 107 107 } 108 108 109 + /* 110 + * Skip retpoline .altinstr_replacement... we already rewrite the 111 + * instructions for retpolines anyway, see arch_is_retpoline() 112 + * usage in add_{call,jump}_destinations(). 113 + */ 114 + if (arch_is_retpoline(new_reloc->sym)) 115 + return 1; 116 + 109 117 alt->new_sec = new_reloc->sym->sec; 110 118 alt->new_off = (unsigned int)new_reloc->addend; 111 119 ··· 162 154 memset(alt, 0, sizeof(*alt)); 163 155 164 156 ret = get_alt_entry(elf, entry, sec, idx, alt); 165 - if (ret) 157 + if (ret > 0) 158 + continue; 159 + if (ret < 0) 166 160 return ret; 167 161 168 162 list_add_tail(&alt->list, alts);
+14 -4
tools/objtool/sync-check.sh
··· 10 10 11 11 if [ "$SRCARCH" = "x86" ]; then 12 12 FILES="$FILES 13 + arch/x86/include/asm/nops.h 13 14 arch/x86/include/asm/inat_types.h 14 15 arch/x86/include/asm/orc_types.h 15 16 arch/x86/include/asm/emulate_prefix.h 16 17 arch/x86/lib/x86-opcode-map.txt 17 18 arch/x86/tools/gen-insn-attr-x86.awk 18 19 include/linux/static_call_types.h 19 - arch/x86/include/asm/inat.h -I '^#include [\"<]\(asm/\)*inat_types.h[\">]' 20 - arch/x86/include/asm/insn.h -I '^#include [\"<]\(asm/\)*inat.h[\">]' 21 - arch/x86/lib/inat.c -I '^#include [\"<]\(../include/\)*asm/insn.h[\">]' 22 - arch/x86/lib/insn.c -I '^#include [\"<]\(../include/\)*asm/in\(at\|sn\).h[\">]' -I '^#include [\"<]\(../include/\)*asm/emulate_prefix.h[\">]' 23 20 " 21 + 22 + SYNC_CHECK_FILES=' 23 + arch/x86/include/asm/inat.h 24 + arch/x86/include/asm/insn.h 25 + arch/x86/lib/inat.c 26 + arch/x86/lib/insn.c 27 + ' 24 28 fi 25 29 26 30 check_2 () { ··· 67 63 done <<EOF 68 64 $FILES 69 65 EOF 66 + 67 + if [ "$SRCARCH" = "x86" ]; then 68 + for i in $SYNC_CHECK_FILES; do 69 + check $i '-I "^.*\/\*.*__ignore_sync_check__.*\*\/.*$"' 70 + done 71 + fi
+4 -5
tools/perf/arch/x86/tests/insn-x86.c
··· 96 96 static int test_data_item(struct test_data *dat, int x86_64) 97 97 { 98 98 struct intel_pt_insn intel_pt_insn; 99 + int op, branch, ret; 99 100 struct insn insn; 100 - int op, branch; 101 101 102 - insn_init(&insn, dat->data, MAX_INSN_SIZE, x86_64); 103 - insn_get_length(&insn); 104 - 105 - if (!insn_complete(&insn)) { 102 + ret = insn_decode(&insn, dat->data, MAX_INSN_SIZE, 103 + x86_64 ? INSN_MODE_64 : INSN_MODE_32); 104 + if (ret < 0) { 106 105 pr_debug("Failed to decode: %s\n", dat->asm_rep); 107 106 return -1; 108 107 }
+5 -4
tools/perf/arch/x86/util/archinsn.c
··· 11 11 struct machine *machine) 12 12 { 13 13 struct insn insn; 14 - int len; 14 + int len, ret; 15 15 bool is64bit = false; 16 16 17 17 if (!sample->ip) ··· 19 19 len = thread__memcpy(thread, machine, sample->insn, sample->ip, sizeof(sample->insn), &is64bit); 20 20 if (len <= 0) 21 21 return; 22 - insn_init(&insn, sample->insn, len, is64bit); 23 - insn_get_length(&insn); 24 - if (insn_complete(&insn) && insn.length <= len) 22 + 23 + ret = insn_decode(&insn, sample->insn, len, 24 + is64bit ? INSN_MODE_64 : INSN_MODE_32); 25 + if (ret >= 0 && insn.length <= len) 25 26 sample->insn_len = insn.length; 26 27 }
+11 -4
tools/perf/check-headers.sh
··· 75 75 include/uapi/asm-generic/unistd.h 76 76 ' 77 77 78 + SYNC_CHECK_FILES=' 79 + arch/x86/include/asm/inat.h 80 + arch/x86/include/asm/insn.h 81 + arch/x86/lib/inat.c 82 + arch/x86/lib/insn.c 83 + ' 84 + 78 85 # These copies are under tools/perf/trace/beauty/ as they are not used to in 79 86 # building object files only by scripts in tools/perf/trace/beauty/ to generate 80 87 # tables that then gets included in .c files for things like id->string syscall ··· 136 129 check $i -B 137 130 done 138 131 132 + for i in $SYNC_CHECK_FILES; do 133 + check $i '-I "^.*\/\*.*__ignore_sync_check__.*\*\/.*$"' 134 + done 135 + 139 136 # diff with extra ignore lines 140 137 check arch/x86/lib/memcpy_64.S '-I "^EXPORT_SYMBOL" -I "^#include <asm/export.h>" -I"^SYM_FUNC_START\(_LOCAL\)*(memcpy_\(erms\|orig\))"' 141 138 check arch/x86/lib/memset_64.S '-I "^EXPORT_SYMBOL" -I "^#include <asm/export.h>" -I"^SYM_FUNC_START\(_LOCAL\)*(memset_\(erms\|orig\))"' ··· 148 137 check include/linux/build_bug.h '-I "^#\(ifndef\|endif\)\( \/\/\)* static_assert$"' 149 138 check include/linux/ctype.h '-I "isdigit("' 150 139 check lib/ctype.c '-I "^EXPORT_SYMBOL" -I "^#include <linux/export.h>" -B' 151 - check arch/x86/include/asm/inat.h '-I "^#include [\"<]\(asm/\)*inat_types.h[\">]"' 152 - check arch/x86/include/asm/insn.h '-I "^#include [\"<]\(asm/\)*inat.h[\">]"' 153 - check arch/x86/lib/inat.c '-I "^#include [\"<]\(../include/\)*asm/insn.h[\">]"' 154 - check arch/x86/lib/insn.c '-I "^#include [\"<]\(../include/\)*asm/in\(at\|sn\).h[\">]" -I "^#include [\"<]\(../include/\)*asm/emulate_prefix.h[\">]"' 155 140 156 141 # diff non-symmetric files 157 142 check_2 tools/perf/arch/x86/entry/syscalls/syscall_64.tbl arch/x86/entry/syscalls/syscall_64.tbl
+10 -7
tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.c
··· 169 169 struct intel_pt_insn *intel_pt_insn) 170 170 { 171 171 struct insn insn; 172 + int ret; 172 173 173 - insn_init(&insn, buf, len, x86_64); 174 - insn_get_length(&insn); 175 - if (!insn_complete(&insn) || insn.length > len) 174 + ret = insn_decode(&insn, buf, len, 175 + x86_64 ? INSN_MODE_64 : INSN_MODE_32); 176 + if (ret < 0 || insn.length > len) 176 177 return -1; 178 + 177 179 intel_pt_insn_decoder(&insn, intel_pt_insn); 178 180 if (insn.length < INTEL_PT_INSN_BUF_SZ) 179 181 memcpy(intel_pt_insn->buf, buf, insn.length); ··· 196 194 u8 *inbuf, int inlen, int *lenp) 197 195 { 198 196 struct insn insn; 199 - int n, i; 197 + int n, i, ret; 200 198 int left; 201 199 202 - insn_init(&insn, inbuf, inlen, x->is64bit); 203 - insn_get_length(&insn); 204 - if (!insn_complete(&insn) || insn.length > inlen) 200 + ret = insn_decode(&insn, inbuf, inlen, 201 + x->is64bit ? INSN_MODE_64 : INSN_MODE_32); 202 + 203 + if (ret < 0 || insn.length > inlen) 205 204 return "<bad>"; 206 205 if (lenp) 207 206 *lenp = insn.length;