Add the function guest_cpuid_set() to allow a bit in the guest cpuid to be set. This is complementary to the guest_cpuid_clear() function. Also, set the XSAVES bit in the guest cpuid if the host has the same bit set and guest has XSAVE bit set. This is to ensure that XSAVES will be enumerated in the guest CPUID if XSAVES can be used in the guest. Reviewed-by: Jim Mattson <jmattson@xxxxxxxxxx> Signed-off-by: Aaron Lewis <aaronlewis@xxxxxxxxxx> --- arch/x86/kvm/cpuid.h | 9 +++++++++ arch/x86/kvm/svm.c | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h index d78a61408243..420ceea02fd1 100644 --- a/arch/x86/kvm/cpuid.h +++ b/arch/x86/kvm/cpuid.h @@ -113,6 +113,15 @@ static __always_inline void guest_cpuid_clear(struct kvm_vcpu *vcpu, unsigned x8 *reg &= ~bit(x86_feature); } +static __always_inline void guest_cpuid_set(struct kvm_vcpu *vcpu, unsigned x86_feature) +{ + int *reg; + + reg = guest_cpuid_get_register(vcpu, x86_feature); + if (reg) + *reg |= ~bit(x86_feature); +} + static inline bool guest_cpuid_is_amd(struct kvm_vcpu *vcpu) { struct kvm_cpuid_entry2 *best; diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 65223827c675..2522a467bbc0 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -5887,6 +5887,10 @@ static void svm_cpuid_update(struct kvm_vcpu *vcpu) { struct vcpu_svm *svm = to_svm(vcpu); + if (guest_cpuid_has(vcpu, X86_FEATURE_XSAVE) && + boot_cpu_has(X86_FEATURE_XSAVES)) + guest_cpuid_set(vcpu, X86_FEATURE_XSAVES); + /* Update nrips enabled cache */ svm->nrips_enabled = !!guest_cpuid_has(&svm->vcpu, X86_FEATURE_NRIPS); -- 2.23.0.581.g78d2f28ef7-goog