@@ -20,7 +20,8 @@
/* FPU Restore Functions */
/*******************************/
/* Restore x87 extended state */
-static inline void fpu_xrstor(struct vcpu *v, uint64_t mask)
+static inline void fpu_xrstor(struct vcpu *v, struct xsave_struct *xsave_area,
+ uint64_t mask)
{
bool ok;
@@ -31,16 +32,14 @@ static inline void fpu_xrstor(struct vcpu *v, uint64_t mask)
*/
ok = set_xcr0(v->arch.xcr0_accum | XSTATE_FP_SSE);
ASSERT(ok);
- xrstor(v, mask);
+ xrstor(v, xsave_area, mask);
ok = set_xcr0(v->arch.xcr0 ?: XSTATE_FP_SSE);
ASSERT(ok);
}
/* Restore x87 FPU, MMX, SSE and SSE2 state */
-static inline void fpu_fxrstor(struct vcpu *v)
+static inline void fpu_fxrstor(struct vcpu *v, const fpusse_t *fpu_ctxt)
{
- const fpusse_t *fpu_ctxt = &v->arch.xsave_area->fpu_sse;
-
/*
* Some CPUs don't save/restore FDP/FIP/FOP unless an exception
* is pending. Clear the x87 state here by setting it to fixed
@@ -197,6 +196,8 @@ static inline void fpu_fxsave(struct vcpu *v, fpusse_t *fpu_ctxt)
/* Restore FPU state whenever VCPU is schduled in. */
void vcpu_restore_fpu_nonlazy(struct vcpu *v, bool need_stts)
{
+ struct xsave_struct *xsave_area;
+
/* Restore nonlazy extended state (i.e. parts not tracked by CR0.TS). */
if ( !v->arch.fully_eager_fpu && !v->arch.nonlazy_xstate_used )
goto maybe_stts;
@@ -211,12 +212,13 @@ void vcpu_restore_fpu_nonlazy(struct vcpu *v, bool need_stts)
* above) we also need to restore full state, to prevent subsequently
* saving state belonging to another vCPU.
*/
+ xsave_area = vcpu_map_xsave_area(v);
if ( v->arch.fully_eager_fpu || xstate_all(v) )
{
if ( cpu_has_xsave )
- fpu_xrstor(v, XSTATE_ALL);
+ fpu_xrstor(v, xsave_area, XSTATE_ALL);
else
- fpu_fxrstor(v);
+ fpu_fxrstor(v, &xsave_area->fpu_sse);
v->fpu_initialised = 1;
v->fpu_dirtied = 1;
@@ -226,9 +228,10 @@ void vcpu_restore_fpu_nonlazy(struct vcpu *v, bool need_stts)
}
else
{
- fpu_xrstor(v, XSTATE_NONLAZY);
+ fpu_xrstor(v, xsave_area, XSTATE_NONLAZY);
need_stts = true;
}
+ vcpu_unmap_xsave_area(v, xsave_area);
maybe_stts:
if ( need_stts )
@@ -240,6 +243,7 @@ void vcpu_restore_fpu_nonlazy(struct vcpu *v, bool need_stts)
*/
void vcpu_restore_fpu_lazy(struct vcpu *v)
{
+ struct xsave_struct *xsave_area;
ASSERT(!is_idle_vcpu(v));
/* Avoid recursion. */
@@ -250,10 +254,12 @@ void vcpu_restore_fpu_lazy(struct vcpu *v)
ASSERT(!v->arch.fully_eager_fpu);
+ xsave_area = vcpu_map_xsave_area(v);
if ( cpu_has_xsave )
- fpu_xrstor(v, XSTATE_LAZY);
+ fpu_xrstor(v, xsave_area, XSTATE_LAZY);
else
- fpu_fxrstor(v);
+ fpu_fxrstor(v, &xsave_area->fpu_sse);
+ vcpu_unmap_xsave_area(v, xsave_area);
v->fpu_initialised = 1;
v->fpu_dirtied = 1;
@@ -98,7 +98,7 @@ void set_msr_xss(u64 xss);
uint64_t get_msr_xss(void);
uint64_t read_bndcfgu(void);
void xsave(struct vcpu *v, struct xsave_struct *ptr, uint64_t mask);
-void xrstor(struct vcpu *v, uint64_t mask);
+void xrstor(struct vcpu *v, struct xsave_struct *ptr, uint64_t mask);
void xstate_set_init(uint64_t mask);
bool xsave_enabled(const struct vcpu *v);
int __must_check validate_xstate(const struct domain *d,
@@ -374,11 +374,10 @@ void xsave(struct vcpu *v, struct xsave_struct *ptr, uint64_t mask)
ptr->fpu_sse.x[FPU_WORD_SIZE_OFFSET] = fip_width;
}
-void xrstor(struct vcpu *v, uint64_t mask)
+void xrstor(struct vcpu *v, struct xsave_struct *ptr, uint64_t mask)
{
uint32_t hmask = mask >> 32;
uint32_t lmask = mask;
- struct xsave_struct *ptr = v->arch.xsave_area;
unsigned int faults, prev_faults;
/*
@@ -992,6 +991,7 @@ int handle_xsetbv(u32 index, u64 new_bv)
mask &= curr->fpu_dirtied ? ~XSTATE_FP_SSE : XSTATE_NONLAZY;
if ( mask )
{
+ struct xsave_struct *xsave_area = vcpu_map_xsave_area(curr);
unsigned long cr0 = read_cr0();
clts();
@@ -1010,7 +1010,9 @@ int handle_xsetbv(u32 index, u64 new_bv)
curr->fpu_dirtied = 1;
cr0 &= ~X86_CR0_TS;
}
- xrstor(curr, mask);
+ xrstor(curr, xsave_area, mask);
+ vcpu_unmap_xsave_area(curr, xsave_area);
+
if ( cr0 & X86_CR0_TS )
write_cr0(cr0);
}
@@ -1080,7 +1082,7 @@ void xstate_set_init(uint64_t mask)
xstate = vcpu_map_xsave_area(v);
memset(&xstate->xsave_hdr, 0, sizeof(xstate->xsave_hdr));
- xrstor(v, mask);
+ xrstor(v, xstate, mask);
vcpu_unmap_xsave_area(v, xstate);
if ( cr0 & X86_CR0_TS )
No functional change. Signed-off-by: Alejandro Vallejo <alejandro.vallejo@cloud.com> --- xen/arch/x86/i387.c | 26 ++++++++++++++++---------- xen/arch/x86/include/asm/xstate.h | 2 +- xen/arch/x86/xstate.c | 10 ++++++---- 3 files changed, 23 insertions(+), 15 deletions(-)