diff options
| -rw-r--r-- | arch/x86/include/asm/fpu/xstate.h | 36 | ||||
| -rw-r--r-- | arch/x86/kernel/fpu/init.c | 3 | ||||
| -rw-r--r-- | arch/x86/kernel/fpu/xstate.c | 26 | 
3 files changed, 38 insertions, 27 deletions
diff --git a/arch/x86/include/asm/fpu/xstate.h b/arch/x86/include/asm/fpu/xstate.h index fc4db51f3b53..b08fa823425f 100644 --- a/arch/x86/include/asm/fpu/xstate.h +++ b/arch/x86/include/asm/fpu/xstate.h @@ -21,19 +21,29 @@  #define XSAVE_YMM_SIZE	    256  #define XSAVE_YMM_OFFSET    (XSAVE_HDR_SIZE + XSAVE_HDR_OFFSET) -/* Supervisor features */ -#define XFEATURE_MASK_SUPERVISOR (XFEATURE_MASK_PT) - -/* All currently supported features */ -#define XCNTXT_MASK		(XFEATURE_MASK_FP | \ -				 XFEATURE_MASK_SSE | \ -				 XFEATURE_MASK_YMM | \ -				 XFEATURE_MASK_OPMASK | \ -				 XFEATURE_MASK_ZMM_Hi256 | \ -				 XFEATURE_MASK_Hi16_ZMM	 | \ -				 XFEATURE_MASK_PKRU | \ -				 XFEATURE_MASK_BNDREGS | \ -				 XFEATURE_MASK_BNDCSR) +/* All currently supported user features */ +#define XFEATURE_MASK_USER_SUPPORTED (XFEATURE_MASK_FP | \ +				      XFEATURE_MASK_SSE | \ +				      XFEATURE_MASK_YMM | \ +				      XFEATURE_MASK_OPMASK | \ +				      XFEATURE_MASK_ZMM_Hi256 | \ +				      XFEATURE_MASK_Hi16_ZMM	 | \ +				      XFEATURE_MASK_PKRU | \ +				      XFEATURE_MASK_BNDREGS | \ +				      XFEATURE_MASK_BNDCSR) + +/* All currently supported supervisor features */ +#define XFEATURE_MASK_SUPERVISOR_SUPPORTED (0) + +/* + * Unsupported supervisor features. When a supervisor feature in this mask is + * supported in the future, move it to the supported supervisor feature mask. + */ +#define XFEATURE_MASK_SUPERVISOR_UNSUPPORTED (XFEATURE_MASK_PT) + +/* All supervisor states including supported and unsupported states. */ +#define XFEATURE_MASK_SUPERVISOR_ALL (XFEATURE_MASK_SUPERVISOR_SUPPORTED | \ +				      XFEATURE_MASK_SUPERVISOR_UNSUPPORTED)  #ifdef CONFIG_X86_64  #define REX_PREFIX	"0x48, " diff --git a/arch/x86/kernel/fpu/init.c b/arch/x86/kernel/fpu/init.c index 6ce7e0a23268..61ddc3a5e5c2 100644 --- a/arch/x86/kernel/fpu/init.c +++ b/arch/x86/kernel/fpu/init.c @@ -224,7 +224,8 @@ static void __init fpu__init_system_xstate_size_legacy(void)   */  u64 __init fpu__get_supported_xfeatures_mask(void)  { -	return XCNTXT_MASK; +	return XFEATURE_MASK_USER_SUPPORTED | +	       XFEATURE_MASK_SUPERVISOR_SUPPORTED;  }  /* Legacy code to initialize eager fpu mode. */ diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c index 8ed64397c78b..9997df717339 100644 --- a/arch/x86/kernel/fpu/xstate.c +++ b/arch/x86/kernel/fpu/xstate.c @@ -208,14 +208,13 @@ void fpu__init_cpu_xstate(void)  	if (!boot_cpu_has(X86_FEATURE_XSAVE) || !xfeatures_mask)  		return;  	/* -	 * Make it clear that XSAVES supervisor states are not yet -	 * implemented should anyone expect it to work by changing -	 * bits in XFEATURE_MASK_* macros and XCR0. +	 * Unsupported supervisor xstates should not be found in +	 * the xfeatures mask.  	 */ -	WARN_ONCE((xfeatures_mask & XFEATURE_MASK_SUPERVISOR), -		"x86/fpu: XSAVES supervisor states are not yet implemented.\n"); +	WARN_ONCE((xfeatures_mask & XFEATURE_MASK_SUPERVISOR_UNSUPPORTED), +		  "x86/fpu: Found unsupported supervisor xstates.\n"); -	xfeatures_mask &= ~XFEATURE_MASK_SUPERVISOR; +	xfeatures_mask &= ~XFEATURE_MASK_SUPERVISOR_UNSUPPORTED;  	cr4_set_bits(X86_CR4_OSXSAVE);  	xsetbv(XCR_XFEATURE_ENABLED_MASK, xfeatures_mask); @@ -438,7 +437,7 @@ static int xfeature_uncompacted_offset(int xfeature_nr)  	 * format. Checking a supervisor state's uncompacted offset is  	 * an error.  	 */ -	if (XFEATURE_MASK_SUPERVISOR & BIT_ULL(xfeature_nr)) { +	if (XFEATURE_MASK_SUPERVISOR_ALL & BIT_ULL(xfeature_nr)) {  		WARN_ONCE(1, "No fixed offset for xstate %d\n", xfeature_nr);  		return -1;  	} @@ -475,7 +474,7 @@ int using_compacted_format(void)  int validate_user_xstate_header(const struct xstate_header *hdr)  {  	/* No unknown or supervisor features may be set */ -	if (hdr->xfeatures & (~xfeatures_mask | XFEATURE_MASK_SUPERVISOR)) +	if (hdr->xfeatures & ~(xfeatures_mask & XFEATURE_MASK_USER_SUPPORTED))  		return -EINVAL;  	/* Userspace must use the uncompacted format */ @@ -768,7 +767,8 @@ void __init fpu__init_system_xstate(void)  	 * Update info used for ptrace frames; use standard-format size and no  	 * supervisor xstates:  	 */ -	update_regset_xstate_info(fpu_user_xstate_size,	xfeatures_mask & ~XFEATURE_MASK_SUPERVISOR); +	update_regset_xstate_info(fpu_user_xstate_size, +				  xfeatures_mask & XFEATURE_MASK_USER_SUPPORTED);  	fpu__init_prepare_fx_sw_frame();  	setup_init_fpu_buf(); @@ -996,7 +996,7 @@ int copy_xstate_to_kernel(void *kbuf, struct xregs_state *xsave, unsigned int of  	 */  	memset(&header, 0, sizeof(header));  	header.xfeatures = xsave->header.xfeatures; -	header.xfeatures &= ~XFEATURE_MASK_SUPERVISOR; +	header.xfeatures &= XFEATURE_MASK_USER_SUPPORTED;  	/*  	 * Copy xregs_state->header: @@ -1080,7 +1080,7 @@ int copy_xstate_to_user(void __user *ubuf, struct xregs_state *xsave, unsigned i  	 */  	memset(&header, 0, sizeof(header));  	header.xfeatures = xsave->header.xfeatures; -	header.xfeatures &= ~XFEATURE_MASK_SUPERVISOR; +	header.xfeatures &= XFEATURE_MASK_USER_SUPPORTED;  	/*  	 * Copy xregs_state->header: @@ -1173,7 +1173,7 @@ int copy_kernel_to_xstate(struct xregs_state *xsave, const void *kbuf)  	 * The state that came in from userspace was user-state only.  	 * Mask all the user states out of 'xfeatures':  	 */ -	xsave->header.xfeatures &= XFEATURE_MASK_SUPERVISOR; +	xsave->header.xfeatures &= XFEATURE_MASK_SUPERVISOR_ALL;  	/*  	 * Add back in the features that came in from userspace: @@ -1229,7 +1229,7 @@ int copy_user_to_xstate(struct xregs_state *xsave, const void __user *ubuf)  	 * The state that came in from userspace was user-state only.  	 * Mask all the user states out of 'xfeatures':  	 */ -	xsave->header.xfeatures &= XFEATURE_MASK_SUPERVISOR; +	xsave->header.xfeatures &= XFEATURE_MASK_SUPERVISOR_ALL;  	/*  	 * Add back in the features that came in from userspace:  | 
