@@ -395,27 +395,40 @@ static __always_inline void amd_set_ssb_virt_state(unsigned long tifn)
395
395
wrmsrl (MSR_AMD64_VIRT_SPEC_CTRL , ssbd_tif_to_spec_ctrl (tifn ));
396
396
}
397
397
398
- static __always_inline void spec_ctrl_update_msr (unsigned long tifn )
399
- {
400
- u64 msr = x86_spec_ctrl_base | ssbd_tif_to_spec_ctrl (tifn );
401
-
402
- wrmsrl (MSR_IA32_SPEC_CTRL , msr );
403
- }
398
+ /*
399
+ * Update the MSRs managing speculation control, during context switch.
400
+ *
401
+ * tifp: Previous task's thread flags
402
+ * tifn: Next task's thread flags
403
+ */
404
+ static __always_inline void __speculation_ctrl_update (unsigned long tifp ,
405
+ unsigned long tifn )
406
+ {
407
+ u64 msr = x86_spec_ctrl_base ;
408
+ bool updmsr = false;
409
+
410
+ /* If TIF_SSBD is different, select the proper mitigation method */
411
+ if ((tifp ^ tifn ) & _TIF_SSBD ) {
412
+ if (static_cpu_has (X86_FEATURE_VIRT_SSBD )) {
413
+ amd_set_ssb_virt_state (tifn );
414
+ } else if (static_cpu_has (X86_FEATURE_LS_CFG_SSBD )) {
415
+ amd_set_core_ssb_state (tifn );
416
+ } else if (static_cpu_has (X86_FEATURE_SPEC_CTRL_SSBD ) ||
417
+ static_cpu_has (X86_FEATURE_AMD_SSBD )) {
418
+ msr |= ssbd_tif_to_spec_ctrl (tifn );
419
+ updmsr = true;
420
+ }
421
+ }
404
422
405
- static __always_inline void __speculation_ctrl_update (unsigned long tifn )
406
- {
407
- if (static_cpu_has (X86_FEATURE_VIRT_SSBD ))
408
- amd_set_ssb_virt_state (tifn );
409
- else if (static_cpu_has (X86_FEATURE_LS_CFG_SSBD ))
410
- amd_set_core_ssb_state (tifn );
411
- else
412
- spec_ctrl_update_msr (tifn );
423
+ if (updmsr )
424
+ wrmsrl (MSR_IA32_SPEC_CTRL , msr );
413
425
}
414
426
415
427
void speculation_ctrl_update (unsigned long tif )
416
428
{
429
+ /* Forced update. Make sure all relevant TIF flags are different */
417
430
preempt_disable ();
418
- __speculation_ctrl_update (tif );
431
+ __speculation_ctrl_update (~ tif , tif );
419
432
preempt_enable ();
420
433
}
421
434
@@ -451,8 +464,7 @@ void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
451
464
if ((tifp ^ tifn ) & _TIF_NOCPUID )
452
465
set_cpuid_faulting (!!(tifn & _TIF_NOCPUID ));
453
466
454
- if ((tifp ^ tifn ) & _TIF_SSBD )
455
- __speculation_ctrl_update (tifn );
467
+ __speculation_ctrl_update (tifp , tifn );
456
468
}
457
469
458
470
/*
0 commit comments