aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/include/asm/i387.h9
-rw-r--r--arch/x86/include/asm/xsave.h10
-rw-r--r--arch/x86/kernel/xsave.c12
3 files changed, 21 insertions, 10 deletions
diff --git a/arch/x86/include/asm/i387.h b/arch/x86/include/asm/i387.h
index c991b3a7b904..0f1cf5d53dd8 100644
--- a/arch/x86/include/asm/i387.h
+++ b/arch/x86/include/asm/i387.h
@@ -127,6 +127,15 @@ static inline int fxsave_user(struct i387_fxsave_struct __user *fx)
127{ 127{
128 int err; 128 int err;
129 129
130 /*
131 * Clear the bytes not touched by the fxsave and reserved
132 * for the SW usage.
133 */
134 err = __clear_user(&fx->sw_reserved,
135 sizeof(struct _fpx_sw_bytes));
136 if (unlikely(err))
137 return -EFAULT;
138
130 asm volatile("1: rex64/fxsave (%[fx])\n\t" 139 asm volatile("1: rex64/fxsave (%[fx])\n\t"
131 "2:\n" 140 "2:\n"
132 ".section .fixup,\"ax\"\n" 141 ".section .fixup,\"ax\"\n"
diff --git a/arch/x86/include/asm/xsave.h b/arch/x86/include/asm/xsave.h
index 2c4390cae228..30dfc81804d5 100644
--- a/arch/x86/include/asm/xsave.h
+++ b/arch/x86/include/asm/xsave.h
@@ -59,6 +59,16 @@ static inline int fpu_xrstor_checking(struct fpu *fpu)
59static inline int xsave_user(struct xsave_struct __user *buf) 59static inline int xsave_user(struct xsave_struct __user *buf)
60{ 60{
61 int err; 61 int err;
62
63 /*
64 * Clear the xsave header first, so that reserved fields are
65 * initialized to zero.
66 */
67 err = __clear_user(&buf->xsave_hdr,
68 sizeof(struct xsave_hdr_struct));
69 if (unlikely(err))
70 return -EFAULT;
71
62 __asm__ __volatile__("1: .byte " REX_PREFIX "0x0f,0xae,0x27\n" 72 __asm__ __volatile__("1: .byte " REX_PREFIX "0x0f,0xae,0x27\n"
63 "2:\n" 73 "2:\n"
64 ".section .fixup,\"ax\"\n" 74 ".section .fixup,\"ax\"\n"
diff --git a/arch/x86/kernel/xsave.c b/arch/x86/kernel/xsave.c
index 37e68fc5e24a..6e73db1b7b4e 100644
--- a/arch/x86/kernel/xsave.c
+++ b/arch/x86/kernel/xsave.c
@@ -91,14 +91,6 @@ int save_i387_xstate(void __user *buf)
91 return 0; 91 return 0;
92 92
93 if (task_thread_info(tsk)->status & TS_USEDFPU) { 93 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()) 94 if (use_xsave())
103 err = xsave_user(buf); 95 err = xsave_user(buf);
104 else 96 else
@@ -184,8 +176,8 @@ static int restore_user_xstate(void __user *buf)
184 * init the state skipped by the user. 176 * init the state skipped by the user.
185 */ 177 */
186 mask = pcntxt_mask & ~mask; 178 mask = pcntxt_mask & ~mask;
187 179 if (unlikely(mask))
188 xrstor_state(init_xstate_buf, mask); 180 xrstor_state(init_xstate_buf, mask);
189 181
190 return 0; 182 return 0;
191 183