aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/xsave.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/xsave.c')
-rw-r--r--arch/x86/kernel/xsave.c25
1 files changed, 9 insertions, 16 deletions
diff --git a/arch/x86/kernel/xsave.c b/arch/x86/kernel/xsave.c
index 37e68fc5e24a..a4ae302f03aa 100644
--- a/arch/x86/kernel/xsave.c
+++ b/arch/x86/kernel/xsave.c
@@ -36,15 +36,14 @@ int check_for_xstate(struct i387_fxsave_struct __user *buf,
36 36
37 err = __copy_from_user(fx_sw_user, &buf->sw_reserved[0], 37 err = __copy_from_user(fx_sw_user, &buf->sw_reserved[0],
38 sizeof(struct _fpx_sw_bytes)); 38 sizeof(struct _fpx_sw_bytes));
39
40 if (err) 39 if (err)
41 return err; 40 return -EFAULT;
42 41
43 /* 42 /*
44 * First Magic check failed. 43 * First Magic check failed.
45 */ 44 */
46 if (fx_sw_user->magic1 != FP_XSTATE_MAGIC1) 45 if (fx_sw_user->magic1 != FP_XSTATE_MAGIC1)
47 return -1; 46 return -EINVAL;
48 47
49 /* 48 /*
50 * Check for error scenarios. 49 * Check for error scenarios.
@@ -52,19 +51,21 @@ int check_for_xstate(struct i387_fxsave_struct __user *buf,
52 if (fx_sw_user->xstate_size < min_xstate_size || 51 if (fx_sw_user->xstate_size < min_xstate_size ||
53 fx_sw_user->xstate_size > xstate_size || 52 fx_sw_user->xstate_size > xstate_size ||
54 fx_sw_user->xstate_size > fx_sw_user->extended_size) 53 fx_sw_user->xstate_size > fx_sw_user->extended_size)
55 return -1; 54 return -EINVAL;
56 55
57 err = __get_user(magic2, (__u32 *) (((void *)fpstate) + 56 err = __get_user(magic2, (__u32 *) (((void *)fpstate) +
58 fx_sw_user->extended_size - 57 fx_sw_user->extended_size -
59 FP_XSTATE_MAGIC2_SIZE)); 58 FP_XSTATE_MAGIC2_SIZE));
59 if (err)
60 return err;
60 /* 61 /*
61 * Check for the presence of second magic word at the end of memory 62 * Check for the presence of second magic word at the end of memory
62 * layout. This detects the case where the user just copied the legacy 63 * layout. This detects the case where the user just copied the legacy
63 * fpstate layout with out copying the extended state information 64 * fpstate layout with out copying the extended state information
64 * in the memory layout. 65 * in the memory layout.
65 */ 66 */
66 if (err || magic2 != FP_XSTATE_MAGIC2) 67 if (magic2 != FP_XSTATE_MAGIC2)
67 return -1; 68 return -EFAULT;
68 69
69 return 0; 70 return 0;
70} 71}
@@ -91,14 +92,6 @@ int save_i387_xstate(void __user *buf)
91 return 0; 92 return 0;
92 93
93 if (task_thread_info(tsk)->status & TS_USEDFPU) { 94 if (task_thread_info(tsk)->status & TS_USEDFPU) {
94 /*
95 * Start with clearing the user buffer. This will present a
96 * clean context for the bytes not touched by the fxsave/xsave.
97 */
98 err = __clear_user(buf, sig_xstate_size);
99 if (err)
100 return err;
101
102 if (use_xsave()) 95 if (use_xsave())
103 err = xsave_user(buf); 96 err = xsave_user(buf);
104 else 97 else
@@ -184,8 +177,8 @@ static int restore_user_xstate(void __user *buf)
184 * init the state skipped by the user. 177 * init the state skipped by the user.
185 */ 178 */
186 mask = pcntxt_mask & ~mask; 179 mask = pcntxt_mask & ~mask;
187 180 if (unlikely(mask))
188 xrstor_state(init_xstate_buf, mask); 181 xrstor_state(init_xstate_buf, mask);
189 182
190 return 0; 183 return 0;
191 184