aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2011-11-18 09:22:45 +0100
committerJan Beulich <jbeulich@suse.com>2011-11-18 09:22:45 +0100
commit04678eb8f30a83620fa2c960431dfe4fb40d86f2 (patch)
treec2caef081e1024ab7b765435f108b025f5aa12aa
parent8eca0db0e836a081d873de7e9eefb3763f065780 (diff)
downloadxen-04678eb8f30a83620fa2c960431dfe4fb40d86f2.tar.gz
xen-04678eb8f30a83620fa2c960431dfe4fb40d86f2.tar.bz2
xen-04678eb8f30a83620fa2c960431dfe4fb40d86f2.zip
x86/xsave: provide guests with finit-like environment
Without the use of xsave, guests get their initial floating point environment set up with finit. At least NetWare actually depends on this (in particular on all exceptions being masked), so to be consistent set the same environment also when using xsave. This is also in line with all SSE exceptions getting masked initially. To avoid further fragile casts in xstate_alloc_save_area() the patch also changes xsave_struct's fpu_see member to have actually usable fields. The patch was tested in its technically identical, but modified-file- wise different 4.1.2 version. Signed-off-by: Jan Beulich <jbeulich@suse.com> Tested-by: Charles Arnold <carnold@suse.com> Acked-by: Keir Fraser <keir@xen.org>
-rw-r--r--xen/arch/x86/i387.c1
-rw-r--r--xen/arch/x86/xstate.c7
-rw-r--r--xen/include/asm-x86/xstate.h27
3 files changed, 30 insertions, 5 deletions
diff --git a/xen/arch/x86/i387.c b/xen/arch/x86/i387.c
index 3b8eedc917..0ec2308e45 100644
--- a/xen/arch/x86/i387.c
+++ b/xen/arch/x86/i387.c
@@ -17,7 +17,6 @@
#include <asm/xstate.h>
#include <asm/asm_defns.h>
-#define MXCSR_DEFAULT 0x1f80
static void fpu_init(void)
{
unsigned long val;
diff --git a/xen/arch/x86/xstate.c b/xen/arch/x86/xstate.c
index 8b9c5583f6..e4de1429ea 100644
--- a/xen/arch/x86/xstate.c
+++ b/xen/arch/x86/xstate.c
@@ -97,7 +97,7 @@ bool_t xsave_enabled(const struct vcpu *v)
int xstate_alloc_save_area(struct vcpu *v)
{
- void *save_area;
+ struct xsave_struct *save_area;
if ( !cpu_has_xsave || is_idle_vcpu(v) )
return 0;
@@ -109,8 +109,9 @@ int xstate_alloc_save_area(struct vcpu *v)
if ( save_area == NULL )
return -ENOMEM;
- ((u32 *)save_area)[6] = 0x1f80; /* MXCSR */
- *(uint64_t *)(save_area + 512) = XSTATE_FP_SSE; /* XSETBV */
+ save_area->fpu_sse.fcw = FCW_DEFAULT;
+ save_area->fpu_sse.mxcsr = MXCSR_DEFAULT;
+ save_area->xsave_hdr.xstate_bv = XSTATE_FP_SSE;
v->arch.xsave_area = save_area;
v->arch.xcr0 = XSTATE_FP_SSE;
diff --git a/xen/include/asm-x86/xstate.h b/xen/include/asm-x86/xstate.h
index 2ff495b226..90e405ef1a 100644
--- a/xen/include/asm-x86/xstate.h
+++ b/xen/include/asm-x86/xstate.h
@@ -11,6 +11,9 @@
#include <xen/types.h>
#include <xen/percpu.h>
+#define FCW_DEFAULT 0x037f
+#define MXCSR_DEFAULT 0x1f80
+
#define XSTATE_CPUID 0x0000000d
#define XSTATE_FEATURE_XSAVEOPT (1 << 0) /* sub-leaf 1, eax[bit 0] */
@@ -46,7 +49,29 @@ extern u64 xfeature_mask;
/* extended state save area */
struct xsave_struct
{
- struct { char x[512]; } fpu_sse; /* FPU/MMX, SSE */
+ union { /* FPU/MMX, SSE */
+ char x[512];
+ struct {
+ uint16_t fcw;
+ uint16_t fsw;
+ uint8_t ftw;
+ uint8_t rsvd1;
+ uint16_t fop;
+ union {
+#ifdef __x86_64__
+ uint64_t addr;
+#endif
+ struct {
+ uint32_t offs;
+ uint16_t sel;
+ uint16_t rsvd;
+ };
+ } fip, fdp;
+ uint32_t mxcsr;
+ uint32_t mxcsr_mask;
+ /* data registers follow here */
+ };
+ } fpu_sse;
struct {
u64 xstate_bv;