diff options
| -rw-r--r-- | arch/x86/kernel/cpu/bugs.c | 26 |
1 files changed, 19 insertions, 7 deletions
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index e0b2e3b3301e..8e327bfec513 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c | |||
| @@ -42,7 +42,7 @@ EXPORT_SYMBOL_GPL(x86_spec_ctrl_base); | |||
| 42 | * The vendor and possibly platform specific bits which can be modified in | 42 | * The vendor and possibly platform specific bits which can be modified in |
| 43 | * x86_spec_ctrl_base. | 43 | * x86_spec_ctrl_base. |
| 44 | */ | 44 | */ |
| 45 | static u64 __ro_after_init x86_spec_ctrl_mask = ~SPEC_CTRL_IBRS; | 45 | static u64 __ro_after_init x86_spec_ctrl_mask = SPEC_CTRL_IBRS; |
| 46 | 46 | ||
| 47 | /* | 47 | /* |
| 48 | * AMD specific MSR info for Speculative Store Bypass control. | 48 | * AMD specific MSR info for Speculative Store Bypass control. |
| @@ -68,6 +68,10 @@ void __init check_bugs(void) | |||
| 68 | if (boot_cpu_has(X86_FEATURE_MSR_SPEC_CTRL)) | 68 | if (boot_cpu_has(X86_FEATURE_MSR_SPEC_CTRL)) |
| 69 | rdmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base); | 69 | rdmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base); |
| 70 | 70 | ||
| 71 | /* Allow STIBP in MSR_SPEC_CTRL if supported */ | ||
| 72 | if (boot_cpu_has(X86_FEATURE_STIBP)) | ||
| 73 | x86_spec_ctrl_mask |= SPEC_CTRL_STIBP; | ||
| 74 | |||
| 71 | /* Select the proper spectre mitigation before patching alternatives */ | 75 | /* Select the proper spectre mitigation before patching alternatives */ |
| 72 | spectre_v2_select_mitigation(); | 76 | spectre_v2_select_mitigation(); |
| 73 | 77 | ||
| @@ -136,18 +140,26 @@ static enum spectre_v2_mitigation spectre_v2_enabled __ro_after_init = | |||
| 136 | void | 140 | void |
| 137 | x86_virt_spec_ctrl(u64 guest_spec_ctrl, u64 guest_virt_spec_ctrl, bool setguest) | 141 | x86_virt_spec_ctrl(u64 guest_spec_ctrl, u64 guest_virt_spec_ctrl, bool setguest) |
| 138 | { | 142 | { |
| 143 | u64 msrval, guestval, hostval = x86_spec_ctrl_base; | ||
| 139 | struct thread_info *ti = current_thread_info(); | 144 | struct thread_info *ti = current_thread_info(); |
| 140 | u64 msr, host = x86_spec_ctrl_base; | ||
| 141 | 145 | ||
| 142 | /* Is MSR_SPEC_CTRL implemented ? */ | 146 | /* Is MSR_SPEC_CTRL implemented ? */ |
| 143 | if (static_cpu_has(X86_FEATURE_MSR_SPEC_CTRL)) { | 147 | if (static_cpu_has(X86_FEATURE_MSR_SPEC_CTRL)) { |
| 148 | /* | ||
| 149 | * Restrict guest_spec_ctrl to supported values. Clear the | ||
| 150 | * modifiable bits in the host base value and or the | ||
| 151 | * modifiable bits from the guest value. | ||
| 152 | */ | ||
| 153 | guestval = hostval & ~x86_spec_ctrl_mask; | ||
| 154 | guestval |= guest_spec_ctrl & x86_spec_ctrl_mask; | ||
| 155 | |||
| 144 | /* SSBD controlled in MSR_SPEC_CTRL */ | 156 | /* SSBD controlled in MSR_SPEC_CTRL */ |
| 145 | if (static_cpu_has(X86_FEATURE_SPEC_CTRL_SSBD)) | 157 | if (static_cpu_has(X86_FEATURE_SPEC_CTRL_SSBD)) |
| 146 | host |= ssbd_tif_to_spec_ctrl(ti->flags); | 158 | hostval |= ssbd_tif_to_spec_ctrl(ti->flags); |
| 147 | 159 | ||
| 148 | if (host != guest_spec_ctrl) { | 160 | if (hostval != guestval) { |
| 149 | msr = setguest ? guest_spec_ctrl : host; | 161 | msrval = setguest ? guestval : hostval; |
| 150 | wrmsrl(MSR_IA32_SPEC_CTRL, msr); | 162 | wrmsrl(MSR_IA32_SPEC_CTRL, msrval); |
| 151 | } | 163 | } |
| 152 | } | 164 | } |
| 153 | } | 165 | } |
| @@ -493,7 +505,7 @@ static enum ssb_mitigation __init __ssb_select_mitigation(void) | |||
| 493 | switch (boot_cpu_data.x86_vendor) { | 505 | switch (boot_cpu_data.x86_vendor) { |
| 494 | case X86_VENDOR_INTEL: | 506 | case X86_VENDOR_INTEL: |
| 495 | x86_spec_ctrl_base |= SPEC_CTRL_SSBD; | 507 | x86_spec_ctrl_base |= SPEC_CTRL_SSBD; |
| 496 | x86_spec_ctrl_mask &= ~SPEC_CTRL_SSBD; | 508 | x86_spec_ctrl_mask |= SPEC_CTRL_SSBD; |
| 497 | wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base); | 509 | wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base); |
| 498 | break; | 510 | break; |
| 499 | case X86_VENDOR_AMD: | 511 | case X86_VENDOR_AMD: |
