[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v3 3/4] xen/hvm: introduce a fpu_uninitialised field to the CPU save record
Introduce a new field to signal if the FPU has been initialised or not. Xen needs this new field in order to know whether to set the FPU as initialised or not during restore of CPU context. Previously Xen always wrongly assumed the FPU was initialised on restore. Signed-off-by: Roger Pau Monnà <roger.pau@xxxxxxxxxx> Cc: Jan Beulich <jbeulich@xxxxxxxx> Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> --- Changes since v1: - Don't add yet another compat structure, new fields should always be added to the end of the existing structure and offsetof should be used to compare sizes. - Leave the previous compat structure as-is, since the field was not added to the end we cannot remove it and use offsetof in this case. - Set xstate_bv based on fpu_initialised value instead of unconditionally setting it to XSTATE_FP_SSE. --- xen/arch/x86/hvm/hvm.c | 8 +++++--- xen/include/public/arch-x86/hvm/save.h | 26 +++++++++++++++++++------- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index ea982e2..72a4e4f 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -1800,6 +1800,7 @@ static int hvm_save_cpu_ctxt(struct domain *d, hvm_domain_context_t *h) memcpy(ctxt.fpu_regs, v->arch.fpu_ctxt, sizeof(ctxt.fpu_regs)); else memset(ctxt.fpu_regs, 0, sizeof(ctxt.fpu_regs)); + ctxt.fpu_initialised = v->fpu_initialised; ctxt.rax = v->arch.user_regs.eax; ctxt.rbx = v->arch.user_regs.ebx; @@ -1979,7 +1980,7 @@ static int hvm_load_cpu_ctxt(struct domain *d, hvm_domain_context_t *h) return -EINVAL; } - if ( hvm_load_entry(CPU, h, &ctxt) != 0 ) + if ( hvm_load_entry_zeroextend(CPU, h, &ctxt) != 0 ) return -EINVAL; /* Sanity check some control registers. */ @@ -2091,7 +2092,8 @@ static int hvm_load_cpu_ctxt(struct domain *d, hvm_domain_context_t *h) struct xsave_struct *xsave_area = v->arch.xsave_area; memcpy(v->arch.xsave_area, ctxt.fpu_regs, sizeof(ctxt.fpu_regs)); - xsave_area->xsave_hdr.xstate_bv = XSTATE_FP_SSE; + xsave_area->xsave_hdr.xstate_bv = ctxt.fpu_initialised ? + XSTATE_FP_SSE : 0; } else memcpy(v->arch.fpu_ctxt, ctxt.fpu_regs, sizeof(ctxt.fpu_regs)); @@ -2122,7 +2124,7 @@ static int hvm_load_cpu_ctxt(struct domain *d, hvm_domain_context_t *h) v->arch.debugreg[7] = ctxt.dr7; v->arch.vgc_flags = VGCF_online; - v->fpu_initialised = 1; + v->fpu_initialised = !!ctxt.fpu_initialised; /* Auxiliary processors should be woken immediately. */ v->is_initialised = 1; diff --git a/xen/include/public/arch-x86/hvm/save.h b/xen/include/public/arch-x86/hvm/save.h index 29d513c..0f7ef5a 100644 --- a/xen/include/public/arch-x86/hvm/save.h +++ b/xen/include/public/arch-x86/hvm/save.h @@ -47,7 +47,9 @@ DECLARE_HVM_SAVE_TYPE(HEADER, 1, struct hvm_save_header); /* * Processor * - * Compat: Pre-3.4 didn't have msr_tsc_aux + * Compat: + * - Pre-3.4 didn't have msr_tsc_aux + * - Pre-4.7 didn't have fpu_initialised */ struct hvm_hw_cpu { @@ -157,6 +159,8 @@ struct hvm_hw_cpu { }; /* error code for pending event */ uint32_t error_code; + /* is fpu initialised? */ + uint32_t fpu_initialised; }; struct hvm_hw_cpu_compat { @@ -266,6 +270,7 @@ struct hvm_hw_cpu_compat { }; /* error code for pending event */ uint32_t error_code; + /*uint32_t fpu_initialised; COMPAT */ }; static inline int _hvm_hw_fix_cpu(void *h, uint32_t size) { @@ -275,12 +280,19 @@ static inline int _hvm_hw_fix_cpu(void *h, uint32_t size) { struct hvm_hw_cpu_compat cmp; } *ucpu = (union hvm_hw_cpu_union *)h; - /* If we copy from the end backwards, we should - * be able to do the modification in-place */ - ucpu->nat.error_code = ucpu->cmp.error_code; - ucpu->nat.pending_event = ucpu->cmp.pending_event; - ucpu->nat.tsc = ucpu->cmp.tsc; - ucpu->nat.msr_tsc_aux = 0; + if ( size == sizeof(struct hvm_hw_cpu_compat) ) + { + /* + * If we copy from the end backwards, we should + * be able to do the modification in-place. + */ + ucpu->nat.error_code = ucpu->cmp.error_code; + ucpu->nat.pending_event = ucpu->cmp.pending_event; + ucpu->nat.tsc = ucpu->cmp.tsc; + ucpu->nat.msr_tsc_aux = 0; + } + /* Mimic the old behaviour by unconditionally setting fpu_initialised. */ + ucpu->nat.fpu_initialised = 1; return 0; } -- 1.9.5 (Apple Git-50.3) _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |