summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kvm/cpuid.h9
-rw-r--r--arch/x86/kvm/svm.c5
-rw-r--r--arch/x86/kvm/vmx.c6
-rw-r--r--arch/x86/kvm/x86.c14
4 files changed, 14 insertions, 20 deletions
diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h
index 4e9ac93b4f3a..ac15193e5e52 100644
--- a/arch/x86/kvm/cpuid.h
+++ b/arch/x86/kvm/cpuid.h
@@ -104,6 +104,15 @@ static __always_inline bool guest_cpuid_has(struct kvm_vcpu *vcpu, unsigned x86_
104 return *reg & bit(x86_feature); 104 return *reg & bit(x86_feature);
105} 105}
106 106
107static __always_inline void guest_cpuid_clear(struct kvm_vcpu *vcpu, unsigned x86_feature)
108{
109 int *reg;
110
111 reg = guest_cpuid_get_register(vcpu, x86_feature);
112 if (reg)
113 *reg &= ~bit(x86_feature);
114}
115
107static inline bool guest_cpuid_is_amd(struct kvm_vcpu *vcpu) 116static inline bool guest_cpuid_is_amd(struct kvm_vcpu *vcpu)
108{ 117{
109 struct kvm_cpuid_entry2 *best; 118 struct kvm_cpuid_entry2 *best;
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index b8196aecbdcc..2432bb952a30 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -5075,7 +5075,6 @@ static u64 svm_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio)
5075static void svm_cpuid_update(struct kvm_vcpu *vcpu) 5075static void svm_cpuid_update(struct kvm_vcpu *vcpu)
5076{ 5076{
5077 struct vcpu_svm *svm = to_svm(vcpu); 5077 struct vcpu_svm *svm = to_svm(vcpu);
5078 struct kvm_cpuid_entry2 *entry;
5079 5078
5080 /* Update nrips enabled cache */ 5079 /* Update nrips enabled cache */
5081 svm->nrips_enabled = !!guest_cpuid_has(&svm->vcpu, X86_FEATURE_NRIPS); 5080 svm->nrips_enabled = !!guest_cpuid_has(&svm->vcpu, X86_FEATURE_NRIPS);
@@ -5083,9 +5082,7 @@ static void svm_cpuid_update(struct kvm_vcpu *vcpu)
5083 if (!kvm_vcpu_apicv_active(vcpu)) 5082 if (!kvm_vcpu_apicv_active(vcpu))
5084 return; 5083 return;
5085 5084
5086 entry = kvm_find_cpuid_entry(vcpu, 1, 0); 5085 guest_cpuid_clear(vcpu, X86_FEATURE_X2APIC);
5087 if (entry)
5088 entry->ecx &= ~bit(X86_FEATURE_X2APIC);
5089} 5086}
5090 5087
5091static void svm_set_supported_cpuid(u32 func, struct kvm_cpuid_entry2 *entry) 5088static void svm_set_supported_cpuid(u32 func, struct kvm_cpuid_entry2 *entry)
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 96d1f8708cef..2c0f5287fb78 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -9636,15 +9636,13 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu)
9636 9636
9637 if (vmx_invpcid_supported()) { 9637 if (vmx_invpcid_supported()) {
9638 /* Exposing INVPCID only when PCID is exposed */ 9638 /* Exposing INVPCID only when PCID is exposed */
9639 struct kvm_cpuid_entry2 *best = kvm_find_cpuid_entry(vcpu, 0x7, 0);
9640 bool invpcid_enabled = 9639 bool invpcid_enabled =
9641 best && best->ebx & bit(X86_FEATURE_INVPCID) && 9640 guest_cpuid_has(vcpu, X86_FEATURE_INVPCID) &&
9642 guest_cpuid_has(vcpu, X86_FEATURE_PCID); 9641 guest_cpuid_has(vcpu, X86_FEATURE_PCID);
9643 9642
9644 if (!invpcid_enabled) { 9643 if (!invpcid_enabled) {
9645 secondary_exec_ctl &= ~SECONDARY_EXEC_ENABLE_INVPCID; 9644 secondary_exec_ctl &= ~SECONDARY_EXEC_ENABLE_INVPCID;
9646 if (best) 9645 guest_cpuid_clear(vcpu, X86_FEATURE_INVPCID);
9647 best->ebx &= ~bit(X86_FEATURE_INVPCID);
9648 } 9646 }
9649 9647
9650 if (nested) { 9648 if (nested) {
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index ee4e251c82fc..33fd6b6419ef 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1022,21 +1022,11 @@ bool kvm_valid_efer(struct kvm_vcpu *vcpu, u64 efer)
1022 if (efer & efer_reserved_bits) 1022 if (efer & efer_reserved_bits)
1023 return false; 1023 return false;
1024 1024
1025 if (efer & EFER_FFXSR) { 1025 if (efer & EFER_FFXSR && !guest_cpuid_has(vcpu, X86_FEATURE_FXSR_OPT))
1026 struct kvm_cpuid_entry2 *feat;
1027
1028 feat = kvm_find_cpuid_entry(vcpu, 0x80000001, 0);
1029 if (!feat || !(feat->edx & bit(X86_FEATURE_FXSR_OPT)))
1030 return false; 1026 return false;
1031 }
1032 1027
1033 if (efer & EFER_SVME) { 1028 if (efer & EFER_SVME && !guest_cpuid_has(vcpu, X86_FEATURE_SVM))
1034 struct kvm_cpuid_entry2 *feat;
1035
1036 feat = kvm_find_cpuid_entry(vcpu, 0x80000001, 0);
1037 if (!feat || !(feat->ecx & bit(X86_FEATURE_SVM)))
1038 return false; 1029 return false;
1039 }
1040 1030
1041 return true; 1031 return true;
1042} 1032}