15
15
#include <asm/sigframe.h>
16
16
#include <asm/trace/fpu.h>
17
17
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 ;
19
20
20
21
/*
21
22
* Check for the presence of extended state information in the
22
23
* user fpstate pointer in the sigcontext.
23
24
*/
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 )
27
27
{
28
28
int min_xstate_size = sizeof (struct fxregs_state ) +
29
29
sizeof (struct xstate_header );
30
+ void __user * fpstate = fxbuf ;
30
31
unsigned int magic2 ;
31
32
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 ;
34
35
35
36
/* Check for the first magic field and other error scenarios. */
36
37
if (fx_sw -> magic1 != FP_XSTATE_MAGIC1 ||
37
38
fx_sw -> xstate_size < min_xstate_size ||
38
39
fx_sw -> xstate_size > fpu_user_xstate_size ||
39
40
fx_sw -> xstate_size > fx_sw -> extended_size )
40
- return -1 ;
41
+ goto setfx ;
41
42
42
43
/*
43
44
* Check for the presence of second magic word at the end of memory
44
45
* layout. This detects the case where the user just copied the legacy
45
46
* fpstate layout with out copying the extended state information
46
47
* in the memory layout.
47
48
*/
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 ;
51
51
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 ;
52
61
return 0 ;
53
62
}
54
63
@@ -213,21 +222,15 @@ int copy_fpstate_to_sigframe(void __user *buf, void __user *buf_fx, int size)
213
222
214
223
static inline void
215
224
sanitize_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 )
218
226
{
219
227
struct xregs_state * xsave = & state -> xsave ;
220
228
struct xstate_header * header = & xsave -> header ;
221
229
222
230
if (use_xsave ()) {
223
231
/*
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
+ *
231
234
* Supervisor state has to be preserved. The sigframe
232
235
* restore can only modify user features, i.e. @mask
233
236
* cannot contain them.
@@ -286,24 +289,19 @@ static int __fpu_restore_sig(void __user *buf, void __user *buf_fx,
286
289
struct fpu * fpu = & tsk -> thread .fpu ;
287
290
struct user_i387_ia32_struct env ;
288
291
u64 user_xfeatures = 0 ;
289
- int fx_only = 0 ;
292
+ bool fx_only = false ;
290
293
int ret = 0 ;
291
294
292
295
if (use_xsave ()) {
293
296
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 ;
307
305
}
308
306
309
307
if (!ia32_fxstate ) {
@@ -403,8 +401,7 @@ static int __fpu_restore_sig(void __user *buf, void __user *buf_fx,
403
401
if (ret )
404
402
return ret ;
405
403
406
- sanitize_restored_user_xstate (& fpu -> state , envp , user_xfeatures ,
407
- fx_only );
404
+ sanitize_restored_user_xstate (& fpu -> state , envp , user_xfeatures );
408
405
409
406
fpregs_lock ();
410
407
if (unlikely (init_bv ))
@@ -422,8 +419,7 @@ static int __fpu_restore_sig(void __user *buf, void __user *buf_fx,
422
419
if (ret )
423
420
return - EFAULT ;
424
421
425
- sanitize_restored_user_xstate (& fpu -> state , envp , user_xfeatures ,
426
- fx_only );
422
+ sanitize_restored_user_xstate (& fpu -> state , envp , user_xfeatures );
427
423
428
424
fpregs_lock ();
429
425
if (use_xsave ()) {
0 commit comments