[patch 2/5] qemu-kvm: use upstream fpu/xsave/xcrs save/restore code

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Signed-off-by: Marcelo Tosatti <mtosatti@xxxxxxxxxx>

Index: qemu-kvm/qemu-kvm.c
===================================================================
--- qemu-kvm.orig/qemu-kvm.c
+++ qemu-kvm/qemu-kvm.c
@@ -472,16 +472,6 @@ int kvm_set_regs(CPUState *env, struct k
     return kvm_vcpu_ioctl(env, KVM_SET_REGS, regs);
 }
 
-int kvm_get_fpu(CPUState *env, struct kvm_fpu *fpu)
-{
-    return kvm_vcpu_ioctl(env, KVM_GET_FPU, fpu);
-}
-
-int kvm_set_fpu(CPUState *env, struct kvm_fpu *fpu)
-{
-    return kvm_vcpu_ioctl(env, KVM_SET_FPU, fpu);
-}
-
 int kvm_get_sregs(CPUState *env, struct kvm_sregs *sregs)
 {
     return kvm_vcpu_ioctl(env, KVM_GET_SREGS, sregs);
@@ -1696,6 +1686,16 @@ static int kvm_create_context(void)
     kvm_state->debugregs = kvm_check_extension(kvm_state, KVM_CAP_DEBUGREGS);
 #endif
 
+    kvm_state->xsave = 0;
+#ifdef KVM_CAP_XSAVE
+    kvm_state->xsave = kvm_check_extension(kvm_state, KVM_CAP_XSAVE);
+#endif
+
+    kvm_state->xcrs = 0;
+#ifdef KVM_CAP_XCRS
+    kvm_state->xcrs = kvm_check_extension(kvm_state, KVM_CAP_XCRS);
+#endif
+
     kvm_init_ap();
     if (kvm_irqchip) {
         if (!qemu_kvm_has_gsi_routing()) {
Index: qemu-kvm/qemu-kvm-x86.c
===================================================================
--- qemu-kvm.orig/qemu-kvm-x86.c
+++ qemu-kvm/qemu-kvm-x86.c
@@ -769,7 +769,6 @@ static void get_seg(SegmentCache *lhs, c
 void kvm_arch_load_regs(CPUState *env, int level)
 {
     struct kvm_regs regs;
-    struct kvm_fpu fpu;
     struct kvm_sregs sregs;
     struct kvm_msr_entry msrs[100];
     int rc, n, i;
@@ -800,58 +799,8 @@ void kvm_arch_load_regs(CPUState *env, i
 
     kvm_set_regs(env, &regs);
 
-#ifdef KVM_CAP_XSAVE
-    if (kvm_check_extension(kvm_state, KVM_CAP_XSAVE)) {
-        struct kvm_xsave* xsave;
-
-        uint16_t cwd, swd, twd, fop;
-
-        xsave = qemu_memalign(4096, sizeof(struct kvm_xsave));
-        memset(xsave, 0, sizeof(struct kvm_xsave));
-        cwd = swd = twd = fop = 0;
-        swd = env->fpus & ~(7 << 11);
-        swd |= (env->fpstt & 7) << 11;
-        cwd = env->fpuc;
-        for (i = 0; i < 8; ++i) {
-            twd |= (!env->fptags[i]) << i;
-        }
-        xsave->region[0] = (uint32_t)(swd << 16) + cwd;
-        xsave->region[1] = (uint32_t)(fop << 16) + twd;
-        memcpy(&xsave->region[XSAVE_ST_SPACE], env->fpregs,
-               sizeof env->fpregs);
-        memcpy(&xsave->region[XSAVE_XMM_SPACE], env->xmm_regs,
-               sizeof env->xmm_regs);
-        xsave->region[XSAVE_MXCSR] = env->mxcsr;
-        *(uint64_t *)&xsave->region[XSAVE_XSTATE_BV] = env->xstate_bv;
-        memcpy(&xsave->region[XSAVE_YMMH_SPACE], env->ymmh_regs,
-               sizeof env->ymmh_regs);
-        kvm_vcpu_ioctl(env, KVM_SET_XSAVE, xsave);
-        if (kvm_check_extension(kvm_state, KVM_CAP_XCRS)) {
-            struct kvm_xcrs xcrs;
-
-            xcrs.nr_xcrs = 1;
-            xcrs.flags = 0;
-            xcrs.xcrs[0].xcr = 0;
-            xcrs.xcrs[0].value = env->xcr0;
-            kvm_vcpu_ioctl(env, KVM_SET_XCRS, &xcrs);
-        }
-        qemu_free(xsave);
-    } else {
-#endif
-        memset(&fpu, 0, sizeof fpu);
-        fpu.fsw = env->fpus & ~(7 << 11);
-        fpu.fsw |= (env->fpstt & 7) << 11;
-        fpu.fcw = env->fpuc;
-        for (i = 0; i < 8; ++i) {
-            fpu.ftwx |= (!env->fptags[i]) << i;
-        }
-        memcpy(fpu.fpr, env->fpregs, sizeof env->fpregs);
-        memcpy(fpu.xmm, env->xmm_regs, sizeof env->xmm_regs);
-        fpu.mxcsr = env->mxcsr;
-        kvm_set_fpu(env, &fpu);
-#ifdef KVM_CAP_XSAVE
-    }
-#endif
+    kvm_put_xsave(env);
+    kvm_put_xcrs(env);
 
     memset(sregs.interrupt_bitmap, 0, sizeof(sregs.interrupt_bitmap));
     if (env->interrupt_injected >= 0) {
@@ -974,7 +923,6 @@ void kvm_arch_load_regs(CPUState *env, i
 void kvm_arch_save_regs(CPUState *env)
 {
     struct kvm_regs regs;
-    struct kvm_fpu fpu;
     struct kvm_sregs sregs;
     struct kvm_msr_entry msrs[100];
     uint32_t hflags;
@@ -1006,54 +954,8 @@ void kvm_arch_save_regs(CPUState *env)
     env->eflags = regs.rflags;
     env->eip = regs.rip;
 
-#ifdef KVM_CAP_XSAVE
-    if (kvm_check_extension(kvm_state, KVM_CAP_XSAVE)) {
-        struct kvm_xsave* xsave;
-        uint16_t cwd, swd, twd, fop;
-        xsave = qemu_memalign(4096, sizeof(struct kvm_xsave));
-        kvm_vcpu_ioctl(env, KVM_GET_XSAVE, xsave);
-        cwd = (uint16_t)xsave->region[0];
-        swd = (uint16_t)(xsave->region[0] >> 16);
-        twd = (uint16_t)xsave->region[1];
-        fop = (uint16_t)(xsave->region[1] >> 16);
-        env->fpstt = (swd >> 11) & 7;
-        env->fpus = swd;
-        env->fpuc = cwd;
-        for (i = 0; i < 8; ++i) {
-            env->fptags[i] = !((twd >> i) & 1);
-        }
-        env->mxcsr = xsave->region[XSAVE_MXCSR];
-        memcpy(env->fpregs, &xsave->region[XSAVE_ST_SPACE],
-                sizeof env->fpregs);
-        memcpy(env->xmm_regs, &xsave->region[XSAVE_XMM_SPACE],
-                sizeof env->xmm_regs);
-        env->xstate_bv = *(uint64_t *)&xsave->region[XSAVE_XSTATE_BV];
-        memcpy(env->ymmh_regs, &xsave->region[XSAVE_YMMH_SPACE],
-                sizeof env->ymmh_regs);
-        if (kvm_check_extension(kvm_state, KVM_CAP_XCRS)) {
-            struct kvm_xcrs xcrs;
-
-            kvm_vcpu_ioctl(env, KVM_GET_XCRS, &xcrs);
-            if (xcrs.xcrs[0].xcr == 0) {
-                env->xcr0 = xcrs.xcrs[0].value;
-            }
-        }
-        qemu_free(xsave);
-    } else {
-#endif
-        kvm_get_fpu(env, &fpu);
-        env->fpstt = (fpu.fsw >> 11) & 7;
-        env->fpus = fpu.fsw;
-        env->fpuc = fpu.fcw;
-        for (i = 0; i < 8; ++i) {
-            env->fptags[i] = !((fpu.ftwx >> i) & 1);
-        }
-        memcpy(env->fpregs, fpu.fpr, sizeof env->fpregs);
-        memcpy(env->xmm_regs, fpu.xmm, sizeof env->xmm_regs);
-        env->mxcsr = fpu.mxcsr;
-#ifdef KVM_CAP_XSAVE
-    }
-#endif
+    kvm_get_xsave(env);
+    kvm_get_xcrs(env);
 
     kvm_get_sregs(env, &sregs);
 
Index: qemu-kvm/qemu-kvm.h
===================================================================
--- qemu-kvm.orig/qemu-kvm.h
+++ qemu-kvm/qemu-kvm.h
@@ -206,36 +206,6 @@ int kvm_get_regs(CPUState *env, struct k
  * \return 0 on success
  */
 int kvm_set_regs(CPUState *env, struct kvm_regs *regs);
-/*!
- * \brief Read VCPU fpu registers
- *
- * This gets the FPU registers from the VCPU and outputs them
- * into a kvm_fpu structure
- *
- * \note This function returns a \b copy of the VCPUs registers.\n
- * If you wish to modify the VCPU FPU registers, you should call kvm_set_fpu()
- *
- * \param kvm Pointer to the current kvm_context
- * \param vcpu Which virtual CPU should get dumped
- * \param fpu Pointer to a kvm_fpu which will be populated with the VCPUs
- * fpu registers values
- * \return 0 on success
- */
-int kvm_get_fpu(CPUState *env, struct kvm_fpu *fpu);
-
-/*!
- * \brief Write VCPU fpu registers
- *
- * This sets the FPU registers on the VCPU from a kvm_fpu structure
- *
- * \note When this function returns, the fpu pointer and the data it points to
- * can be discarded
- * \param kvm Pointer to the current kvm_context
- * \param vcpu Which virtual CPU should get dumped
- * \param fpu Pointer to a kvm_fpu which holds the new vcpu fpu state
- * \return 0 on success
- */
-int kvm_set_fpu(CPUState *env, struct kvm_fpu *fpu);
 
 /*!
  * \brief Read VCPU system registers
@@ -847,6 +817,7 @@ struct KVMState {
 #endif
     int irqchip_in_kernel;
     int pit_in_kernel;
+    int xsave, xcrs;
 
     struct kvm_context kvm_context;
 };
Index: qemu-kvm/target-i386/kvm.c
===================================================================
--- qemu-kvm.orig/target-i386/kvm.c
+++ qemu-kvm/target-i386/kvm.c
@@ -675,6 +675,8 @@ static int kvm_getput_regs(CPUState *env
     return ret;
 }
 
+#endif
+
 static int kvm_put_fpu(CPUState *env)
 {
     struct kvm_fpu fpu;
@@ -757,6 +759,8 @@ static int kvm_put_xcrs(CPUState *env)
 #endif
 }
 
+#ifdef OBSOLETE_KVM_IMPL
+
 static int kvm_put_sregs(CPUState *env)
 {
     struct kvm_sregs sregs;
@@ -879,6 +883,7 @@ static int kvm_put_msrs(CPUState *env, i
 
 }
 
+#endif
 
 static int kvm_get_fpu(CPUState *env)
 {
@@ -967,6 +972,8 @@ static int kvm_get_xcrs(CPUState *env)
 #endif
 }
 
+#ifdef OBSOLETE_KVM_IMPL
+
 static int kvm_get_sregs(CPUState *env)
 {
     struct kvm_sregs sregs;
Index: qemu-kvm/kvm-all.c
===================================================================
--- qemu-kvm.orig/kvm-all.c
+++ qemu-kvm/kvm-all.c
@@ -1056,7 +1056,6 @@ int kvm_has_debugregs(void)
     return kvm_state->debugregs;
 }
 
-#ifdef OBSOLETE_KVM_IMPL
 int kvm_has_xsave(void)
 {
     return kvm_state->xsave;
@@ -1066,7 +1065,6 @@ int kvm_has_xcrs(void)
 {
     return kvm_state->xcrs;
 }
-#endif
 
 void kvm_setup_guest_memory(void *start, size_t size)
 {


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux