aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/entry/calling.h17
-rw-r--r--arch/x86/entry/entry_64.S21
-rw-r--r--arch/x86/include/asm/cpufeatures.h2
3 files changed, 37 insertions, 3 deletions
diff --git a/arch/x86/entry/calling.h b/arch/x86/entry/calling.h
index 9f1f9e3b8230..7ce7ac9d9d3f 100644
--- a/arch/x86/entry/calling.h
+++ b/arch/x86/entry/calling.h
@@ -314,6 +314,23 @@ For 32-bit we have the following conventions - kernel is built with
314 314
315#endif 315#endif
316 316
317/*
318 * Mitigate Spectre v1 for conditional swapgs code paths.
319 *
320 * FENCE_SWAPGS_USER_ENTRY is used in the user entry swapgs code path, to
321 * prevent a speculative swapgs when coming from kernel space.
322 *
323 * FENCE_SWAPGS_KERNEL_ENTRY is used in the kernel entry non-swapgs code path,
324 * to prevent the swapgs from getting speculatively skipped when coming from
325 * user space.
326 */
327.macro FENCE_SWAPGS_USER_ENTRY
328 ALTERNATIVE "", "lfence", X86_FEATURE_FENCE_SWAPGS_USER
329.endm
330.macro FENCE_SWAPGS_KERNEL_ENTRY
331 ALTERNATIVE "", "lfence", X86_FEATURE_FENCE_SWAPGS_KERNEL
332.endm
333
317.macro STACKLEAK_ERASE_NOCLOBBER 334.macro STACKLEAK_ERASE_NOCLOBBER
318#ifdef CONFIG_GCC_PLUGIN_STACKLEAK 335#ifdef CONFIG_GCC_PLUGIN_STACKLEAK
319 PUSH_AND_CLEAR_REGS 336 PUSH_AND_CLEAR_REGS
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index a829dd3117d0..57a0d96d6beb 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -519,7 +519,7 @@ ENTRY(interrupt_entry)
519 testb $3, CS-ORIG_RAX+8(%rsp) 519 testb $3, CS-ORIG_RAX+8(%rsp)
520 jz 1f 520 jz 1f
521 SWAPGS 521 SWAPGS
522 522 FENCE_SWAPGS_USER_ENTRY
523 /* 523 /*
524 * Switch to the thread stack. The IRET frame and orig_ax are 524 * Switch to the thread stack. The IRET frame and orig_ax are
525 * on the stack, as well as the return address. RDI..R12 are 525 * on the stack, as well as the return address. RDI..R12 are
@@ -549,8 +549,10 @@ ENTRY(interrupt_entry)
549 UNWIND_HINT_FUNC 549 UNWIND_HINT_FUNC
550 550
551 movq (%rdi), %rdi 551 movq (%rdi), %rdi
552 jmpq 2f
5521: 5531:
553 554 FENCE_SWAPGS_KERNEL_ENTRY
5552:
554 PUSH_AND_CLEAR_REGS save_ret=1 556 PUSH_AND_CLEAR_REGS save_ret=1
555 ENCODE_FRAME_POINTER 8 557 ENCODE_FRAME_POINTER 8
556 558
@@ -1221,6 +1223,13 @@ ENTRY(paranoid_entry)
1221 */ 1223 */
1222 SAVE_AND_SWITCH_TO_KERNEL_CR3 scratch_reg=%rax save_reg=%r14 1224 SAVE_AND_SWITCH_TO_KERNEL_CR3 scratch_reg=%rax save_reg=%r14
1223 1225
1226 /*
1227 * The above SAVE_AND_SWITCH_TO_KERNEL_CR3 macro doesn't do an
1228 * unconditional CR3 write, even in the PTI case. So do an lfence
1229 * to prevent GS speculation, regardless of whether PTI is enabled.
1230 */
1231 FENCE_SWAPGS_KERNEL_ENTRY
1232
1224 ret 1233 ret
1225END(paranoid_entry) 1234END(paranoid_entry)
1226 1235
@@ -1271,6 +1280,7 @@ ENTRY(error_entry)
1271 * from user mode due to an IRET fault. 1280 * from user mode due to an IRET fault.
1272 */ 1281 */
1273 SWAPGS 1282 SWAPGS
1283 FENCE_SWAPGS_USER_ENTRY
1274 /* We have user CR3. Change to kernel CR3. */ 1284 /* We have user CR3. Change to kernel CR3. */
1275 SWITCH_TO_KERNEL_CR3 scratch_reg=%rax 1285 SWITCH_TO_KERNEL_CR3 scratch_reg=%rax
1276 1286
@@ -1292,6 +1302,8 @@ ENTRY(error_entry)
1292 CALL_enter_from_user_mode 1302 CALL_enter_from_user_mode
1293 ret 1303 ret
1294 1304
1305.Lerror_entry_done_lfence:
1306 FENCE_SWAPGS_KERNEL_ENTRY
1295.Lerror_entry_done: 1307.Lerror_entry_done:
1296 TRACE_IRQS_OFF 1308 TRACE_IRQS_OFF
1297 ret 1309 ret
@@ -1310,7 +1322,7 @@ ENTRY(error_entry)
1310 cmpq %rax, RIP+8(%rsp) 1322 cmpq %rax, RIP+8(%rsp)
1311 je .Lbstep_iret 1323 je .Lbstep_iret
1312 cmpq $.Lgs_change, RIP+8(%rsp) 1324 cmpq $.Lgs_change, RIP+8(%rsp)
1313 jne .Lerror_entry_done 1325 jne .Lerror_entry_done_lfence
1314 1326
1315 /* 1327 /*
1316 * hack: .Lgs_change can fail with user gsbase. If this happens, fix up 1328 * hack: .Lgs_change can fail with user gsbase. If this happens, fix up
@@ -1318,6 +1330,7 @@ ENTRY(error_entry)
1318 * .Lgs_change's error handler with kernel gsbase. 1330 * .Lgs_change's error handler with kernel gsbase.
1319 */ 1331 */
1320 SWAPGS 1332 SWAPGS
1333 FENCE_SWAPGS_USER_ENTRY
1321 SWITCH_TO_KERNEL_CR3 scratch_reg=%rax 1334 SWITCH_TO_KERNEL_CR3 scratch_reg=%rax
1322 jmp .Lerror_entry_done 1335 jmp .Lerror_entry_done
1323 1336
@@ -1332,6 +1345,7 @@ ENTRY(error_entry)
1332 * gsbase and CR3. Switch to kernel gsbase and CR3: 1345 * gsbase and CR3. Switch to kernel gsbase and CR3:
1333 */ 1346 */
1334 SWAPGS 1347 SWAPGS
1348 FENCE_SWAPGS_USER_ENTRY
1335 SWITCH_TO_KERNEL_CR3 scratch_reg=%rax 1349 SWITCH_TO_KERNEL_CR3 scratch_reg=%rax
1336 1350
1337 /* 1351 /*
@@ -1423,6 +1437,7 @@ ENTRY(nmi)
1423 1437
1424 swapgs 1438 swapgs
1425 cld 1439 cld
1440 FENCE_SWAPGS_USER_ENTRY
1426 SWITCH_TO_KERNEL_CR3 scratch_reg=%rdx 1441 SWITCH_TO_KERNEL_CR3 scratch_reg=%rdx
1427 movq %rsp, %rdx 1442 movq %rsp, %rdx
1428 movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp 1443 movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp
diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
index 998c2cc08363..4393278666d9 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -281,6 +281,8 @@
281#define X86_FEATURE_CQM_OCCUP_LLC (11*32+ 1) /* LLC occupancy monitoring */ 281#define X86_FEATURE_CQM_OCCUP_LLC (11*32+ 1) /* LLC occupancy monitoring */
282#define X86_FEATURE_CQM_MBM_TOTAL (11*32+ 2) /* LLC Total MBM monitoring */ 282#define X86_FEATURE_CQM_MBM_TOTAL (11*32+ 2) /* LLC Total MBM monitoring */
283#define X86_FEATURE_CQM_MBM_LOCAL (11*32+ 3) /* LLC Local MBM monitoring */ 283#define X86_FEATURE_CQM_MBM_LOCAL (11*32+ 3) /* LLC Local MBM monitoring */
284#define X86_FEATURE_FENCE_SWAPGS_USER (11*32+ 4) /* "" LFENCE in user entry SWAPGS path */
285#define X86_FEATURE_FENCE_SWAPGS_KERNEL (11*32+ 5) /* "" LFENCE in kernel entry SWAPGS path */
284 286
285/* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */ 287/* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */
286#define X86_FEATURE_AVX512_BF16 (12*32+ 5) /* AVX512 BFLOAT16 instructions */ 288#define X86_FEATURE_AVX512_BF16 (12*32+ 5) /* AVX512 BFLOAT16 instructions */