]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - arch/x86/kvm/svm.c
x86/bugs, KVM: Support the combination of guest and host IBRS
[mirror_ubuntu-artful-kernel.git] / arch / x86 / kvm / svm.c
index e57aa854f2c1e2eec8c0b010f6cd206f4f2d1c1e..f9e7ddd56ea6e480fe41bd290884fd401c6bd93b 100644 (file)
@@ -519,6 +519,8 @@ struct svm_cpu_data {
        struct kvm_ldttss_desc *tss_desc;
 
        struct page *save_area;
+
+       struct vmcb *current_vmcb;
 };
 
 static DEFINE_PER_CPU(struct svm_cpu_data *, svm_data);
@@ -1686,11 +1688,19 @@ static void svm_free_vcpu(struct kvm_vcpu *vcpu)
        __free_pages(virt_to_page(svm->nested.msrpm), MSRPM_ALLOC_ORDER);
        kvm_vcpu_uninit(vcpu);
        kmem_cache_free(kvm_vcpu_cache, svm);
+
+       /*
+        * The VMCB could be recycled, causing a false negative in svm_vcpu_load;
+        * block speculative execution.
+        */
+       if (ibpb_inuse)
+               wrmsrl(MSR_IA32_PRED_CMD, FEATURE_SET_IBPB);
 }
 
 static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 {
        struct vcpu_svm *svm = to_svm(vcpu);
+       struct svm_cpu_data *sd = per_cpu(svm_data, cpu);
        int i;
 
        if (unlikely(cpu != vcpu->cpu)) {
@@ -1719,6 +1729,12 @@ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
        if (static_cpu_has(X86_FEATURE_RDTSCP))
                wrmsrl(MSR_TSC_AUX, svm->tsc_aux);
 
+       if (sd->current_vmcb != svm->vmcb) {
+               sd->current_vmcb = svm->vmcb;
+               if (ibpb_inuse)
+                       wrmsrl(MSR_IA32_PRED_CMD, FEATURE_SET_IBPB);
+       }
+
        avic_vcpu_load(vcpu, cpu);
 }
 
@@ -4885,8 +4901,8 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
 
        local_irq_enable();
 
-       if (ibrs_inuse && (svm->spec_ctrl != FEATURE_ENABLE_IBRS))
-               wrmsrl(MSR_IA32_SPEC_CTRL, svm->spec_ctrl);
+       /* SMB: Don't care about ibrs_inuse but rely on guest value */
+       x86_spec_ctrl_set_guest(svm->spec_ctrl);
 
        asm volatile (
                "push %%" _ASM_BP "; \n\t"
@@ -4983,11 +4999,7 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
        /* Eliminate branch target predictions from guest mode */
        vmexit_fill_RSB();
 
-       if (ibrs_inuse) {
-               rdmsrl(MSR_IA32_SPEC_CTRL, svm->spec_ctrl);
-               if (svm->spec_ctrl != FEATURE_ENABLE_IBRS)
-                       wrmsrl(MSR_IA32_SPEC_CTRL, FEATURE_ENABLE_IBRS);
-       }
+       x86_spec_ctrl_restore_host(svm->spec_ctrl);
 
 #ifdef CONFIG_X86_64
        wrmsrl(MSR_GS_BASE, svm->host.gs_base);