This is an adopation of what is being posted upstream.
The issue here is that guest kernels such as Windows
needs IBRS to solve their spectre_v2 mitigation.
And since our kernel can do either IBRS or retpoline
we need to be aware of both.
(We are ignoring for right now the situation in which
the microcode is not loaded and we want to emulate IBRS)
In short:
1) If the CPU has microcode, and host uses IBRS we need
to save the MSR during VMEXIT and write our IBRS value.
Also before VMENTER we need to write the guest MSR value.
2) If the host kernel uses retpoline we need to WRMSR the
guest MSR value on VMENTER, but we are optimizing by only
doing it if it a non-zero value.
On VMEXIT we read the guest MSR value.
Orabug:
27477743
CVE: CVE-2017-5715
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Reviewed-by: Pavel Tatashin <pasha.tatashin@oracle.com>
// TSC_ADJUST is emulated
entry->ebx |= F(TSC_ADJUST);
entry->edx &= kvm_cpuid_7_0_edx_x86_features;
+ /* Aka !ibrs_supported and !ibpb_supported */
if ( !boot_cpu_has(X86_FEATURE_SPEC_CTRL) )
entry->edx &= !(1u << KVM_CPUID_BIT_SPEC_CTRL);
if ( !boot_cpu_has(X86_FEATURE_STIPB) )
local_irq_enable();
- if (ibrs_inuse &&
- svm->spec_ctrl != SPEC_CTRL_FEATURE_ENABLE_IBRS)
- wrmsrl(MSR_IA32_SPEC_CTRL, svm->spec_ctrl);
-
+ if (ibrs_supported) {
+ if (ibrs_inuse || svm->spec_ctrl)
+ wrmsrl(MSR_IA32_SPEC_CTRL, svm->spec_ctrl);
+ }
asm volatile (
"push %%" _ASM_BP "; \n\t"
"mov %c[rbx](%[svm]), %%" _ASM_BX " \n\t"
#endif
);
- if (ibrs_inuse) {
+ if (ibrs_supported) {
rdmsrl(MSR_IA32_SPEC_CTRL, svm->spec_ctrl);
- if (svm->spec_ctrl != SPEC_CTRL_FEATURE_ENABLE_IBRS)
+ if (ibrs_inuse)
wrmsrl(MSR_IA32_SPEC_CTRL, SPEC_CTRL_FEATURE_ENABLE_IBRS);
}
vmx->__launched = vmx->loaded_vmcs->launched;
- if (ibrs_inuse)
- wrmsrl(MSR_IA32_SPEC_CTRL, vmx->spec_ctrl);
+ if (ibrs_supported) {
+ if (ibrs_inuse || vmx->spec_ctrl)
+ wrmsrl(MSR_IA32_SPEC_CTRL, vmx->spec_ctrl);
+ }
asm(
/* Store host registers */
#endif
);
- if (ibrs_inuse) {
- rdmsrl(MSR_IA32_SPEC_CTRL, vmx->spec_ctrl);
- wrmsrl(MSR_IA32_SPEC_CTRL, SPEC_CTRL_FEATURE_ENABLE_IBRS);
- }
-
/* Eliminate branch target predictions from guest mode */
vmexit_fill_RSB();
+ if (ibrs_supported) {
+ rdmsrl(MSR_IA32_SPEC_CTRL, vmx->spec_ctrl);
+ if (ibrs_inuse)
+ wrmsrl(MSR_IA32_SPEC_CTRL, SPEC_CTRL_FEATURE_ENABLE_IBRS);
+ }
+
/* MSR_IA32_DEBUGCTLMSR is zeroed on vmexit. Restore it if needed */
if (debugctlmsr)
update_debugctlmsr(debugctlmsr);