]> Pileus Git - ~andy/linux/blobdiff - arch/x86/kvm/x86.c
Merge branch 'timers/posix-cpu-timers-for-tglx' of
[~andy/linux] / arch / x86 / kvm / x86.c
index 05a8b1a2300df0997d116e753506bf6e6ffa1fe2..e8ba99c341808d6069b0b4f6985b8d71ef243971 100644 (file)
@@ -555,6 +555,25 @@ void kvm_lmsw(struct kvm_vcpu *vcpu, unsigned long msw)
 }
 EXPORT_SYMBOL_GPL(kvm_lmsw);
 
+static void kvm_load_guest_xcr0(struct kvm_vcpu *vcpu)
+{
+       if (kvm_read_cr4_bits(vcpu, X86_CR4_OSXSAVE) &&
+                       !vcpu->guest_xcr0_loaded) {
+               /* kvm_set_xcr() also depends on this */
+               xsetbv(XCR_XFEATURE_ENABLED_MASK, vcpu->arch.xcr0);
+               vcpu->guest_xcr0_loaded = 1;
+       }
+}
+
+static void kvm_put_guest_xcr0(struct kvm_vcpu *vcpu)
+{
+       if (vcpu->guest_xcr0_loaded) {
+               if (vcpu->arch.xcr0 != host_xcr0)
+                       xsetbv(XCR_XFEATURE_ENABLED_MASK, host_xcr0);
+               vcpu->guest_xcr0_loaded = 0;
+       }
+}
+
 int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr)
 {
        u64 xcr0;
@@ -563,22 +582,21 @@ int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr)
        if (index != XCR_XFEATURE_ENABLED_MASK)
                return 1;
        xcr0 = xcr;
-       if (kvm_x86_ops->get_cpl(vcpu) != 0)
-               return 1;
        if (!(xcr0 & XSTATE_FP))
                return 1;
        if ((xcr0 & XSTATE_YMM) && !(xcr0 & XSTATE_SSE))
                return 1;
        if (xcr0 & ~host_xcr0)
                return 1;
+       kvm_put_guest_xcr0(vcpu);
        vcpu->arch.xcr0 = xcr0;
-       vcpu->guest_xcr0_loaded = 0;
        return 0;
 }
 
 int kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr)
 {
-       if (__kvm_set_xcr(vcpu, index, xcr)) {
+       if (kvm_x86_ops->get_cpl(vcpu) != 0 ||
+           __kvm_set_xcr(vcpu, index, xcr)) {
                kvm_inject_gp(vcpu, 0);
                return 1;
        }
@@ -5614,25 +5632,6 @@ static void inject_pending_event(struct kvm_vcpu *vcpu)
        }
 }
 
-static void kvm_load_guest_xcr0(struct kvm_vcpu *vcpu)
-{
-       if (kvm_read_cr4_bits(vcpu, X86_CR4_OSXSAVE) &&
-                       !vcpu->guest_xcr0_loaded) {
-               /* kvm_set_xcr() also depends on this */
-               xsetbv(XCR_XFEATURE_ENABLED_MASK, vcpu->arch.xcr0);
-               vcpu->guest_xcr0_loaded = 1;
-       }
-}
-
-static void kvm_put_guest_xcr0(struct kvm_vcpu *vcpu)
-{
-       if (vcpu->guest_xcr0_loaded) {
-               if (vcpu->arch.xcr0 != host_xcr0)
-                       xsetbv(XCR_XFEATURE_ENABLED_MASK, host_xcr0);
-               vcpu->guest_xcr0_loaded = 0;
-       }
-}
-
 static void process_nmi(struct kvm_vcpu *vcpu)
 {
        unsigned limit = 2;