Re: [PATCH] KVM: x86: Fix the #GP(0) and #UD conditions for XSETBV emulation

From: Paolo Bonzini
Date: Mon Jan 17 2022 - 03:31:55 EST


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;