]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
kvm: vmx: add MSR_IA32_SPEC_CTRL and MSR_IA32_PRED_CMD
authorPaolo Bonzini <pbonzini@redhat.com>
Thu, 30 Nov 2017 14:00:13 +0000 (15:00 +0100)
committerKirtikar Kashyap <kirtikar.kashyap@oracle.com>
Fri, 12 Jan 2018 18:19:58 +0000 (10:19 -0800)
[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 <pbonzini@redhat.com>
Signed-off-by: Andrea Arcangeli <aarcange@redhat.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Reviewed-by: John Haxby <john.haxby@oracle.com>
Signed-off-by: Kirtikar Kashyap <kirtikar.kashyap@oracle.com>
arch/x86/kvm/vmx.c

index 9f21e6b16a389a9fde046dddeee1d6d39685f3c5..a245dce60bfada89dd4e4ed17dcf9025919461ed 100644 (file)
@@ -47,6 +47,7 @@
 #include <asm/debugreg.h>
 #include <asm/kexec.h>
 #include <asm/apic.h>
+#include <asm/microcode.h>
 
 #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 */