diff options
Diffstat (limited to 'arch/x86/include/asm/xsave.h')
| -rw-r--r-- | arch/x86/include/asm/xsave.h | 40 | 
1 files changed, 34 insertions, 6 deletions
diff --git a/arch/x86/include/asm/xsave.h b/arch/x86/include/asm/xsave.h index 2c4390cae22..c6ce2452f10 100644 --- a/arch/x86/include/asm/xsave.h +++ b/arch/x86/include/asm/xsave.h @@ -3,7 +3,8 @@  #include <linux/types.h>  #include <asm/processor.h> -#include <asm/i387.h> + +#define XSTATE_CPUID		0x0000000d  #define XSTATE_FP	0x1  #define XSTATE_SSE	0x2 @@ -13,6 +14,12 @@  #define FXSAVE_SIZE	512 +#define XSAVE_HDR_SIZE	    64 +#define XSAVE_HDR_OFFSET    FXSAVE_SIZE + +#define XSAVE_YMM_SIZE	    256 +#define XSAVE_YMM_OFFSET    (XSAVE_HDR_SIZE + XSAVE_HDR_OFFSET) +  /*   * These are the features that the OS can handle currently.   */ @@ -26,10 +33,8 @@  extern unsigned int xstate_size;  extern u64 pcntxt_mask; -extern struct xsave_struct *init_xstate_buf;  extern u64 xstate_fx_sw_bytes[USER_XSTATE_FX_SW_WORDS]; -extern void xsave_cntxt_init(void);  extern void xsave_init(void);  extern void update_regset_xstate_info(unsigned int size, u64 xstate_mask);  extern int init_fpu(struct task_struct *child); @@ -59,6 +64,16 @@ static inline int fpu_xrstor_checking(struct fpu *fpu)  static inline int xsave_user(struct xsave_struct __user *buf)  {  	int err; + +	/* +	 * Clear the xsave header first, so that reserved fields are +	 * initialized to zero. +	 */ +	err = __clear_user(&buf->xsave_hdr, +			   sizeof(struct xsave_hdr_struct)); +	if (unlikely(err)) +		return -EFAULT; +  	__asm__ __volatile__("1: .byte " REX_PREFIX "0x0f,0xae,0x27\n"  			     "2:\n"  			     ".section .fixup,\"ax\"\n" @@ -111,12 +126,25 @@ static inline void xrstor_state(struct xsave_struct *fx, u64 mask)  		     :   "memory");  } +static inline void xsave_state(struct xsave_struct *fx, u64 mask) +{ +	u32 lmask = mask; +	u32 hmask = mask >> 32; + +	asm volatile(".byte " REX_PREFIX "0x0f,0xae,0x27\n\t" +		     : : "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask) +		     :   "memory"); +} +  static inline void fpu_xsave(struct fpu *fpu)  {  	/* This, however, we can work around by forcing the compiler to select  	   an addressing mode that doesn't require extended registers. */ -	__asm__ __volatile__(".byte " REX_PREFIX "0x0f,0xae,0x27" -			     : : "D" (&(fpu->state->xsave)), -				 "a" (-1), "d"(-1) : "memory"); +	alternative_input( +		".byte " REX_PREFIX "0x0f,0xae,0x27", +		".byte " REX_PREFIX "0x0f,0xae,0x37", +		X86_FEATURE_XSAVEOPT, +		[fx] "D" (&fpu->state->xsave), "a" (-1), "d" (-1) : +		"memory");  }  #endif  | 
