Skip to content

Commit 50b2d49

Browse files
sean-jcbonzini
authored andcommitted
KVM: x86: Inject #UD on emulated XSETBV if XSAVES isn't enabled
Inject #UD when emulating XSETBV if CR4.OSXSAVE is not set. This also covers the "XSAVE not supported" check, as setting CR4.OSXSAVE=1 #GPs if XSAVE is not supported (and userspace gets to keep the pieces if it forces incoherent vCPU state). Add a comment to kvm_emulate_xsetbv() to call out that the CPU checks CR4.OSXSAVE before checking for intercepts. AMD'S APM implies that #UD has priority (says that intercepts are checked before #GP exceptions), while Intel's SDM says nothing about interception priority. However, testing on hardware shows that both AMD and Intel CPUs prioritize the #UD over interception. Fixes: 02d4160 ("x86: KVM: add xsetbv to the emulator") Cc: [email protected] Cc: Vitaly Kuznetsov <[email protected]> Signed-off-by: Sean Christopherson <[email protected]> Message-Id: <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent a1020a2 commit 50b2d49

File tree

2 files changed

+4
-0
lines changed

2 files changed

+4
-0
lines changed

arch/x86/kvm/emulate.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4132,6 +4132,9 @@ static int em_xsetbv(struct x86_emulate_ctxt *ctxt)
41324132
{
41334133
u32 eax, ecx, edx;
41344134

4135+
if (!(ctxt->ops->get_cr(ctxt, 4) & X86_CR4_OSXSAVE))
4136+
return emulate_ud(ctxt);
4137+
41354138
eax = reg_read(ctxt, VCPU_REGS_RAX);
41364139
edx = reg_read(ctxt, VCPU_REGS_RDX);
41374140
ecx = reg_read(ctxt, VCPU_REGS_RCX);

arch/x86/kvm/x86.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1065,6 +1065,7 @@ static int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr)
10651065

10661066
int kvm_emulate_xsetbv(struct kvm_vcpu *vcpu)
10671067
{
1068+
/* Note, #UD due to CR4.OSXSAVE=0 has priority over the intercept. */
10681069
if (static_call(kvm_x86_get_cpl)(vcpu) != 0 ||
10691070
__kvm_set_xcr(vcpu, kvm_rcx_read(vcpu), kvm_read_edx_eax(vcpu))) {
10701071
kvm_inject_gp(vcpu, 0);

0 commit comments

Comments
 (0)