target-i386: kvm: Use X86XSaveArea struct for xsave save/load
Instead of using offset macros and bit operations in a uint32_t array, use the X86XSaveArea struct to perform the loading/saving operations in kvm_put_xsave() and kvm_get_xsave(). Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
This commit is contained in:
parent
ee1b09f695
commit
86cd2ea071
@ -1333,9 +1333,8 @@ ASSERT_OFFSET(XSAVE_PKRU, pkru_state);
|
||||
static int kvm_put_xsave(X86CPU *cpu)
|
||||
{
|
||||
CPUX86State *env = &cpu->env;
|
||||
struct kvm_xsave* xsave = env->kvm_xsave_buf;
|
||||
X86XSaveArea *xsave = env->kvm_xsave_buf;
|
||||
uint16_t cwd, swd, twd;
|
||||
uint8_t *xmm, *ymmh, *zmmh;
|
||||
int i, r;
|
||||
|
||||
if (!has_xsave) {
|
||||
@ -1350,25 +1349,26 @@ static int kvm_put_xsave(X86CPU *cpu)
|
||||
for (i = 0; i < 8; ++i) {
|
||||
twd |= (!env->fptags[i]) << i;
|
||||
}
|
||||
xsave->region[XSAVE_FCW_FSW] = (uint32_t)(swd << 16) + cwd;
|
||||
xsave->region[XSAVE_FTW_FOP] = (uint32_t)(env->fpop << 16) + twd;
|
||||
memcpy(&xsave->region[XSAVE_CWD_RIP], &env->fpip, sizeof(env->fpip));
|
||||
memcpy(&xsave->region[XSAVE_CWD_RDP], &env->fpdp, sizeof(env->fpdp));
|
||||
memcpy(&xsave->region[XSAVE_ST_SPACE], env->fpregs,
|
||||
xsave->legacy.fcw = cwd;
|
||||
xsave->legacy.fsw = swd;
|
||||
xsave->legacy.ftw = twd;
|
||||
xsave->legacy.fpop = env->fpop;
|
||||
xsave->legacy.fpip = env->fpip;
|
||||
xsave->legacy.fpdp = env->fpdp;
|
||||
memcpy(&xsave->legacy.fpregs, env->fpregs,
|
||||
sizeof env->fpregs);
|
||||
xsave->region[XSAVE_MXCSR] = env->mxcsr;
|
||||
*(uint64_t *)&xsave->region[XSAVE_XSTATE_BV] = env->xstate_bv;
|
||||
memcpy(&xsave->region[XSAVE_BNDREGS], env->bnd_regs,
|
||||
xsave->legacy.mxcsr = env->mxcsr;
|
||||
xsave->header.xstate_bv = env->xstate_bv;
|
||||
memcpy(&xsave->bndreg_state.bnd_regs, env->bnd_regs,
|
||||
sizeof env->bnd_regs);
|
||||
memcpy(&xsave->region[XSAVE_BNDCSR], &env->bndcs_regs,
|
||||
sizeof(env->bndcs_regs));
|
||||
memcpy(&xsave->region[XSAVE_OPMASK], env->opmask_regs,
|
||||
xsave->bndcsr_state.bndcsr = env->bndcs_regs;
|
||||
memcpy(&xsave->opmask_state.opmask_regs, env->opmask_regs,
|
||||
sizeof env->opmask_regs);
|
||||
|
||||
xmm = (uint8_t *)&xsave->region[XSAVE_XMM_SPACE];
|
||||
ymmh = (uint8_t *)&xsave->region[XSAVE_YMMH_SPACE];
|
||||
zmmh = (uint8_t *)&xsave->region[XSAVE_ZMM_Hi256];
|
||||
for (i = 0; i < CPU_NB_REGS; i++, xmm += 16, ymmh += 16, zmmh += 32) {
|
||||
for (i = 0; i < CPU_NB_REGS; i++) {
|
||||
uint8_t *xmm = xsave->legacy.xmm_regs[i];
|
||||
uint8_t *ymmh = xsave->avx_state.ymmh[i];
|
||||
uint8_t *zmmh = xsave->zmm_hi256_state.zmm_hi256[i];
|
||||
stq_p(xmm, env->xmm_regs[i].ZMM_Q(0));
|
||||
stq_p(xmm+8, env->xmm_regs[i].ZMM_Q(1));
|
||||
stq_p(ymmh, env->xmm_regs[i].ZMM_Q(2));
|
||||
@ -1380,9 +1380,9 @@ static int kvm_put_xsave(X86CPU *cpu)
|
||||
}
|
||||
|
||||
#ifdef TARGET_X86_64
|
||||
memcpy(&xsave->region[XSAVE_Hi16_ZMM], &env->xmm_regs[16],
|
||||
memcpy(&xsave->hi16_zmm_state.hi16_zmm, &env->xmm_regs[16],
|
||||
16 * sizeof env->xmm_regs[16]);
|
||||
memcpy(&xsave->region[XSAVE_PKRU], &env->pkru, sizeof env->pkru);
|
||||
memcpy(&xsave->pkru_state, &env->pkru, sizeof env->pkru);
|
||||
#endif
|
||||
r = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_XSAVE, xsave);
|
||||
return r;
|
||||
@ -1771,9 +1771,8 @@ static int kvm_get_fpu(X86CPU *cpu)
|
||||
static int kvm_get_xsave(X86CPU *cpu)
|
||||
{
|
||||
CPUX86State *env = &cpu->env;
|
||||
struct kvm_xsave* xsave = env->kvm_xsave_buf;
|
||||
X86XSaveArea *xsave = env->kvm_xsave_buf;
|
||||
int ret, i;
|
||||
const uint8_t *xmm, *ymmh, *zmmh;
|
||||
uint16_t cwd, swd, twd;
|
||||
|
||||
if (!has_xsave) {
|
||||
@ -1785,33 +1784,32 @@ static int kvm_get_xsave(X86CPU *cpu)
|
||||
return ret;
|
||||
}
|
||||
|
||||
cwd = (uint16_t)xsave->region[XSAVE_FCW_FSW];
|
||||
swd = (uint16_t)(xsave->region[XSAVE_FCW_FSW] >> 16);
|
||||
twd = (uint16_t)xsave->region[XSAVE_FTW_FOP];
|
||||
env->fpop = (uint16_t)(xsave->region[XSAVE_FTW_FOP] >> 16);
|
||||
cwd = xsave->legacy.fcw;
|
||||
swd = xsave->legacy.fsw;
|
||||
twd = xsave->legacy.ftw;
|
||||
env->fpop = xsave->legacy.fpop;
|
||||
env->fpstt = (swd >> 11) & 7;
|
||||
env->fpus = swd;
|
||||
env->fpuc = cwd;
|
||||
for (i = 0; i < 8; ++i) {
|
||||
env->fptags[i] = !((twd >> i) & 1);
|
||||
}
|
||||
memcpy(&env->fpip, &xsave->region[XSAVE_CWD_RIP], sizeof(env->fpip));
|
||||
memcpy(&env->fpdp, &xsave->region[XSAVE_CWD_RDP], sizeof(env->fpdp));
|
||||
env->mxcsr = xsave->region[XSAVE_MXCSR];
|
||||
memcpy(env->fpregs, &xsave->region[XSAVE_ST_SPACE],
|
||||
env->fpip = xsave->legacy.fpip;
|
||||
env->fpdp = xsave->legacy.fpdp;
|
||||
env->mxcsr = xsave->legacy.mxcsr;
|
||||
memcpy(env->fpregs, &xsave->legacy.fpregs,
|
||||
sizeof env->fpregs);
|
||||
env->xstate_bv = *(uint64_t *)&xsave->region[XSAVE_XSTATE_BV];
|
||||
memcpy(env->bnd_regs, &xsave->region[XSAVE_BNDREGS],
|
||||
env->xstate_bv = xsave->header.xstate_bv;
|
||||
memcpy(env->bnd_regs, &xsave->bndreg_state.bnd_regs,
|
||||
sizeof env->bnd_regs);
|
||||
memcpy(&env->bndcs_regs, &xsave->region[XSAVE_BNDCSR],
|
||||
sizeof(env->bndcs_regs));
|
||||
memcpy(env->opmask_regs, &xsave->region[XSAVE_OPMASK],
|
||||
env->bndcs_regs = xsave->bndcsr_state.bndcsr;
|
||||
memcpy(env->opmask_regs, &xsave->opmask_state.opmask_regs,
|
||||
sizeof env->opmask_regs);
|
||||
|
||||
xmm = (const uint8_t *)&xsave->region[XSAVE_XMM_SPACE];
|
||||
ymmh = (const uint8_t *)&xsave->region[XSAVE_YMMH_SPACE];
|
||||
zmmh = (const uint8_t *)&xsave->region[XSAVE_ZMM_Hi256];
|
||||
for (i = 0; i < CPU_NB_REGS; i++, xmm += 16, ymmh += 16, zmmh += 32) {
|
||||
for (i = 0; i < CPU_NB_REGS; i++) {
|
||||
uint8_t *xmm = xsave->legacy.xmm_regs[i];
|
||||
uint8_t *ymmh = xsave->avx_state.ymmh[i];
|
||||
uint8_t *zmmh = xsave->zmm_hi256_state.zmm_hi256[i];
|
||||
env->xmm_regs[i].ZMM_Q(0) = ldq_p(xmm);
|
||||
env->xmm_regs[i].ZMM_Q(1) = ldq_p(xmm+8);
|
||||
env->xmm_regs[i].ZMM_Q(2) = ldq_p(ymmh);
|
||||
@ -1823,9 +1821,9 @@ static int kvm_get_xsave(X86CPU *cpu)
|
||||
}
|
||||
|
||||
#ifdef TARGET_X86_64
|
||||
memcpy(&env->xmm_regs[16], &xsave->region[XSAVE_Hi16_ZMM],
|
||||
memcpy(&env->xmm_regs[16], &xsave->hi16_zmm_state.hi16_zmm,
|
||||
16 * sizeof env->xmm_regs[16]);
|
||||
memcpy(&env->pkru, &xsave->region[XSAVE_PKRU], sizeof env->pkru);
|
||||
memcpy(&env->pkru, &xsave->pkru_state, sizeof env->pkru);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user