From: Paolo Bonzini Date: Thu, 30 Nov 2017 14:00:13 +0000 (+0100) Subject: kvm: vmx: add MSR_IA32_SPEC_CTRL and MSR_IA32_PRED_CMD X-Git-Tag: v4.1.12-124.31.3~1394 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=909a5f41e53afc26ebb48a87279a8aee745fbab0;p=users%2Fjedix%2Flinux-maple.git kvm: vmx: add MSR_IA32_SPEC_CTRL and MSR_IA32_PRED_CMD [RHEL7.5 PATCH 08/35] kvm: vmx: add MSR_IA32_SPEC_CTRL and MSR_IA32_PRED_CMD Allow load/store of MSR_IA32_SPEC_CTRL, restore guest IBRS on VM entry and set it to 1 on VM exit. Orabug: 27344012 CVE: CVE-2017-5715 Signed-off-by: Paolo Bonzini Signed-off-by: Andrea Arcangeli Signed-off-by: Konrad Rzeszutek Wilk Reviewed-by: John Haxby Signed-off-by: Kirtikar Kashyap --- diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 9f21e6b16a38..a245dce60bfa 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -47,6 +47,7 @@ #include #include #include +#include #include "trace.h" @@ -485,6 +486,8 @@ struct vcpu_vmx { u64 msr_host_kernel_gs_base; u64 msr_guest_kernel_gs_base; #endif + u64 spec_ctrl; + u32 vm_entry_controls_shadow; u32 vm_exit_controls_shadow; /* @@ -2664,6 +2667,9 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata) case MSR_IA32_TSC: data = guest_read_tsc(); break; + case MSR_IA32_SPEC_CTRL: + data = to_vmx(vcpu)->spec_ctrl; + break; case MSR_IA32_SYSENTER_CS: data = vmcs_read32(GUEST_SYSENTER_CS); break; @@ -2759,6 +2765,9 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) case MSR_IA32_TSC: kvm_write_tsc(vcpu, msr_info); break; + case MSR_IA32_SPEC_CTRL: + to_vmx(vcpu)->spec_ctrl = data; + break; case MSR_IA32_CR_PAT: if (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_PAT) { if (!kvm_mtrr_valid(vcpu, MSR_IA32_CR_PAT, data)) @@ -6149,6 +6158,8 @@ static __init int hardware_setup(void) vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_CS, false); vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_ESP, false); vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_EIP, false); + vmx_disable_intercept_for_msr(MSR_IA32_SPEC_CTRL, false); + vmx_disable_intercept_for_msr(MSR_IA32_PRED_CMD, false); vmx_disable_intercept_for_msr(MSR_IA32_BNDCFGS, true); memcpy(vmx_msr_bitmap_legacy_x2apic, @@ -8170,6 +8181,10 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) vmx_set_interrupt_shadow(vcpu, 0); + if (static_cpu_has(X86_FEATURE_SPEC_CTRL) && + vmx->spec_ctrl != FEATURE_ENABLE_IBRS) + wrmsrl(MSR_IA32_SPEC_CTRL, vmx->spec_ctrl); + atomic_switch_perf_msrs(vmx); debugctlmsr = get_debugctlmsr(); @@ -8296,6 +8311,11 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) #endif ); + if (static_cpu_has(X86_FEATURE_SPEC_CTRL)) { + rdmsrl(MSR_IA32_SPEC_CTRL, vmx->spec_ctrl); + if (vmx->spec_ctrl) + wrmsrl(MSR_IA32_SPEC_CTRL, FEATURE_ENABLE_IBRS); + } stuff_RSB(); /* MSR_IA32_DEBUGCTLMSR is zeroed on vmexit. Restore it if needed */