[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[RFC PATCH 7/7] target/i386: Manipulate only AMD XSAVE state on AMD
From: |
David Edmondson |
Subject: |
[RFC PATCH 7/7] target/i386: Manipulate only AMD XSAVE state on AMD |
Date: |
Thu, 20 May 2021 15:56:47 +0100 |
On AMD CPUs, ensure to save/load only the relevant XSAVE state.
Signed-off-by: David Edmondson <david.edmondson@oracle.com>
---
target/i386/tcg/fpu_helper.c | 12 +++++--
target/i386/xsave_helper.c | 70 ++++++++++++++++++++++--------------
2 files changed, 54 insertions(+), 28 deletions(-)
diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
index fba2de5b04..f1d4704b34 100644
--- a/target/i386/tcg/fpu_helper.c
+++ b/target/i386/tcg/fpu_helper.c
@@ -2643,7 +2643,11 @@ static void do_xsave(CPUX86State *env, target_ulong ptr,
uint64_t rfbm,
do_xsave_bndcsr(env, ptr + XO(intel.bndcsr_state), ra);
}
if (opt & XSTATE_PKRU_MASK) {
- do_xsave_pkru(env, ptr + XO(intel.pkru_state), ra);
+ if (IS_AMD_CPU(env)) {
+ do_xsave_pkru(env, ptr + XO(amd.pkru_state), ra);
+ } else {
+ do_xsave_pkru(env, ptr + XO(intel.pkru_state), ra);
+ }
}
/* Update the XSTATE_BV field. */
@@ -2854,7 +2858,11 @@ void helper_xrstor(CPUX86State *env, target_ulong ptr,
uint64_t rfbm)
if (rfbm & XSTATE_PKRU_MASK) {
uint64_t old_pkru = env->pkru;
if (xstate_bv & XSTATE_PKRU_MASK) {
- do_xrstor_pkru(env, ptr + XO(intel.pkru_state), ra);
+ if (IS_AMD_CPU(env)) {
+ do_xrstor_pkru(env, ptr + XO(amd.pkru_state), ra);
+ } else {
+ do_xrstor_pkru(env, ptr + XO(intel.pkru_state), ra);
+ }
} else {
env->pkru = 0;
}
diff --git a/target/i386/xsave_helper.c b/target/i386/xsave_helper.c
index 97dbab85d1..6b4501cf29 100644
--- a/target/i386/xsave_helper.c
+++ b/target/i386/xsave_helper.c
@@ -10,6 +10,7 @@ void x86_cpu_xsave_all_areas(X86CPU *cpu, X86XSaveArea *buf)
{
CPUX86State *env = &cpu->env;
X86XSaveArea *xsave = buf;
+ const bool is_amd = IS_AMD_CPU(env);
uint16_t cwd, swd, twd;
int i;
@@ -31,30 +32,38 @@ void x86_cpu_xsave_all_areas(X86CPU *cpu, X86XSaveArea *buf)
sizeof env->fpregs);
xsave->legacy.mxcsr = env->mxcsr;
xsave->header.xstate_bv = env->xstate_bv;
- memcpy(&xsave->intel.bndreg_state.bnd_regs, env->bnd_regs,
- sizeof env->bnd_regs);
- xsave->intel.bndcsr_state.bndcsr = env->bndcs_regs;
- memcpy(&xsave->intel.opmask_state.opmask_regs, env->opmask_regs,
- sizeof env->opmask_regs);
+ if (!is_amd) {
+ memcpy(&xsave->intel.bndreg_state.bnd_regs, env->bnd_regs,
+ sizeof env->bnd_regs);
+ xsave->intel.bndcsr_state.bndcsr = env->bndcs_regs;
+ memcpy(&xsave->intel.opmask_state.opmask_regs, env->opmask_regs,
+ sizeof env->opmask_regs);
+ }
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->intel.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));
stq_p(ymmh+8, env->xmm_regs[i].ZMM_Q(3));
- stq_p(zmmh, env->xmm_regs[i].ZMM_Q(4));
- stq_p(zmmh+8, env->xmm_regs[i].ZMM_Q(5));
- stq_p(zmmh+16, env->xmm_regs[i].ZMM_Q(6));
- stq_p(zmmh+24, env->xmm_regs[i].ZMM_Q(7));
+ if (!is_amd) {
+ uint8_t *zmmh = xsave->intel.zmm_hi256_state.zmm_hi256[i];
+ stq_p(zmmh, env->xmm_regs[i].ZMM_Q(4));
+ stq_p(zmmh+8, env->xmm_regs[i].ZMM_Q(5));
+ stq_p(zmmh+16, env->xmm_regs[i].ZMM_Q(6));
+ stq_p(zmmh+24, env->xmm_regs[i].ZMM_Q(7));
+ }
}
#ifdef TARGET_X86_64
- memcpy(&xsave->intel.hi16_zmm_state.hi16_zmm, &env->xmm_regs[16],
- 16 * sizeof env->xmm_regs[16]);
- memcpy(&xsave->intel.pkru_state, &env->pkru, sizeof env->pkru);
+ if (is_amd) {
+ memcpy(&xsave->amd.pkru_state, &env->pkru, sizeof env->pkru);
+ } else {
+ memcpy(&xsave->intel.hi16_zmm_state.hi16_zmm, &env->xmm_regs[16],
+ 16 * sizeof env->xmm_regs[16]);
+ memcpy(&xsave->intel.pkru_state, &env->pkru, sizeof env->pkru);
+ }
#endif
}
@@ -64,6 +73,7 @@ void x86_cpu_xrstor_all_areas(X86CPU *cpu, const X86XSaveArea
*buf)
CPUX86State *env = &cpu->env;
const X86XSaveArea *xsave = buf;
+ const bool is_amd = IS_AMD_CPU(env);
int i;
uint16_t cwd, swd, twd;
@@ -83,30 +93,38 @@ void x86_cpu_xrstor_all_areas(X86CPU *cpu, const
X86XSaveArea *buf)
memcpy(env->fpregs, &xsave->legacy.fpregs,
sizeof env->fpregs);
env->xstate_bv = xsave->header.xstate_bv;
- memcpy(env->bnd_regs, &xsave->intel.bndreg_state.bnd_regs,
- sizeof env->bnd_regs);
- env->bndcs_regs = xsave->intel.bndcsr_state.bndcsr;
- memcpy(env->opmask_regs, &xsave->intel.opmask_state.opmask_regs,
- sizeof env->opmask_regs);
+ if (!is_amd) {
+ memcpy(env->bnd_regs, &xsave->intel.bndreg_state.bnd_regs,
+ sizeof env->bnd_regs);
+ env->bndcs_regs = xsave->intel.bndcsr_state.bndcsr;
+ memcpy(env->opmask_regs, &xsave->intel.opmask_state.opmask_regs,
+ sizeof env->opmask_regs);
+ }
for (i = 0; i < CPU_NB_REGS; i++) {
const uint8_t *xmm = xsave->legacy.xmm_regs[i];
const uint8_t *ymmh = xsave->avx_state.ymmh[i];
- const uint8_t *zmmh = xsave->intel.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);
env->xmm_regs[i].ZMM_Q(3) = ldq_p(ymmh+8);
- env->xmm_regs[i].ZMM_Q(4) = ldq_p(zmmh);
- env->xmm_regs[i].ZMM_Q(5) = ldq_p(zmmh+8);
- env->xmm_regs[i].ZMM_Q(6) = ldq_p(zmmh+16);
- env->xmm_regs[i].ZMM_Q(7) = ldq_p(zmmh+24);
+ if (!is_amd) {
+ const uint8_t *zmmh = xsave->intel.zmm_hi256_state.zmm_hi256[i];
+ env->xmm_regs[i].ZMM_Q(4) = ldq_p(zmmh);
+ env->xmm_regs[i].ZMM_Q(5) = ldq_p(zmmh+8);
+ env->xmm_regs[i].ZMM_Q(6) = ldq_p(zmmh+16);
+ env->xmm_regs[i].ZMM_Q(7) = ldq_p(zmmh+24);
+ }
}
#ifdef TARGET_X86_64
- memcpy(&env->xmm_regs[16], &xsave->intel.hi16_zmm_state.hi16_zmm,
- 16 * sizeof env->xmm_regs[16]);
- memcpy(&env->pkru, &xsave->intel.pkru_state, sizeof env->pkru);
+ if (is_amd) {
+ memcpy(&env->pkru, &xsave->amd.pkru_state, sizeof env->pkru);
+ } else {
+ memcpy(&env->xmm_regs[16], &xsave->intel.hi16_zmm_state.hi16_zmm,
+ 16 * sizeof env->xmm_regs[16]);
+ memcpy(&env->pkru, &xsave->intel.pkru_state, sizeof env->pkru);
+ }
#endif
}
--
2.30.2
- [RFC PATCH 0/7] Support protection keys in an AMD EPYC-Milan VM, David Edmondson, 2021/05/20
- [RFC PATCH 1/7] target/i386: Declare constants for XSAVE offsets, David Edmondson, 2021/05/20
- [RFC PATCH 3/7] target/i386: Clarify the padding requirements of X86XSaveArea, David Edmondson, 2021/05/20
- [RFC PATCH 4/7] target/i386: Prepare for per-vendor X86XSaveArea layout, David Edmondson, 2021/05/20
- [RFC PATCH 5/7] target/i386: Introduce AMD X86XSaveArea sub-union, David Edmondson, 2021/05/20
- [RFC PATCH 6/7] target/i386: Adjust AMD XSAVE PKRU area offset in CPUID leaf 0xd, David Edmondson, 2021/05/20
- [RFC PATCH 2/7] target/i386: Use constants for XSAVE offsets, David Edmondson, 2021/05/20
- [RFC PATCH 7/7] target/i386: Manipulate only AMD XSAVE state on AMD,
David Edmondson <=
- Re: [RFC PATCH 0/7] Support protection keys in an AMD EPYC-Milan VM, no-reply, 2021/05/20