]> git.itanic.dy.fi Git - linux-stable/commitdiff
KVM: x86: reinstate vendor-agnostic check on SPEC_CTRL cpuid bits
authorPaolo Bonzini <pbonzini@redhat.com>
Thu, 3 Dec 2020 14:40:15 +0000 (09:40 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 6 Jan 2021 13:44:59 +0000 (14:44 +0100)
[ Upstream commit 39485ed95d6b83b62fa75c06c2c4d33992e0d971 ]

Until commit e7c587da1252 ("x86/speculation: Use synthetic bits for
IBRS/IBPB/STIBP"), KVM was testing both Intel and AMD CPUID bits before
allowing the guest to write MSR_IA32_SPEC_CTRL and MSR_IA32_PRED_CMD.
Testing only Intel bits on VMX processors, or only AMD bits on SVM
processors, fails if the guests are created with the "opposite" vendor
as the host.

While at it, also tweak the host CPU check to use the vendor-agnostic
feature bit X86_FEATURE_IBPB, since we only care about the availability
of the MSR on the host here and not about specific CPUID bits.

Fixes: e7c587da1252 ("x86/speculation: Use synthetic bits for IBRS/IBPB/STIBP")
Cc: stable@vger.kernel.org
Reported-by: Denis V. Lunev <den@openvz.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
arch/x86/kvm/cpuid.h
arch/x86/kvm/svm.c
arch/x86/kvm/vmx.c

index d78a61408243f20e8369bc5acaa3562d7c34d0aa..7dec43b2c4205680925bca103541287e78dfb450 100644 (file)
@@ -154,6 +154,20 @@ static inline int guest_cpuid_stepping(struct kvm_vcpu *vcpu)
        return x86_stepping(best->eax);
 }
 
+static inline bool guest_has_spec_ctrl_msr(struct kvm_vcpu *vcpu)
+{
+       return (guest_cpuid_has(vcpu, X86_FEATURE_SPEC_CTRL) ||
+               guest_cpuid_has(vcpu, X86_FEATURE_AMD_STIBP) ||
+               guest_cpuid_has(vcpu, X86_FEATURE_AMD_IBRS) ||
+               guest_cpuid_has(vcpu, X86_FEATURE_AMD_SSBD));
+}
+
+static inline bool guest_has_pred_cmd_msr(struct kvm_vcpu *vcpu)
+{
+       return (guest_cpuid_has(vcpu, X86_FEATURE_SPEC_CTRL) ||
+               guest_cpuid_has(vcpu, X86_FEATURE_AMD_IBPB));
+}
+
 static inline bool supports_cpuid_fault(struct kvm_vcpu *vcpu)
 {
        return vcpu->arch.msr_platform_info & MSR_PLATFORM_INFO_CPUID_FAULT;
index f513110983d4c1886f12335a6df0ec81e6a65358..d2dc734f5bd0d820953faa274736a4becd4c9999 100644 (file)
@@ -4209,10 +4209,7 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
                break;
        case MSR_IA32_SPEC_CTRL:
                if (!msr_info->host_initiated &&
-                   !guest_cpuid_has(vcpu, X86_FEATURE_SPEC_CTRL) &&
-                   !guest_cpuid_has(vcpu, X86_FEATURE_AMD_STIBP) &&
-                   !guest_cpuid_has(vcpu, X86_FEATURE_AMD_IBRS) &&
-                   !guest_cpuid_has(vcpu, X86_FEATURE_AMD_SSBD))
+                   !guest_has_spec_ctrl_msr(vcpu))
                        return 1;
 
                msr_info->data = svm->spec_ctrl;
@@ -4314,10 +4311,7 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
                break;
        case MSR_IA32_SPEC_CTRL:
                if (!msr->host_initiated &&
-                   !guest_cpuid_has(vcpu, X86_FEATURE_SPEC_CTRL) &&
-                   !guest_cpuid_has(vcpu, X86_FEATURE_AMD_STIBP) &&
-                   !guest_cpuid_has(vcpu, X86_FEATURE_AMD_IBRS) &&
-                   !guest_cpuid_has(vcpu, X86_FEATURE_AMD_SSBD))
+                   !guest_has_spec_ctrl_msr(vcpu))
                        return 1;
 
                /* The STIBP bit doesn't fault even if it's not advertised */
@@ -4344,12 +4338,11 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
                break;
        case MSR_IA32_PRED_CMD:
                if (!msr->host_initiated &&
-                   !guest_cpuid_has(vcpu, X86_FEATURE_AMD_IBPB))
+                   !guest_has_pred_cmd_msr(vcpu))
                        return 1;
 
                if (data & ~PRED_CMD_IBPB)
                        return 1;
-
                if (!data)
                        break;
 
index d6bcbce6c15cbb143694f77b64c538c2b899171f..77b9ed5223f37f5774215aea835b86020e8a2e6f 100644 (file)
@@ -4066,7 +4066,7 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
                return kvm_get_msr_common(vcpu, msr_info);
        case MSR_IA32_SPEC_CTRL:
                if (!msr_info->host_initiated &&
-                   !guest_cpuid_has(vcpu, X86_FEATURE_SPEC_CTRL))
+                   !guest_has_spec_ctrl_msr(vcpu))
                        return 1;
 
                msr_info->data = to_vmx(vcpu)->spec_ctrl;
@@ -4180,7 +4180,7 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
                break;
        case MSR_IA32_SPEC_CTRL:
                if (!msr_info->host_initiated &&
-                   !guest_cpuid_has(vcpu, X86_FEATURE_SPEC_CTRL))
+                   !guest_has_spec_ctrl_msr(vcpu))
                        return 1;
 
                /* The STIBP bit doesn't fault even if it's not advertised */
@@ -4210,7 +4210,7 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
                break;
        case MSR_IA32_PRED_CMD:
                if (!msr_info->host_initiated &&
-                   !guest_cpuid_has(vcpu, X86_FEATURE_SPEC_CTRL))
+                   !guest_has_pred_cmd_msr(vcpu))
                        return 1;
 
                if (data & ~PRED_CMD_IBPB)