On 1/17/22 08:24, Like Xu wrote:
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 76b4803dd3bd..7d8622e592bb 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1024,7 +1024,11 @@ static int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr)
int kvm_emulate_xsetbv(struct kvm_vcpu *vcpu)
{
- if (static_call(kvm_x86_get_cpl)(vcpu) != 0 ||
+ if (!guest_cpuid_has(vcpu, X86_FEATURE_XSAVE) ||
+ !kvm_read_cr4_bits(vcpu, X86_CR4_OSXSAVE))
+ return kvm_handle_invalid_op(vcpu);
There's no need to check XSAVE, because it XSAVE=0 will prevent setting
CR4.OSXSAVE.
Likewise, CPL and SS.DPL are also defined in real mode so there's no
need to check is_protmode. The Intel manuals sometimes still act as the
descriptor caches don't exist, even though VMX effectively made them
part of the architecture.
Also, the "Fixes" tag is not really correct as the behavior was the same
before. Rather, it fixes commit 02d4160fbd76 ("x86: KVM: add xsetbv to
the emulator", 2019-08-22). Checking OSXSAVE is a bug in the emulator
path, even though it's not needed in the XSETBV vmexit case.
Thanks,
Paolo
+ if ((is_protmode(vcpu) && static_call(kvm_x86_get_cpl)(vcpu) != 0) ||
__kvm_set_xcr(vcpu, kvm_rcx_read(vcpu), kvm_read_edx_eax(vcpu))) {
kvm_inject_gp(vcpu, 0);
return 1;