diff options
| -rw-r--r-- | arch/x86/include/asm/spec-ctrl.h | 33 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/bugs.c | 60 |
2 files changed, 44 insertions, 49 deletions
diff --git a/arch/x86/include/asm/spec-ctrl.h b/arch/x86/include/asm/spec-ctrl.h index 82b6c5a0d61e..9cecbe5e57ee 100644 --- a/arch/x86/include/asm/spec-ctrl.h +++ b/arch/x86/include/asm/spec-ctrl.h | |||
| @@ -13,10 +13,35 @@ | |||
| 13 | * Takes the guest view of SPEC_CTRL MSR as a parameter and also | 13 | * Takes the guest view of SPEC_CTRL MSR as a parameter and also |
| 14 | * the guest's version of VIRT_SPEC_CTRL, if emulated. | 14 | * the guest's version of VIRT_SPEC_CTRL, if emulated. |
| 15 | */ | 15 | */ |
| 16 | extern void x86_spec_ctrl_set_guest(u64 guest_spec_ctrl, | 16 | extern void x86_virt_spec_ctrl(u64 guest_spec_ctrl, u64 guest_virt_spec_ctrl, bool guest); |
| 17 | u64 guest_virt_spec_ctrl); | 17 | |
| 18 | extern void x86_spec_ctrl_restore_host(u64 guest_spec_ctrl, | 18 | /** |
| 19 | u64 guest_virt_spec_ctrl); | 19 | * x86_spec_ctrl_set_guest - Set speculation control registers for the guest |
| 20 | * @guest_spec_ctrl: The guest content of MSR_SPEC_CTRL | ||
| 21 | * @guest_virt_spec_ctrl: The guest controlled bits of MSR_VIRT_SPEC_CTRL | ||
| 22 | * (may get translated to MSR_AMD64_LS_CFG bits) | ||
| 23 | * | ||
| 24 | * Avoids writing to the MSR if the content/bits are the same | ||
| 25 | */ | ||
| 26 | static inline | ||
| 27 | void x86_spec_ctrl_set_guest(u64 guest_spec_ctrl, u64 guest_virt_spec_ctrl) | ||
| 28 | { | ||
| 29 | x86_virt_spec_ctrl(guest_spec_ctrl, guest_virt_spec_ctrl, true); | ||
| 30 | } | ||
| 31 | |||
| 32 | /** | ||
| 33 | * x86_spec_ctrl_restore_host - Restore host speculation control registers | ||
| 34 | * @guest_spec_ctrl: The guest content of MSR_SPEC_CTRL | ||
| 35 | * @guest_virt_spec_ctrl: The guest controlled bits of MSR_VIRT_SPEC_CTRL | ||
| 36 | * (may get translated to MSR_AMD64_LS_CFG bits) | ||
| 37 | * | ||
| 38 | * Avoids writing to the MSR if the content/bits are the same | ||
| 39 | */ | ||
| 40 | static inline | ||
| 41 | void x86_spec_ctrl_restore_host(u64 guest_spec_ctrl, u64 guest_virt_spec_ctrl) | ||
| 42 | { | ||
| 43 | x86_virt_spec_ctrl(guest_spec_ctrl, guest_virt_spec_ctrl, false); | ||
| 44 | } | ||
| 20 | 45 | ||
| 21 | /* AMD specific Speculative Store Bypass MSR data */ | 46 | /* AMD specific Speculative Store Bypass MSR data */ |
| 22 | extern u64 x86_amd_ls_cfg_base; | 47 | extern u64 x86_amd_ls_cfg_base; |
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index f2f0c1b3bf50..feb7d597c265 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c | |||
| @@ -151,55 +151,25 @@ u64 x86_spec_ctrl_get_default(void) | |||
| 151 | } | 151 | } |
| 152 | EXPORT_SYMBOL_GPL(x86_spec_ctrl_get_default); | 152 | EXPORT_SYMBOL_GPL(x86_spec_ctrl_get_default); |
| 153 | 153 | ||
| 154 | /** | 154 | void |
| 155 | * x86_spec_ctrl_set_guest - Set speculation control registers for the guest | 155 | x86_virt_spec_ctrl(u64 guest_spec_ctrl, u64 guest_virt_spec_ctrl, bool setguest) |
| 156 | * @guest_spec_ctrl: The guest content of MSR_SPEC_CTRL | ||
| 157 | * @guest_virt_spec_ctrl: The guest controlled bits of MSR_VIRT_SPEC_CTRL | ||
| 158 | * (may get translated to MSR_AMD64_LS_CFG bits) | ||
| 159 | * | ||
| 160 | * Avoids writing to the MSR if the content/bits are the same | ||
| 161 | */ | ||
| 162 | void x86_spec_ctrl_set_guest(u64 guest_spec_ctrl, u64 guest_virt_spec_ctrl) | ||
| 163 | { | 156 | { |
| 164 | u64 host = x86_spec_ctrl_base; | 157 | struct thread_info *ti = current_thread_info(); |
| 158 | u64 msr, host = x86_spec_ctrl_base; | ||
| 165 | 159 | ||
| 166 | /* Is MSR_SPEC_CTRL implemented ? */ | 160 | /* Is MSR_SPEC_CTRL implemented ? */ |
| 167 | if (!static_cpu_has(X86_FEATURE_MSR_SPEC_CTRL)) | 161 | if (static_cpu_has(X86_FEATURE_MSR_SPEC_CTRL)) { |
| 168 | return; | 162 | /* SSBD controlled in MSR_SPEC_CTRL */ |
| 169 | 163 | if (static_cpu_has(X86_FEATURE_SPEC_CTRL_SSBD)) | |
| 170 | /* SSBD controlled in MSR_SPEC_CTRL */ | 164 | host |= ssbd_tif_to_spec_ctrl(ti->flags); |
| 171 | if (static_cpu_has(X86_FEATURE_SPEC_CTRL_SSBD)) | 165 | |
| 172 | host |= ssbd_tif_to_spec_ctrl(current_thread_info()->flags); | 166 | if (host != guest_spec_ctrl) { |
| 173 | 167 | msr = setguest ? guest_spec_ctrl : host; | |
| 174 | if (host != guest_spec_ctrl) | 168 | wrmsrl(MSR_IA32_SPEC_CTRL, msr); |
| 175 | wrmsrl(MSR_IA32_SPEC_CTRL, guest_spec_ctrl); | 169 | } |
| 176 | } | 170 | } |
| 177 | EXPORT_SYMBOL_GPL(x86_spec_ctrl_set_guest); | ||
| 178 | |||
| 179 | /** | ||
| 180 | * x86_spec_ctrl_restore_host - Restore host speculation control registers | ||
| 181 | * @guest_spec_ctrl: The guest content of MSR_SPEC_CTRL | ||
| 182 | * @guest_virt_spec_ctrl: The guest controlled bits of MSR_VIRT_SPEC_CTRL | ||
| 183 | * (may get translated to MSR_AMD64_LS_CFG bits) | ||
| 184 | * | ||
| 185 | * Avoids writing to the MSR if the content/bits are the same | ||
| 186 | */ | ||
| 187 | void x86_spec_ctrl_restore_host(u64 guest_spec_ctrl, u64 guest_virt_spec_ctrl) | ||
| 188 | { | ||
| 189 | u64 host = x86_spec_ctrl_base; | ||
| 190 | |||
| 191 | /* Is MSR_SPEC_CTRL implemented ? */ | ||
| 192 | if (!static_cpu_has(X86_FEATURE_MSR_SPEC_CTRL)) | ||
| 193 | return; | ||
| 194 | |||
| 195 | /* SSBD controlled in MSR_SPEC_CTRL */ | ||
| 196 | if (static_cpu_has(X86_FEATURE_SPEC_CTRL_SSBD)) | ||
| 197 | host |= ssbd_tif_to_spec_ctrl(current_thread_info()->flags); | ||
| 198 | |||
| 199 | if (host != guest_spec_ctrl) | ||
| 200 | wrmsrl(MSR_IA32_SPEC_CTRL, host); | ||
| 201 | } | 171 | } |
| 202 | EXPORT_SYMBOL_GPL(x86_spec_ctrl_restore_host); | 172 | EXPORT_SYMBOL_GPL(x86_virt_spec_ctrl); |
| 203 | 173 | ||
| 204 | static void x86_amd_ssb_disable(void) | 174 | static void x86_amd_ssb_disable(void) |
| 205 | { | 175 | { |
