]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
KVM: SVM: Implement VIRT_SPEC_CTRL support for SSBD
authorTom Lendacky <thomas.lendacky@amd.com>
Thu, 10 May 2018 20:06:39 +0000 (22:06 +0200)
committerBrian Maly <brian.maly@oracle.com>
Mon, 4 Jun 2018 17:35:48 +0000 (13:35 -0400)
Expose the new virtualized architectural mechanism, VIRT_SSBD, for using
speculative store bypass disable (SSBD) under SVM.  This will allow guests
to use SSBD on hardware that uses non-architectural mechanisms for enabling
SSBD.

[ tglx: Folded the migration fixup from Paolo Bonzini ]

Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Orabug: 28063992
CVE: CVE-2018-3639

(cherry picked from commit bc226f07)
Signed-off-by: Mihai Carabas <mihai.carabas@oracle.com>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
Signed-off-by: Brian Maly <brian.maly@oracle.com>
Conflicts:
arch/x86/include/asm/kvm_host.h
arch/x86/kernel/cpu/common.c
arch/x86/kvm/cpuid.c
arch/x86/kvm/svm.c
arch/x86/kvm/vmx.c
arch/x86/kvm/x86.c
[
We did not have cpu_has_high_real_mode_segbase entry at all.
Also msr_info is not in this patchset, I will take care of it
in Orabug: 28069548 in a future patchset.
]

Signed-off-by: Brian Maly <brian.maly@oracle.com>
arch/x86/include/asm/kvm_host.h
arch/x86/kernel/cpu/amd.c
arch/x86/kvm/cpuid.c
arch/x86/kvm/svm.c
arch/x86/kvm/vmx.c

index 868bcad618324ef54ab1cedfc69519587c5e487f..4b3cc2be726015f40359454f4f8ba3e3c1d7b6fa 100644 (file)
@@ -708,6 +708,7 @@ struct kvm_x86_ops {
        int (*hardware_setup)(void);               /* __init */
        void (*hardware_unsetup)(void);            /* __exit */
        bool (*cpu_has_accelerated_tpr)(void);
+       bool (*has_emulated_msr)(int index);
        void (*cpuid_update)(struct kvm_vcpu *vcpu);
 
        /* Create, but do not attach this VCPU */
index d293c8e4dd3d7b861743facd2d8cc764bda5e711..1890a4b4bb26a328fb03448ea1e2a903c7745bb6 100644 (file)
@@ -766,7 +766,8 @@ static void init_amd(struct cpuinfo_x86 *c)
        /* AMD CPUs don't reset SS attributes on SYSRET */
        set_cpu_bug(c, X86_BUG_SYSRET_SS_ATTRS);
 
-       if (boot_cpu_has(X86_FEATURE_AMD_SSBD)) {
+       if (boot_cpu_has(X86_FEATURE_AMD_SSBD) ||
+           cpu_has(c, X86_FEATURE_VIRT_SSBD)) {
                set_cpu_cap(c, X86_FEATURE_SSBD);
                set_cpu_cap(c, X86_FEATURE_AMD_SSBD);
        }
index fb84a07d6bb3dfbb8a8927e14be024fb88144904..06e302a011e317b5f49dcafd489e0aa27ef49a17 100644 (file)
@@ -66,6 +66,7 @@ u64 kvm_supported_xcr0(void)
 
 /* CPUID[eax=0x80000008].ebx */
 #define KVM_CPUID_BIT_IBPB_SUPPORT     12
+#define KVM_CPUID_BIT_VIRT_SSBD                25
 
 #define KF(x) bit(KVM_CPUID_BIT_##x)
 
@@ -370,7 +371,7 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
 
        /* cpuid 0x80000008.ebx */
        const u32 kvm_cpuid_80000008_ebx_x86_features =
-               KF(IBPB_SUPPORT);
+               KF(IBPB_SUPPORT) | KF(VIRT_SSBD);
 
        /* all calls to cpuid_count() should be made on the same cpu */
        get_cpu();
@@ -600,9 +601,17 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
                        g_phys_as = phys_as;
                entry->eax = g_phys_as | (virt_as << 8);
                entry->edx = 0;
+
+               if (boot_cpu_has(X86_FEATURE_VIRT_SSBD))
+                       entry->ebx |= KF(VIRT_SSBD);
+
                entry->ebx &= kvm_cpuid_80000008_ebx_x86_features;
+
                if ( !boot_cpu_has(X86_FEATURE_IBPB) )
-                       entry->ebx &= !(1u << KVM_CPUID_BIT_IBPB_SUPPORT);
+                       entry->ebx &= ~(1u << KVM_CPUID_BIT_IBPB_SUPPORT);
+
+               if (boot_cpu_has(X86_FEATURE_AMD_SSBD))
+                       entry->ebx |= KF(VIRT_SSBD);
                break;
        }
        case 0x80000019:
index d03593025f2f3e5f4fd3561387bfaa535b80e03b..fd56cdaf6496bab132377408f34a280896909c89 100644 (file)
@@ -3173,6 +3173,9 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data)
        case MSR_IA32_SPEC_CTRL:
                *data = svm->spec_ctrl;
                break;
+       case MSR_AMD64_VIRT_SPEC_CTRL:
+               *data = svm->virt_spec_ctrl;
+               break;
        case MSR_IA32_UCODE_REV:
                *data = 0x01000065;
                break;
@@ -3291,6 +3294,12 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
        case MSR_IA32_SPEC_CTRL:
                svm->spec_ctrl = data;
                break;
+       case MSR_AMD64_VIRT_SPEC_CTRL:
+               if (data & ~SPEC_CTRL_SSBD)
+                       return 1;
+
+               svm->virt_spec_ctrl = data;
+               break;
        default:
                return kvm_set_msr_common(vcpu, msr);
        }
@@ -4149,6 +4158,11 @@ static bool svm_cpu_has_accelerated_tpr(void)
        return false;
 }
 
+static bool svm_has_emulated_msr(int index)
+{
+               return true;
+}
+
 static u64 svm_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio)
 {
        return 0;
@@ -4424,6 +4438,7 @@ static struct kvm_x86_ops svm_x86_ops = {
        .hardware_enable = svm_hardware_enable,
        .hardware_disable = svm_hardware_disable,
        .cpu_has_accelerated_tpr = svm_cpu_has_accelerated_tpr,
+       .has_emulated_msr = svm_has_emulated_msr,
 
        .vcpu_create = svm_create_vcpu,
        .vcpu_free = svm_free_vcpu,
index f2fa1162751e86c284798715b809bdab29076473..e6931417a15714bd7d2c786bc9628e48c93ab286 100644 (file)
@@ -8018,6 +8018,17 @@ static void vmx_handle_external_intr(struct kvm_vcpu *vcpu)
                local_irq_enable();
 }
 
+static bool vmx_has_emulated_msr(int index)
+{
+       switch (index) {
+       case MSR_AMD64_VIRT_SPEC_CTRL:
+               /* This is AMD only.  */
+               return false;
+       default:
+               return true;
+       }
+}
+
 static bool vmx_mpx_supported(void)
 {
        return (vmcs_config.vmexit_ctrl & VM_EXIT_CLEAR_BNDCFGS) &&
@@ -10254,6 +10265,7 @@ static struct kvm_x86_ops vmx_x86_ops = {
        .hardware_enable = hardware_enable,
        .hardware_disable = hardware_disable,
        .cpu_has_accelerated_tpr = report_flexpriority,
+       .has_emulated_msr = vmx_has_emulated_msr,
 
        .vcpu_create = vmx_create_vcpu,
        .vcpu_free = vmx_free_vcpu,