1 /* SPDX-License-Identifier: GPL-2.0 */ 2 3 #ifndef _ASM_X86_NOSPEC_BRANCH_H_ 4 #define _ASM_X86_NOSPEC_BRANCH_H_ 5 6 #include <linux/static_key.h> 7 #include <linux/objtool.h> 8 #include <linux/linkage.h> 9 10 #include <asm/alternative.h> 11 #include <asm/cpufeatures.h> 12 #include <asm/msr-index.h> 13 #include <asm/unwind_hints.h> 14 #include <asm/percpu.h> 15 #include <asm/current.h> 16 17 /* 18 * Call depth tracking for Intel SKL CPUs to address the RSB underflow 19 * issue in software. 20 * 21 * The tracking does not use a counter. It uses uses arithmetic shift 22 * right on call entry and logical shift left on return. 23 * 24 * The depth tracking variable is initialized to 0x8000.... when the call 25 * depth is zero. The arithmetic shift right sign extends the MSB and 26 * saturates after the 12th call. The shift count is 5 for both directions 27 * so the tracking covers 12 nested calls. 28 * 29 * Call 30 * 0: 0x8000000000000000 0x0000000000000000 31 * 1: 0xfc00000000000000 0xf000000000000000 32 * ... 33 * 11: 0xfffffffffffffff8 0xfffffffffffffc00 34 * 12: 0xffffffffffffffff 0xffffffffffffffe0 35 * 36 * After a return buffer fill the depth is credited 12 calls before the 37 * next stuffing has to take place. 38 * 39 * There is a inaccuracy for situations like this: 40 * 41 * 10 calls 42 * 5 returns 43 * 3 calls 44 * 4 returns 45 * 3 calls 46 * .... 47 * 48 * The shift count might cause this to be off by one in either direction, 49 * but there is still a cushion vs. the RSB depth. The algorithm does not 50 * claim to be perfect and it can be speculated around by the CPU, but it 51 * is considered that it obfuscates the problem enough to make exploitation 52 * extremely difficult. 53 */ 54 #define RET_DEPTH_SHIFT 5 55 #define RSB_RET_STUFF_LOOPS 16 56 #define RET_DEPTH_INIT 0x8000000000000000ULL 57 #define RET_DEPTH_INIT_FROM_CALL 0xfc00000000000000ULL 58 #define RET_DEPTH_CREDIT 0xffffffffffffffffULL 59 60 #ifdef CONFIG_CALL_THUNKS_DEBUG 61 # define CALL_THUNKS_DEBUG_INC_CALLS \ 62 incq PER_CPU_VAR(__x86_call_count); 63 # define CALL_THUNKS_DEBUG_INC_RETS \ 64 incq PER_CPU_VAR(__x86_ret_count); 65 # define CALL_THUNKS_DEBUG_INC_STUFFS \ 66 incq PER_CPU_VAR(__x86_stuffs_count); 67 # define CALL_THUNKS_DEBUG_INC_CTXSW \ 68 incq PER_CPU_VAR(__x86_ctxsw_count); 69 #else 70 # define CALL_THUNKS_DEBUG_INC_CALLS 71 # define CALL_THUNKS_DEBUG_INC_RETS 72 # define CALL_THUNKS_DEBUG_INC_STUFFS 73 # define CALL_THUNKS_DEBUG_INC_CTXSW 74 #endif 75 76 #if defined(CONFIG_MITIGATION_CALL_DEPTH_TRACKING) && !defined(COMPILE_OFFSETS) 77 78 #include <asm/asm-offsets.h> 79 80 #define CREDIT_CALL_DEPTH \ 81 movq $-1, PER_CPU_VAR(pcpu_hot + X86_call_depth); 82 83 #define RESET_CALL_DEPTH \ 84 xor %eax, %eax; \ 85 bts $63, %rax; \ 86 movq %rax, PER_CPU_VAR(pcpu_hot + X86_call_depth); 87 88 #define RESET_CALL_DEPTH_FROM_CALL \ 89 movb $0xfc, %al; \ 90 shl $56, %rax; \ 91 movq %rax, PER_CPU_VAR(pcpu_hot + X86_call_depth); \ 92 CALL_THUNKS_DEBUG_INC_CALLS 93 94 #define INCREMENT_CALL_DEPTH \ 95 sarq $5, PER_CPU_VAR(pcpu_hot + X86_call_depth); \ 96 CALL_THUNKS_DEBUG_INC_CALLS 97 98 #else 99 #define CREDIT_CALL_DEPTH 100 #define RESET_CALL_DEPTH 101 #define RESET_CALL_DEPTH_FROM_CALL 102 #define INCREMENT_CALL_DEPTH 103 #endif 104 105 /* 106 * Fill the CPU return stack buffer. 107 * 108 * Each entry in the RSB, if used for a speculative 'ret', contains an 109 * infinite 'pause; lfence; jmp' loop to capture speculative execution. 110 * 111 * This is required in various cases for retpoline and IBRS-based 112 * mitigations for the Spectre variant 2 vulnerability. Sometimes to 113 * eliminate potentially bogus entries from the RSB, and sometimes 114 * purely to ensure that it doesn't get empty, which on some CPUs would 115 * allow predictions from other (unwanted!) sources to be used. 116 * 117 * We define a CPP macro such that it can be used from both .S files and 118 * inline assembly. It's possible to do a .macro and then include that 119 * from C via asm(".include <asm/nospec-branch.h>") but let's not go there. 120 */ 121 122 #define RETPOLINE_THUNK_SIZE 32 123 #define RSB_CLEAR_LOOPS 32 /* To forcibly overwrite all entries */ 124 125 /* 126 * Common helper for __FILL_RETURN_BUFFER and __FILL_ONE_RETURN. 127 */ 128 #define __FILL_RETURN_SLOT \ 129 ANNOTATE_INTRA_FUNCTION_CALL; \ 130 call 772f; \ 131 int3; \ 132 772: 133 134 /* 135 * Stuff the entire RSB. 136 * 137 * Google experimented with loop-unrolling and this turned out to be 138 * the optimal version - two calls, each with their own speculation 139 * trap should their return address end up getting used, in a loop. 140 */ 141 #ifdef CONFIG_X86_64 142 #define __FILL_RETURN_BUFFER(reg, nr) \ 143 mov $(nr/2), reg; \ 144 771: \ 145 __FILL_RETURN_SLOT \ 146 __FILL_RETURN_SLOT \ 147 add $(BITS_PER_LONG/8) * 2, %_ASM_SP; \ 148 dec reg; \ 149 jnz 771b; \ 150 /* barrier for jnz misprediction */ \ 151 lfence; \ 152 CREDIT_CALL_DEPTH \ 153 CALL_THUNKS_DEBUG_INC_CTXSW 154 #else 155 /* 156 * i386 doesn't unconditionally have LFENCE, as such it can't 157 * do a loop. 158 */ 159 #define __FILL_RETURN_BUFFER(reg, nr) \ 160 .rept nr; \ 161 __FILL_RETURN_SLOT; \ 162 .endr; \ 163 add $(BITS_PER_LONG/8) * nr, %_ASM_SP; 164 #endif 165 166 /* 167 * Stuff a single RSB slot. 168 * 169 * To mitigate Post-Barrier RSB speculation, one CALL instruction must be 170 * forced to retire before letting a RET instruction execute. 171 * 172 * On PBRSB-vulnerable CPUs, it is not safe for a RET to be executed 173 * before this point. 174 */ 175 #define __FILL_ONE_RETURN \ 176 __FILL_RETURN_SLOT \ 177 add $(BITS_PER_LONG/8), %_ASM_SP; \ 178 lfence; 179 180 #ifdef __ASSEMBLY__ 181 182 /* 183 * (ab)use RETPOLINE_SAFE on RET to annotate away 'bare' RET instructions 184 * vs RETBleed validation. 185 */ 186 #define ANNOTATE_UNRET_SAFE ANNOTATE_RETPOLINE_SAFE 187 188 /* 189 * Abuse ANNOTATE_RETPOLINE_SAFE on a NOP to indicate UNRET_END, should 190 * eventually turn into its own annotation. 191 */ 192 .macro VALIDATE_UNRET_END 193 #if defined(CONFIG_NOINSTR_VALIDATION) && \ 194 (defined(CONFIG_MITIGATION_UNRET_ENTRY) || defined(CONFIG_MITIGATION_SRSO)) 195 ANNOTATE_RETPOLINE_SAFE 196 nop 197 #endif 198 .endm 199 200 /* 201 * Equivalent to -mindirect-branch-cs-prefix; emit the 5 byte jmp/call 202 * to the retpoline thunk with a CS prefix when the register requires 203 * a RAX prefix byte to encode. Also see apply_retpolines(). 204 */ 205 .macro __CS_PREFIX reg:req 206 .irp rs,r8,r9,r10,r11,r12,r13,r14,r15 207 .ifc \reg,\rs 208 .byte 0x2e 209 .endif 210 .endr 211 .endm 212 213 /* 214 * JMP_NOSPEC and CALL_NOSPEC macros can be used instead of a simple 215 * indirect jmp/call which may be susceptible to the Spectre variant 2 216 * attack. 217 * 218 * NOTE: these do not take kCFI into account and are thus not comparable to C 219 * indirect calls, take care when using. The target of these should be an ENDBR 220 * instruction irrespective of kCFI. 221 */ 222 .macro JMP_NOSPEC reg:req 223 #ifdef CONFIG_MITIGATION_RETPOLINE 224 __CS_PREFIX \reg 225 jmp __x86_indirect_thunk_\reg 226 #else 227 jmp *%\reg 228 int3 229 #endif 230 .endm 231 232 .macro CALL_NOSPEC reg:req 233 #ifdef CONFIG_MITIGATION_RETPOLINE 234 __CS_PREFIX \reg 235 call __x86_indirect_thunk_\reg 236 #else 237 call *%\reg 238 #endif 239 .endm 240 241 /* 242 * A simpler FILL_RETURN_BUFFER macro. Don't make people use the CPP 243 * monstrosity above, manually. 244 */ 245 .macro FILL_RETURN_BUFFER reg:req nr:req ftr:req ftr2=ALT_NOT(X86_FEATURE_ALWAYS) 246 ALTERNATIVE_2 "jmp .Lskip_rsb_\@", \ 247 __stringify(__FILL_RETURN_BUFFER(\reg,\nr)), \ftr, \ 248 __stringify(nop;nop;__FILL_ONE_RETURN), \ftr2 249 250 .Lskip_rsb_\@: 251 .endm 252 253 /* 254 * The CALL to srso_alias_untrain_ret() must be patched in directly at 255 * the spot where untraining must be done, ie., srso_alias_untrain_ret() 256 * must be the target of a CALL instruction instead of indirectly 257 * jumping to a wrapper which then calls it. Therefore, this macro is 258 * called outside of __UNTRAIN_RET below, for the time being, before the 259 * kernel can support nested alternatives with arbitrary nesting. 260 */ 261 .macro CALL_UNTRAIN_RET 262 #if defined(CONFIG_MITIGATION_UNRET_ENTRY) || defined(CONFIG_MITIGATION_SRSO) 263 ALTERNATIVE_2 "", "call entry_untrain_ret", X86_FEATURE_UNRET, \ 264 "call srso_alias_untrain_ret", X86_FEATURE_SRSO_ALIAS 265 #endif 266 .endm 267 268 /* 269 * Mitigate RETBleed for AMD/Hygon Zen uarch. Requires KERNEL CR3 because the 270 * return thunk isn't mapped into the userspace tables (then again, AMD 271 * typically has NO_MELTDOWN). 272 * 273 * While retbleed_untrain_ret() doesn't clobber anything but requires stack, 274 * entry_ibpb() will clobber AX, CX, DX. 275 * 276 * As such, this must be placed after every *SWITCH_TO_KERNEL_CR3 at a point 277 * where we have a stack but before any RET instruction. 278 */ 279 .macro __UNTRAIN_RET ibpb_feature, call_depth_insns 280 #if defined(CONFIG_MITIGATION_RETHUNK) || defined(CONFIG_MITIGATION_IBPB_ENTRY) 281 VALIDATE_UNRET_END 282 CALL_UNTRAIN_RET 283 ALTERNATIVE_2 "", \ 284 "call entry_ibpb", \ibpb_feature, \ 285 __stringify(\call_depth_insns), X86_FEATURE_CALL_DEPTH 286 #endif 287 .endm 288 289 #define UNTRAIN_RET \ 290 __UNTRAIN_RET X86_FEATURE_ENTRY_IBPB, __stringify(RESET_CALL_DEPTH) 291 292 #define UNTRAIN_RET_VM \ 293 __UNTRAIN_RET X86_FEATURE_IBPB_ON_VMEXIT, __stringify(RESET_CALL_DEPTH) 294 295 #define UNTRAIN_RET_FROM_CALL \ 296 __UNTRAIN_RET X86_FEATURE_ENTRY_IBPB, __stringify(RESET_CALL_DEPTH_FROM_CALL) 297 298 299 .macro CALL_DEPTH_ACCOUNT 300 #ifdef CONFIG_MITIGATION_CALL_DEPTH_TRACKING 301 ALTERNATIVE "", \ 302 __stringify(INCREMENT_CALL_DEPTH), X86_FEATURE_CALL_DEPTH 303 #endif 304 .endm 305 306 /* 307 * Macro to execute VERW instruction that mitigate transient data sampling 308 * attacks such as MDS. On affected systems a microcode update overloaded VERW 309 * instruction to also clear the CPU buffers. VERW clobbers CFLAGS.ZF. 310 * 311 * Note: Only the memory operand variant of VERW clears the CPU buffers. 312 */ 313 .macro CLEAR_CPU_BUFFERS 314 #ifdef CONFIG_X86_64 315 ALTERNATIVE "", "verw mds_verw_sel(%rip)", X86_FEATURE_CLEAR_CPU_BUF 316 #else 317 /* 318 * In 32bit mode, the memory operand must be a %cs reference. The data 319 * segments may not be usable (vm86 mode), and the stack segment may not 320 * be flat (ESPFIX32). 321 */ 322 ALTERNATIVE "", "verw %cs:mds_verw_sel", X86_FEATURE_CLEAR_CPU_BUF 323 #endif 324 .endm 325 326 #ifdef CONFIG_X86_64 327 .macro CLEAR_BRANCH_HISTORY 328 ALTERNATIVE "", "call clear_bhb_loop", X86_FEATURE_CLEAR_BHB_LOOP 329 .endm 330 331 .macro CLEAR_BRANCH_HISTORY_VMEXIT 332 ALTERNATIVE "", "call clear_bhb_loop", X86_FEATURE_CLEAR_BHB_LOOP_ON_VMEXIT 333 .endm 334 #else 335 #define CLEAR_BRANCH_HISTORY 336 #define CLEAR_BRANCH_HISTORY_VMEXIT 337 #endif 338 339 #else /* __ASSEMBLY__ */ 340 341 typedef u8 retpoline_thunk_t[RETPOLINE_THUNK_SIZE]; 342 extern retpoline_thunk_t __x86_indirect_thunk_array[]; 343 extern retpoline_thunk_t __x86_indirect_call_thunk_array[]; 344 extern retpoline_thunk_t __x86_indirect_jump_thunk_array[]; 345 346 #ifdef CONFIG_MITIGATION_RETHUNK 347 extern void __x86_return_thunk(void); 348 #else 349 static inline void __x86_return_thunk(void) {} 350 #endif 351 352 #ifdef CONFIG_MITIGATION_UNRET_ENTRY 353 extern void retbleed_return_thunk(void); 354 #else 355 static inline void retbleed_return_thunk(void) {} 356 #endif 357 358 extern void srso_alias_untrain_ret(void); 359 360 #ifdef CONFIG_MITIGATION_SRSO 361 extern void srso_return_thunk(void); 362 extern void srso_alias_return_thunk(void); 363 #else 364 static inline void srso_return_thunk(void) {} 365 static inline void srso_alias_return_thunk(void) {} 366 #endif 367 368 extern void retbleed_return_thunk(void); 369 extern void srso_return_thunk(void); 370 extern void srso_alias_return_thunk(void); 371 372 extern void entry_untrain_ret(void); 373 extern void entry_ibpb(void); 374 375 #ifdef CONFIG_X86_64 376 extern void clear_bhb_loop(void); 377 #endif 378 379 extern void (*x86_return_thunk)(void); 380 381 extern void __warn_thunk(void); 382 383 #ifdef CONFIG_MITIGATION_CALL_DEPTH_TRACKING 384 extern void call_depth_return_thunk(void); 385 386 #define CALL_DEPTH_ACCOUNT \ 387 ALTERNATIVE("", \ 388 __stringify(INCREMENT_CALL_DEPTH), \ 389 X86_FEATURE_CALL_DEPTH) 390 391 #ifdef CONFIG_CALL_THUNKS_DEBUG 392 DECLARE_PER_CPU(u64, __x86_call_count); 393 DECLARE_PER_CPU(u64, __x86_ret_count); 394 DECLARE_PER_CPU(u64, __x86_stuffs_count); 395 DECLARE_PER_CPU(u64, __x86_ctxsw_count); 396 #endif 397 #else /* !CONFIG_MITIGATION_CALL_DEPTH_TRACKING */ 398 399 static inline void call_depth_return_thunk(void) {} 400 #define CALL_DEPTH_ACCOUNT "" 401 402 #endif /* CONFIG_MITIGATION_CALL_DEPTH_TRACKING */ 403 404 #ifdef CONFIG_MITIGATION_RETPOLINE 405 406 #define GEN(reg) \ 407 extern retpoline_thunk_t __x86_indirect_thunk_ ## reg; 408 #include <asm/GEN-for-each-reg.h> 409 #undef GEN 410 411 #define GEN(reg) \ 412 extern retpoline_thunk_t __x86_indirect_call_thunk_ ## reg; 413 #include <asm/GEN-for-each-reg.h> 414 #undef GEN 415 416 #define GEN(reg) \ 417 extern retpoline_thunk_t __x86_indirect_jump_thunk_ ## reg; 418 #include <asm/GEN-for-each-reg.h> 419 #undef GEN 420 421 #ifdef CONFIG_X86_64 422 423 /* 424 * Inline asm uses the %V modifier which is only in newer GCC 425 * which is ensured when CONFIG_MITIGATION_RETPOLINE is defined. 426 */ 427 # define CALL_NOSPEC \ 428 ALTERNATIVE_2( \ 429 ANNOTATE_RETPOLINE_SAFE \ 430 "call *%[thunk_target]\n", \ 431 "call __x86_indirect_thunk_%V[thunk_target]\n", \ 432 X86_FEATURE_RETPOLINE, \ 433 "lfence;\n" \ 434 ANNOTATE_RETPOLINE_SAFE \ 435 "call *%[thunk_target]\n", \ 436 X86_FEATURE_RETPOLINE_LFENCE) 437 438 # define THUNK_TARGET(addr) [thunk_target] "r" (addr) 439 440 #else /* CONFIG_X86_32 */ 441 /* 442 * For i386 we use the original ret-equivalent retpoline, because 443 * otherwise we'll run out of registers. We don't care about CET 444 * here, anyway. 445 */ 446 # define CALL_NOSPEC \ 447 ALTERNATIVE_2( \ 448 ANNOTATE_RETPOLINE_SAFE \ 449 "call *%[thunk_target]\n", \ 450 " jmp 904f;\n" \ 451 " .align 16\n" \ 452 "901: call 903f;\n" \ 453 "902: pause;\n" \ 454 " lfence;\n" \ 455 " jmp 902b;\n" \ 456 " .align 16\n" \ 457 "903: lea 4(%%esp), %%esp;\n" \ 458 " pushl %[thunk_target];\n" \ 459 " ret;\n" \ 460 " .align 16\n" \ 461 "904: call 901b;\n", \ 462 X86_FEATURE_RETPOLINE, \ 463 "lfence;\n" \ 464 ANNOTATE_RETPOLINE_SAFE \ 465 "call *%[thunk_target]\n", \ 466 X86_FEATURE_RETPOLINE_LFENCE) 467 468 # define THUNK_TARGET(addr) [thunk_target] "rm" (addr) 469 #endif 470 #else /* No retpoline for C / inline asm */ 471 # define CALL_NOSPEC "call *%[thunk_target]\n" 472 # define THUNK_TARGET(addr) [thunk_target] "rm" (addr) 473 #endif 474 475 /* The Spectre V2 mitigation variants */ 476 enum spectre_v2_mitigation { 477 SPECTRE_V2_NONE, 478 SPECTRE_V2_RETPOLINE, 479 SPECTRE_V2_LFENCE, 480 SPECTRE_V2_EIBRS, 481 SPECTRE_V2_EIBRS_RETPOLINE, 482 SPECTRE_V2_EIBRS_LFENCE, 483 SPECTRE_V2_IBRS, 484 }; 485 486 /* The indirect branch speculation control variants */ 487 enum spectre_v2_user_mitigation { 488 SPECTRE_V2_USER_NONE, 489 SPECTRE_V2_USER_STRICT, 490 SPECTRE_V2_USER_STRICT_PREFERRED, 491 SPECTRE_V2_USER_PRCTL, 492 SPECTRE_V2_USER_SECCOMP, 493 }; 494 495 /* The Speculative Store Bypass disable variants */ 496 enum ssb_mitigation { 497 SPEC_STORE_BYPASS_NONE, 498 SPEC_STORE_BYPASS_DISABLE, 499 SPEC_STORE_BYPASS_PRCTL, 500 SPEC_STORE_BYPASS_SECCOMP, 501 }; 502 503 static __always_inline 504 void alternative_msr_write(unsigned int msr, u64 val, unsigned int feature) 505 { 506 asm volatile(ALTERNATIVE("", "wrmsr", %c[feature]) 507 : : "c" (msr), 508 "a" ((u32)val), 509 "d" ((u32)(val >> 32)), 510 [feature] "i" (feature) 511 : "memory"); 512 } 513 514 extern u64 x86_pred_cmd; 515 516 static inline void indirect_branch_prediction_barrier(void) 517 { 518 alternative_msr_write(MSR_IA32_PRED_CMD, x86_pred_cmd, X86_FEATURE_USE_IBPB); 519 } 520 521 /* The Intel SPEC CTRL MSR base value cache */ 522 extern u64 x86_spec_ctrl_base; 523 DECLARE_PER_CPU(u64, x86_spec_ctrl_current); 524 extern void update_spec_ctrl_cond(u64 val); 525 extern u64 spec_ctrl_current(void); 526 527 /* 528 * With retpoline, we must use IBRS to restrict branch prediction 529 * before calling into firmware. 530 * 531 * (Implemented as CPP macros due to header hell.) 532 */ 533 #define firmware_restrict_branch_speculation_start() \ 534 do { \ 535 preempt_disable(); \ 536 alternative_msr_write(MSR_IA32_SPEC_CTRL, \ 537 spec_ctrl_current() | SPEC_CTRL_IBRS, \ 538 X86_FEATURE_USE_IBRS_FW); \ 539 alternative_msr_write(MSR_IA32_PRED_CMD, PRED_CMD_IBPB, \ 540 X86_FEATURE_USE_IBPB_FW); \ 541 } while (0) 542 543 #define firmware_restrict_branch_speculation_end() \ 544 do { \ 545 alternative_msr_write(MSR_IA32_SPEC_CTRL, \ 546 spec_ctrl_current(), \ 547 X86_FEATURE_USE_IBRS_FW); \ 548 preempt_enable(); \ 549 } while (0) 550 551 DECLARE_STATIC_KEY_FALSE(switch_to_cond_stibp); 552 DECLARE_STATIC_KEY_FALSE(switch_mm_cond_ibpb); 553 DECLARE_STATIC_KEY_FALSE(switch_mm_always_ibpb); 554 555 DECLARE_STATIC_KEY_FALSE(mds_idle_clear); 556 557 DECLARE_STATIC_KEY_FALSE(switch_mm_cond_l1d_flush); 558 559 DECLARE_STATIC_KEY_FALSE(mmio_stale_data_clear); 560 561 extern u16 mds_verw_sel; 562 563 #include <asm/segment.h> 564 565 /** 566 * mds_clear_cpu_buffers - Mitigation for MDS and TAA vulnerability 567 * 568 * This uses the otherwise unused and obsolete VERW instruction in 569 * combination with microcode which triggers a CPU buffer flush when the 570 * instruction is executed. 571 */ 572 static __always_inline void mds_clear_cpu_buffers(void) 573 { 574 static const u16 ds = __KERNEL_DS; 575 576 /* 577 * Has to be the memory-operand variant because only that 578 * guarantees the CPU buffer flush functionality according to 579 * documentation. The register-operand variant does not. 580 * Works with any segment selector, but a valid writable 581 * data segment is the fastest variant. 582 * 583 * "cc" clobber is required because VERW modifies ZF. 584 */ 585 asm volatile("verw %[ds]" : : [ds] "m" (ds) : "cc"); 586 } 587 588 /** 589 * mds_idle_clear_cpu_buffers - Mitigation for MDS vulnerability 590 * 591 * Clear CPU buffers if the corresponding static key is enabled 592 */ 593 static __always_inline void mds_idle_clear_cpu_buffers(void) 594 { 595 if (static_branch_likely(&mds_idle_clear)) 596 mds_clear_cpu_buffers(); 597 } 598 599 #endif /* __ASSEMBLY__ */ 600 601 #endif /* _ASM_X86_NOSPEC_BRANCH_H_ */ 602