1515#include <asm/sigframe.h>
1616#include <asm/trace/fpu.h>
1717
18- static struct _fpx_sw_bytes fx_sw_reserved , fx_sw_reserved_ia32 ;
18+ static struct _fpx_sw_bytes fx_sw_reserved __ro_after_init ;
19+ static struct _fpx_sw_bytes fx_sw_reserved_ia32 __ro_after_init ;
1920
2021/*
2122 * Check for the presence of extended state information in the
2223 * user fpstate pointer in the sigcontext.
2324 */
24- static inline int check_for_xstate (struct fxregs_state __user * buf ,
25- void __user * fpstate ,
26- struct _fpx_sw_bytes * fx_sw )
25+ static inline int check_xstate_in_sigframe (struct fxregs_state __user * fxbuf ,
26+ struct _fpx_sw_bytes * fx_sw )
2727{
2828 int min_xstate_size = sizeof (struct fxregs_state ) +
2929 sizeof (struct xstate_header );
30+ void __user * fpstate = fxbuf ;
3031 unsigned int magic2 ;
3132
32- if (__copy_from_user (fx_sw , & buf -> sw_reserved [0 ], sizeof (* fx_sw )))
33- return -1 ;
33+ if (__copy_from_user (fx_sw , & fxbuf -> sw_reserved [0 ], sizeof (* fx_sw )))
34+ return - EFAULT ;
3435
3536 /* Check for the first magic field and other error scenarios. */
3637 if (fx_sw -> magic1 != FP_XSTATE_MAGIC1 ||
3738 fx_sw -> xstate_size < min_xstate_size ||
3839 fx_sw -> xstate_size > fpu_user_xstate_size ||
3940 fx_sw -> xstate_size > fx_sw -> extended_size )
40- return -1 ;
41+ goto setfx ;
4142
4243 /*
4344 * Check for the presence of second magic word at the end of memory
4445 * layout. This detects the case where the user just copied the legacy
4546 * fpstate layout with out copying the extended state information
4647 * in the memory layout.
4748 */
48- if (__get_user (magic2 , (__u32 __user * )(fpstate + fx_sw -> xstate_size ))
49- || magic2 != FP_XSTATE_MAGIC2 )
50- return -1 ;
49+ if (__get_user (magic2 , (__u32 __user * )(fpstate + fx_sw -> xstate_size )))
50+ return - EFAULT ;
5151
52+ if (likely (magic2 == FP_XSTATE_MAGIC2 ))
53+ return 0 ;
54+ setfx :
55+ trace_x86_fpu_xstate_check_failed (& current -> thread .fpu );
56+
57+ /* Set the parameters for fx only state */
58+ fx_sw -> magic1 = 0 ;
59+ fx_sw -> xstate_size = sizeof (struct fxregs_state );
60+ fx_sw -> xfeatures = XFEATURE_MASK_FPSSE ;
5261 return 0 ;
5362}
5463
@@ -213,21 +222,15 @@ int copy_fpstate_to_sigframe(void __user *buf, void __user *buf_fx, int size)
213222
214223static inline void
215224sanitize_restored_user_xstate (union fpregs_state * state ,
216- struct user_i387_ia32_struct * ia32_env ,
217- u64 user_xfeatures , int fx_only )
225+ struct user_i387_ia32_struct * ia32_env , u64 mask )
218226{
219227 struct xregs_state * xsave = & state -> xsave ;
220228 struct xstate_header * header = & xsave -> header ;
221229
222230 if (use_xsave ()) {
223231 /*
224- * Clear all feature bits which are not set in
225- * user_xfeatures and clear all extended features
226- * for fx_only mode.
227- */
228- u64 mask = fx_only ? XFEATURE_MASK_FPSSE : user_xfeatures ;
229-
230- /*
232+ * Clear all feature bits which are not set in mask.
233+ *
231234 * Supervisor state has to be preserved. The sigframe
232235 * restore can only modify user features, i.e. @mask
233236 * cannot contain them.
@@ -286,24 +289,19 @@ static int __fpu_restore_sig(void __user *buf, void __user *buf_fx,
286289 struct fpu * fpu = & tsk -> thread .fpu ;
287290 struct user_i387_ia32_struct env ;
288291 u64 user_xfeatures = 0 ;
289- int fx_only = 0 ;
292+ bool fx_only = false ;
290293 int ret = 0 ;
291294
292295 if (use_xsave ()) {
293296 struct _fpx_sw_bytes fx_sw_user ;
294- if (unlikely (check_for_xstate (buf_fx , buf_fx , & fx_sw_user ))) {
295- /*
296- * Couldn't find the extended state information in the
297- * memory layout. Restore just the FP/SSE and init all
298- * the other extended state.
299- */
300- state_size = sizeof (struct fxregs_state );
301- fx_only = 1 ;
302- trace_x86_fpu_xstate_check_failed (fpu );
303- } else {
304- state_size = fx_sw_user .xstate_size ;
305- user_xfeatures = fx_sw_user .xfeatures ;
306- }
297+
298+ ret = check_xstate_in_sigframe (buf_fx , & fx_sw_user );
299+ if (unlikely (ret ))
300+ return ret ;
301+
302+ fx_only = !fx_sw_user .magic1 ;
303+ state_size = fx_sw_user .xstate_size ;
304+ user_xfeatures = fx_sw_user .xfeatures ;
307305 }
308306
309307 if (!ia32_fxstate ) {
@@ -403,8 +401,7 @@ static int __fpu_restore_sig(void __user *buf, void __user *buf_fx,
403401 if (ret )
404402 return ret ;
405403
406- sanitize_restored_user_xstate (& fpu -> state , envp , user_xfeatures ,
407- fx_only );
404+ sanitize_restored_user_xstate (& fpu -> state , envp , user_xfeatures );
408405
409406 fpregs_lock ();
410407 if (unlikely (init_bv ))
@@ -422,8 +419,7 @@ static int __fpu_restore_sig(void __user *buf, void __user *buf_fx,
422419 if (ret )
423420 return - EFAULT ;
424421
425- sanitize_restored_user_xstate (& fpu -> state , envp , user_xfeatures ,
426- fx_only );
422+ sanitize_restored_user_xstate (& fpu -> state , envp , user_xfeatures );
427423
428424 fpregs_lock ();
429425 if (use_xsave ()) {
0 commit comments