aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2013-10-17 10:50:46 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2013-10-31 06:30:46 -0400
commit46c34cb059d519601fb567b55cf45c300fea2928 (patch)
tree7714d9f5073951ce554a417a0fb246ed5d424c39 /arch/x86
parente0f0bbc527f6e9c0261f1d16b2a0b47612b7f235 (diff)
KVM: x86: fix KVM_SET_XCRS for CPUs that do not support XSAVE
The KVM_SET_XCRS ioctl must accept anything that KVM_GET_XCRS could return. XCR0's bit 0 is always 1 in real processors with XSAVE, and KVM_GET_XCRS will always leave bit 0 set even if the emulated processor does not have XSAVE. So, KVM_SET_XCRS must ignore that bit when checking for attempts to enable unsupported save states. Reviewed-by: Gleb Natapov <gleb@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/kvm/x86.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index ec35d09937da..296154956399 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -577,6 +577,7 @@ static void kvm_put_guest_xcr0(struct kvm_vcpu *vcpu)
577int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr) 577int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr)
578{ 578{
579 u64 xcr0; 579 u64 xcr0;
580 u64 valid_bits;
580 581
581 /* Only support XCR_XFEATURE_ENABLED_MASK(xcr0) now */ 582 /* Only support XCR_XFEATURE_ENABLED_MASK(xcr0) now */
582 if (index != XCR_XFEATURE_ENABLED_MASK) 583 if (index != XCR_XFEATURE_ENABLED_MASK)
@@ -586,8 +587,16 @@ int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr)
586 return 1; 587 return 1;
587 if ((xcr0 & XSTATE_YMM) && !(xcr0 & XSTATE_SSE)) 588 if ((xcr0 & XSTATE_YMM) && !(xcr0 & XSTATE_SSE))
588 return 1; 589 return 1;
589 if (xcr0 & ~vcpu->arch.guest_supported_xcr0) 590
591 /*
592 * Do not allow the guest to set bits that we do not support
593 * saving. However, xcr0 bit 0 is always set, even if the
594 * emulated CPU does not support XSAVE (see fx_init).
595 */
596 valid_bits = vcpu->arch.guest_supported_xcr0 | XSTATE_FP;
597 if (xcr0 & ~valid_bits)
590 return 1; 598 return 1;
599
591 kvm_put_guest_xcr0(vcpu); 600 kvm_put_guest_xcr0(vcpu);
592 vcpu->arch.xcr0 = xcr0; 601 vcpu->arch.xcr0 = xcr0;
593 return 0; 602 return 0;