Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
[firefly-linux-kernel-4.4.55.git] / arch / x86 / kvm / x86.c
index 613e13a61cb55dce9de549ae377ed71506154b6d..ac165c2fb8e54a307cb3f70a5e990635f95978b2 100644 (file)
@@ -59,9 +59,8 @@
 #include <asm/msr.h>
 #include <asm/desc.h>
 #include <asm/mce.h>
-#include <asm/i387.h>
-#include <asm/fpu-internal.h> /* Ugh! */
-#include <asm/xcr.h>
+#include <linux/kernel_stat.h>
+#include <asm/fpu/internal.h> /* Ugh! */
 #include <asm/pvclock.h>
 #include <asm/div64.h>
 
@@ -3094,8 +3093,8 @@ static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu,
 
 static void fill_xsave(u8 *dest, struct kvm_vcpu *vcpu)
 {
-       struct xsave_struct *xsave = &vcpu->arch.guest_fpu.state->xsave;
-       u64 xstate_bv = xsave->xsave_hdr.xstate_bv;
+       struct xregs_state *xsave = &vcpu->arch.guest_fpu.state.xsave;
+       u64 xstate_bv = xsave->header.xfeatures;
        u64 valid;
 
        /*
@@ -3130,7 +3129,7 @@ static void fill_xsave(u8 *dest, struct kvm_vcpu *vcpu)
 
 static void load_xsave(struct kvm_vcpu *vcpu, u8 *src)
 {
-       struct xsave_struct *xsave = &vcpu->arch.guest_fpu.state->xsave;
+       struct xregs_state *xsave = &vcpu->arch.guest_fpu.state.xsave;
        u64 xstate_bv = *(u64 *)(src + XSAVE_HDR_OFFSET);
        u64 valid;
 
@@ -3141,9 +3140,9 @@ static void load_xsave(struct kvm_vcpu *vcpu, u8 *src)
        memcpy(xsave, src, XSAVE_HDR_OFFSET);
 
        /* Set XSTATE_BV and possibly XCOMP_BV.  */
-       xsave->xsave_hdr.xstate_bv = xstate_bv;
+       xsave->header.xfeatures = xstate_bv;
        if (cpu_has_xsaves)
-               xsave->xsave_hdr.xcomp_bv = host_xcr0 | XSTATE_COMPACTION_ENABLED;
+               xsave->header.xcomp_bv = host_xcr0 | XSTATE_COMPACTION_ENABLED;
 
        /*
         * Copy each region from the non-compacted offset to the
@@ -3175,8 +3174,8 @@ static void kvm_vcpu_ioctl_x86_get_xsave(struct kvm_vcpu *vcpu,
                fill_xsave((u8 *) guest_xsave->region, vcpu);
        } else {
                memcpy(guest_xsave->region,
-                       &vcpu->arch.guest_fpu.state->fxsave,
-                       sizeof(struct i387_fxsave_struct));
+                       &vcpu->arch.guest_fpu.state.fxsave,
+                       sizeof(struct fxregs_state));
                *(u64 *)&guest_xsave->region[XSAVE_HDR_OFFSET / sizeof(u32)] =
                        XSTATE_FPSSE;
        }
@@ -3200,8 +3199,8 @@ static int kvm_vcpu_ioctl_x86_set_xsave(struct kvm_vcpu *vcpu,
        } else {
                if (xstate_bv & ~XSTATE_FPSSE)
                        return -EINVAL;
-               memcpy(&vcpu->arch.guest_fpu.state->fxsave,
-                       guest_xsave->region, sizeof(struct i387_fxsave_struct));
+               memcpy(&vcpu->arch.guest_fpu.state.fxsave,
+                       guest_xsave->region, sizeof(struct fxregs_state));
        }
        return 0;
 }
@@ -6834,11 +6833,11 @@ static int complete_emulated_mmio(struct kvm_vcpu *vcpu)
 
 int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 {
+       struct fpu *fpu = &current->thread.fpu;
        int r;
        sigset_t sigsaved;
 
-       if (!tsk_used_math(current) && init_fpu(current))
-               return -ENOMEM;
+       fpu__activate_curr(fpu);
 
        if (vcpu->sigset_active)
                sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);
@@ -7208,8 +7207,8 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
 
 int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
 {
-       struct i387_fxsave_struct *fxsave =
-                       &vcpu->arch.guest_fpu.state->fxsave;
+       struct fxregs_state *fxsave =
+                       &vcpu->arch.guest_fpu.state.fxsave;
 
        memcpy(fpu->fpr, fxsave->st_space, 128);
        fpu->fcw = fxsave->cwd;
@@ -7225,8 +7224,8 @@ int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
 
 int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
 {
-       struct i387_fxsave_struct *fxsave =
-                       &vcpu->arch.guest_fpu.state->fxsave;
+       struct fxregs_state *fxsave =
+                       &vcpu->arch.guest_fpu.state.fxsave;
 
        memcpy(fxsave->st_space, fpu->fpr, 128);
        fxsave->cwd = fpu->fcw;
@@ -7240,19 +7239,11 @@ int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
        return 0;
 }
 
-int fx_init(struct kvm_vcpu *vcpu, bool init_event)
+static void fx_init(struct kvm_vcpu *vcpu)
 {
-       int err;
-
-       err = fpu_alloc(&vcpu->arch.guest_fpu);
-       if (err)
-               return err;
-
-       if (!init_event)
-               fpu_finit(&vcpu->arch.guest_fpu);
-
+       fpstate_init(&vcpu->arch.guest_fpu.state);
        if (cpu_has_xsaves)
-               vcpu->arch.guest_fpu.state->xsave.xsave_hdr.xcomp_bv =
+               vcpu->arch.guest_fpu.state.xsave.header.xcomp_bv =
                        host_xcr0 | XSTATE_COMPACTION_ENABLED;
 
        /*
@@ -7261,14 +7252,6 @@ int fx_init(struct kvm_vcpu *vcpu, bool init_event)
        vcpu->arch.xcr0 = XSTATE_FP;
 
        vcpu->arch.cr0 |= X86_CR0_ET;
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(fx_init);
-
-static void fx_free(struct kvm_vcpu *vcpu)
-{
-       fpu_free(&vcpu->arch.guest_fpu);
 }
 
 void kvm_load_guest_fpu(struct kvm_vcpu *vcpu)
@@ -7284,7 +7267,7 @@ void kvm_load_guest_fpu(struct kvm_vcpu *vcpu)
        kvm_put_guest_xcr0(vcpu);
        vcpu->guest_fpu_loaded = 1;
        __kernel_fpu_begin();
-       fpu_restore_checking(&vcpu->arch.guest_fpu);
+       __copy_kernel_to_fpregs(&vcpu->arch.guest_fpu.state);
        trace_kvm_fpu(1);
 }
 
@@ -7298,7 +7281,7 @@ void kvm_put_guest_fpu(struct kvm_vcpu *vcpu)
        }
 
        vcpu->guest_fpu_loaded = 0;
-       fpu_save_init(&vcpu->arch.guest_fpu);
+       copy_fpregs_to_fpstate(&vcpu->arch.guest_fpu);
        __kernel_fpu_end();
        ++vcpu->stat.fpu_reload;
        /*
@@ -7319,7 +7302,6 @@ void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu)
        kvmclock_reset(vcpu);
 
        free_cpumask_var(vcpu->arch.wbinvd_dirty_mask);
-       fx_free(vcpu);
        kvm_x86_ops->vcpu_free(vcpu);
 }
 
@@ -7387,7 +7369,6 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
        kvm_mmu_unload(vcpu);
        vcpu_put(vcpu);
 
-       fx_free(vcpu);
        kvm_x86_ops->vcpu_free(vcpu);
 }
 
@@ -7618,9 +7599,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
                goto fail_free_mce_banks;
        }
 
-       r = fx_init(vcpu, false);
-       if (r)
-               goto fail_free_wbinvd_dirty_mask;
+       fx_init(vcpu);
 
        vcpu->arch.ia32_tsc_adjust_msr = 0x0;
        vcpu->arch.pv_time_enabled = false;
@@ -7636,8 +7615,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
        kvm_pmu_init(vcpu);
 
        return 0;
-fail_free_wbinvd_dirty_mask:
-       free_cpumask_var(vcpu->arch.wbinvd_dirty_mask);
+
 fail_free_mce_banks:
        kfree(vcpu->arch.mce_banks);
 fail_free_lapic: