diff options
author | Jan Beulich <jbeulich@suse.com> | 2013-06-04 17:23:11 +0200 |
---|---|---|
committer | Jan Beulich <jbeulich@suse.com> | 2013-06-04 17:23:11 +0200 |
commit | 10f969150025498fe27d985f9021a68f8c7acc31 (patch) | |
tree | 08b97882a408b61fcfcf8ee1f11d8bc257c4ca6a /xen/include/asm-x86/xstate.h | |
parent | 365c95f7de789e1dca03f119eab7dc61fe0f77c9 (diff) | |
download | xen-10f969150025498fe27d985f9021a68f8c7acc31.tar.gz xen-10f969150025498fe27d985f9021a68f8c7acc31.tar.bz2 xen-10f969150025498fe27d985f9021a68f8c7acc31.zip |
x86: preserve FPU selectors for 32-bit guest code
Doing {,F}X{SAVE,RSTOR} unconditionally with 64-bit operand size leads
to the selector values associated with the last instruction/data
pointers getting lost. This, besides being inconsistent and not
compatible with native hardware behavior especially for 32-bit guests,
leads to bug checks in 32-bit Windows when running with "Driver
verifier" (see e.g. http://support.microsoft.com/kb/244617).
In a first try I made the code figure out the current guest mode, but
that has the disadvantage of only taking care of the issue when the
guest executes in the mode for which the state currently is (i.e.
namely not in the case of a 64-bit guest running a 32-bit application,
but being in kernle [64-bit] mode).
The solution presented here is to conditionally execute an auxiliary
FNSTENV and use the selectors from there.
In either case the determined word size gets stored in the last byte
of the FPU/SSE save area, which is available for software use (and I
verified is being cleared to zero by all versions of Xen, i.e. will not
present a problem when migrating guests from older to newer hosts), and
evaluated for determining the operand size {,F}XRSTOR is to be issued
with.
Note that I did check whether using a second FXSAVE or a partial second
XSAVE would be faster than FNSTENV - neither on my Westmere (FXSAVE)
nor on my Romley (XSAVE) they are.
I was really tempted to use branches into the middle of instructions
(i.e. past the REX64 prefixes) here, as that would have allowed to
collapse the otherwise identical fault recovery blocks. I stayed away
from doing so just because I expect others to dislike such slightly
subtle/tricky code.
Reported-by: Ben Guthro <Benjamin.Guthro@citrix.com>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Keir Fraser <keir@xen.org>
Acked-by: George Dunlap <george.dunlap@eu.citrix.com>
Diffstat (limited to 'xen/include/asm-x86/xstate.h')
-rw-r--r-- | xen/include/asm-x86/xstate.h | 2 |
1 files changed, 0 insertions, 2 deletions
diff --git a/xen/include/asm-x86/xstate.h b/xen/include/asm-x86/xstate.h index 9f4fd5c083..6d64f37827 100644 --- a/xen/include/asm-x86/xstate.h +++ b/xen/include/asm-x86/xstate.h @@ -34,8 +34,6 @@ #define XSTATE_NONLAZY (XSTATE_LWP) #define XSTATE_LAZY (XSTATE_ALL & ~XSTATE_NONLAZY) -#define REX_PREFIX "0x48, " - /* extended state variables */ DECLARE_PER_CPU(uint64_t, xcr0); |