diff options
-rw-r--r-- | arch/x86/include/asm/xsave.h | 33 |
1 files changed, 18 insertions, 15 deletions
diff --git a/arch/x86/include/asm/xsave.h b/arch/x86/include/asm/xsave.h index 8b75824e41dd..0d1523146545 100644 --- a/arch/x86/include/asm/xsave.h +++ b/arch/x86/include/asm/xsave.h | |||
@@ -145,6 +145,16 @@ static inline int fpu_xrstor_checking(struct xsave_struct *fx) | |||
145 | return xrstor_state(fx, -1); | 145 | return xrstor_state(fx, -1); |
146 | } | 146 | } |
147 | 147 | ||
148 | /* | ||
149 | * Save xstate to user space xsave area. | ||
150 | * | ||
151 | * We don't use modified optimization because xrstor/xrstors might track | ||
152 | * a different application. | ||
153 | * | ||
154 | * We don't use compacted format xsave area for | ||
155 | * backward compatibility for old applications which don't understand | ||
156 | * compacted format of xsave area. | ||
157 | */ | ||
148 | static inline int xsave_user(struct xsave_struct __user *buf) | 158 | static inline int xsave_user(struct xsave_struct __user *buf) |
149 | { | 159 | { |
150 | int err; | 160 | int err; |
@@ -158,35 +168,28 @@ static inline int xsave_user(struct xsave_struct __user *buf) | |||
158 | return -EFAULT; | 168 | return -EFAULT; |
159 | 169 | ||
160 | __asm__ __volatile__(ASM_STAC "\n" | 170 | __asm__ __volatile__(ASM_STAC "\n" |
161 | "1: .byte " REX_PREFIX "0x0f,0xae,0x27\n" | 171 | "1:"XSAVE"\n" |
162 | "2: " ASM_CLAC "\n" | 172 | "2: " ASM_CLAC "\n" |
163 | ".section .fixup,\"ax\"\n" | 173 | xstate_fault |
164 | "3: movl $-1,%[err]\n" | ||
165 | " jmp 2b\n" | ||
166 | ".previous\n" | ||
167 | _ASM_EXTABLE(1b,3b) | ||
168 | : [err] "=r" (err) | ||
169 | : "D" (buf), "a" (-1), "d" (-1), "0" (0) | 174 | : "D" (buf), "a" (-1), "d" (-1), "0" (0) |
170 | : "memory"); | 175 | : "memory"); |
171 | return err; | 176 | return err; |
172 | } | 177 | } |
173 | 178 | ||
179 | /* | ||
180 | * Restore xstate from user space xsave area. | ||
181 | */ | ||
174 | static inline int xrestore_user(struct xsave_struct __user *buf, u64 mask) | 182 | static inline int xrestore_user(struct xsave_struct __user *buf, u64 mask) |
175 | { | 183 | { |
176 | int err; | 184 | int err = 0; |
177 | struct xsave_struct *xstate = ((__force struct xsave_struct *)buf); | 185 | struct xsave_struct *xstate = ((__force struct xsave_struct *)buf); |
178 | u32 lmask = mask; | 186 | u32 lmask = mask; |
179 | u32 hmask = mask >> 32; | 187 | u32 hmask = mask >> 32; |
180 | 188 | ||
181 | __asm__ __volatile__(ASM_STAC "\n" | 189 | __asm__ __volatile__(ASM_STAC "\n" |
182 | "1: .byte " REX_PREFIX "0x0f,0xae,0x2f\n" | 190 | "1:"XRSTOR"\n" |
183 | "2: " ASM_CLAC "\n" | 191 | "2: " ASM_CLAC "\n" |
184 | ".section .fixup,\"ax\"\n" | 192 | xstate_fault |
185 | "3: movl $-1,%[err]\n" | ||
186 | " jmp 2b\n" | ||
187 | ".previous\n" | ||
188 | _ASM_EXTABLE(1b,3b) | ||
189 | : [err] "=r" (err) | ||
190 | : "D" (xstate), "a" (lmask), "d" (hmask), "0" (0) | 193 | : "D" (xstate), "a" (lmask), "d" (hmask), "0" (0) |
191 | : "memory"); /* memory required? */ | 194 | : "memory"); /* memory required? */ |
192 | return err; | 195 | return err; |