static int kvm_get_xsave(CPUState *env) { #ifdef KVM_CAP_XSAVE struct kvm_xsave* xsave; int ret, i; uint16_t cwd, swd, twd, fop; if (!kvm_has_xsave()) { return kvm_get_fpu(env); } xsave = qemu_memalign(4096, sizeof(struct kvm_xsave)); ret = kvm_vcpu_ioctl(env, KVM_GET_XSAVE, xsave); if (ret < 0) { qemu_free(xsave); return ret; } 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); qemu_free(xsave); return 0; #else return kvm_get_fpu(env); #endif }