Merge branch 'x86-pti-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 pti fixes from Thomas Gleixner:
"A small set of fixes for the meltdown/spectre mitigations:

- Make kprobes aware of retpolines to prevent probes in the retpoline
thunks.

- Make the machine check exception speculation protected. MCE used to
issue an indirect call directly from the ASM entry code. Convert
that to a direct call into a C-function and issue the indirect call
from there so the compiler can add the retpoline protection,

- Make the vmexit_fill_RSB() assembly less stupid

- Fix a typo in the PTI documentation"

* 'x86-pti-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86/retpoline: Optimize inline assembler for vmexit_fill_RSB
x86/pti: Document fix wrong index
kprobes/x86: Disable optimizing on the function jumps to indirect thunk
kprobes/x86: Blacklist indirect thunk functions for kprobes
retpoline: Introduce start/end markers of indirect thunk
x86/mce: Make machine check speculation protected

Changed files
+46 -8
Documentation
x86
arch
x86
entry
include
kernel
cpu
mcheck
kprobes
lib
+1 -1
Documentation/x86/pti.txt
··· 78 78 non-PTI SYSCALL entry code, so requires mapping fewer 79 79 things into the userspace page tables. The downside is 80 80 that stacks must be switched at entry time. 81 - d. Global pages are disabled for all kernel structures not 81 + c. Global pages are disabled for all kernel structures not 82 82 mapped into both kernel and userspace page tables. This 83 83 feature of the MMU allows different processes to share TLB 84 84 entries mapping the kernel. Losing the feature means more
+1 -1
arch/x86/entry/entry_64.S
··· 1264 1264 #endif 1265 1265 1266 1266 #ifdef CONFIG_X86_MCE 1267 - idtentry machine_check has_error_code=0 paranoid=1 do_sym=*machine_check_vector(%rip) 1267 + idtentry machine_check do_mce has_error_code=0 paranoid=1 1268 1268 #endif 1269 1269 1270 1270 /*
+7 -3
arch/x86/include/asm/nospec-branch.h
··· 194 194 SPECTRE_V2_IBRS, 195 195 }; 196 196 197 + extern char __indirect_thunk_start[]; 198 + extern char __indirect_thunk_end[]; 199 + 197 200 /* 198 201 * On VMEXIT we must ensure that no RSB predictions learned in the guest 199 202 * can be followed in the host, by overwriting the RSB completely. Both ··· 206 203 static inline void vmexit_fill_RSB(void) 207 204 { 208 205 #ifdef CONFIG_RETPOLINE 209 - unsigned long loops = RSB_CLEAR_LOOPS / 2; 206 + unsigned long loops; 210 207 211 208 asm volatile (ANNOTATE_NOSPEC_ALTERNATIVE 212 209 ALTERNATIVE("jmp 910f", 213 210 __stringify(__FILL_RETURN_BUFFER(%0, RSB_CLEAR_LOOPS, %1)), 214 211 X86_FEATURE_RETPOLINE) 215 212 "910:" 216 - : "=&r" (loops), ASM_CALL_CONSTRAINT 217 - : "r" (loops) : "memory" ); 213 + : "=r" (loops), ASM_CALL_CONSTRAINT 214 + : : "memory" ); 218 215 #endif 219 216 } 217 + 220 218 #endif /* __ASSEMBLY__ */ 221 219 #endif /* __NOSPEC_BRANCH_H__ */
+1
arch/x86/include/asm/traps.h
··· 88 88 #ifdef CONFIG_X86_32 89 89 dotraplinkage void do_iret_error(struct pt_regs *, long); 90 90 #endif 91 + dotraplinkage void do_mce(struct pt_regs *, long); 91 92 92 93 static inline int get_si_code(unsigned long condition) 93 94 {
+5
arch/x86/kernel/cpu/mcheck/mce.c
··· 1785 1785 void (*machine_check_vector)(struct pt_regs *, long error_code) = 1786 1786 unexpected_machine_check; 1787 1787 1788 + dotraplinkage void do_mce(struct pt_regs *regs, long error_code) 1789 + { 1790 + machine_check_vector(regs, error_code); 1791 + } 1792 + 1788 1793 /* 1789 1794 * Called for each booted CPU to set up machine checks. 1790 1795 * Must be called with preempt off:
+22 -1
arch/x86/kernel/kprobes/opt.c
··· 40 40 #include <asm/debugreg.h> 41 41 #include <asm/set_memory.h> 42 42 #include <asm/sections.h> 43 + #include <asm/nospec-branch.h> 43 44 44 45 #include "common.h" 45 46 ··· 204 203 } 205 204 206 205 /* Check whether insn is indirect jump */ 207 - static int insn_is_indirect_jump(struct insn *insn) 206 + static int __insn_is_indirect_jump(struct insn *insn) 208 207 { 209 208 return ((insn->opcode.bytes[0] == 0xff && 210 209 (X86_MODRM_REG(insn->modrm.value) & 6) == 4) || /* Jump */ ··· 236 235 target = (unsigned long)insn->next_byte + insn->immediate.value; 237 236 238 237 return (start <= target && target <= start + len); 238 + } 239 + 240 + static int insn_is_indirect_jump(struct insn *insn) 241 + { 242 + int ret = __insn_is_indirect_jump(insn); 243 + 244 + #ifdef CONFIG_RETPOLINE 245 + /* 246 + * Jump to x86_indirect_thunk_* is treated as an indirect jump. 247 + * Note that even with CONFIG_RETPOLINE=y, the kernel compiled with 248 + * older gcc may use indirect jump. So we add this check instead of 249 + * replace indirect-jump check. 250 + */ 251 + if (!ret) 252 + ret = insn_jump_into_range(insn, 253 + (unsigned long)__indirect_thunk_start, 254 + (unsigned long)__indirect_thunk_end - 255 + (unsigned long)__indirect_thunk_start); 256 + #endif 257 + return ret; 239 258 } 240 259 241 260 /* Decode whole function to ensure any instructions don't jump into target */
+6
arch/x86/kernel/vmlinux.lds.S
··· 124 124 ASSERT(. - _entry_trampoline == PAGE_SIZE, "entry trampoline is too big"); 125 125 #endif 126 126 127 + #ifdef CONFIG_RETPOLINE 128 + __indirect_thunk_start = .; 129 + *(.text.__x86.indirect_thunk) 130 + __indirect_thunk_end = .; 131 + #endif 132 + 127 133 /* End of text section */ 128 134 _etext = .; 129 135 } :text = 0x9090
+3 -2
arch/x86/lib/retpoline.S
··· 9 9 #include <asm/nospec-branch.h> 10 10 11 11 .macro THUNK reg 12 - .section .text.__x86.indirect_thunk.\reg 12 + .section .text.__x86.indirect_thunk 13 13 14 14 ENTRY(__x86_indirect_thunk_\reg) 15 15 CFI_STARTPROC ··· 25 25 * than one per register with the correct names. So we do it 26 26 * the simple and nasty way... 27 27 */ 28 - #define EXPORT_THUNK(reg) EXPORT_SYMBOL(__x86_indirect_thunk_ ## reg) 28 + #define __EXPORT_THUNK(sym) _ASM_NOKPROBE(sym); EXPORT_SYMBOL(sym) 29 + #define EXPORT_THUNK(reg) __EXPORT_THUNK(__x86_indirect_thunk_ ## reg) 29 30 #define GENERATE_THUNK(reg) THUNK reg ; EXPORT_THUNK(reg) 30 31 31 32 GENERATE_THUNK(_ASM_AX)