aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r--arch/x86/kernel/fpu/core.c25
-rw-r--r--arch/x86/kernel/fpu/init.c21
-rw-r--r--arch/x86/kernel/fpu/signal.c35
-rw-r--r--arch/x86/kernel/fpu/xstate.c92
4 files changed, 116 insertions, 57 deletions
diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c
index 97027545a72d..c759bd01ec99 100644
--- a/arch/x86/kernel/fpu/core.c
+++ b/arch/x86/kernel/fpu/core.c
@@ -12,6 +12,9 @@
12 12
13#include <linux/hardirq.h> 13#include <linux/hardirq.h>
14 14
15#define CREATE_TRACE_POINTS
16#include <asm/trace/fpu.h>
17
15/* 18/*
16 * Represents the initial FPU state. It's mostly (but not completely) zeroes, 19 * Represents the initial FPU state. It's mostly (but not completely) zeroes,
17 * depending on the FPU hardware format: 20 * depending on the FPU hardware format:
@@ -192,6 +195,7 @@ void fpu__save(struct fpu *fpu)
192 WARN_ON_FPU(fpu != &current->thread.fpu); 195 WARN_ON_FPU(fpu != &current->thread.fpu);
193 196
194 preempt_disable(); 197 preempt_disable();
198 trace_x86_fpu_before_save(fpu);
195 if (fpu->fpregs_active) { 199 if (fpu->fpregs_active) {
196 if (!copy_fpregs_to_fpstate(fpu)) { 200 if (!copy_fpregs_to_fpstate(fpu)) {
197 if (use_eager_fpu()) 201 if (use_eager_fpu())
@@ -200,6 +204,7 @@ void fpu__save(struct fpu *fpu)
200 fpregs_deactivate(fpu); 204 fpregs_deactivate(fpu);
201 } 205 }
202 } 206 }
207 trace_x86_fpu_after_save(fpu);
203 preempt_enable(); 208 preempt_enable();
204} 209}
205EXPORT_SYMBOL_GPL(fpu__save); 210EXPORT_SYMBOL_GPL(fpu__save);
@@ -222,7 +227,7 @@ void fpstate_init(union fpregs_state *state)
222 return; 227 return;
223 } 228 }
224 229
225 memset(state, 0, xstate_size); 230 memset(state, 0, fpu_kernel_xstate_size);
226 231
227 if (static_cpu_has(X86_FEATURE_FXSR)) 232 if (static_cpu_has(X86_FEATURE_FXSR))
228 fpstate_init_fxstate(&state->fxsave); 233 fpstate_init_fxstate(&state->fxsave);
@@ -247,7 +252,7 @@ int fpu__copy(struct fpu *dst_fpu, struct fpu *src_fpu)
247 * leak into the child task: 252 * leak into the child task:
248 */ 253 */
249 if (use_eager_fpu()) 254 if (use_eager_fpu())
250 memset(&dst_fpu->state.xsave, 0, xstate_size); 255 memset(&dst_fpu->state.xsave, 0, fpu_kernel_xstate_size);
251 256
252 /* 257 /*
253 * Save current FPU registers directly into the child 258 * Save current FPU registers directly into the child
@@ -266,7 +271,8 @@ int fpu__copy(struct fpu *dst_fpu, struct fpu *src_fpu)
266 */ 271 */
267 preempt_disable(); 272 preempt_disable();
268 if (!copy_fpregs_to_fpstate(dst_fpu)) { 273 if (!copy_fpregs_to_fpstate(dst_fpu)) {
269 memcpy(&src_fpu->state, &dst_fpu->state, xstate_size); 274 memcpy(&src_fpu->state, &dst_fpu->state,
275 fpu_kernel_xstate_size);
270 276
271 if (use_eager_fpu()) 277 if (use_eager_fpu())
272 copy_kernel_to_fpregs(&src_fpu->state); 278 copy_kernel_to_fpregs(&src_fpu->state);
@@ -275,6 +281,9 @@ int fpu__copy(struct fpu *dst_fpu, struct fpu *src_fpu)
275 } 281 }
276 preempt_enable(); 282 preempt_enable();
277 283
284 trace_x86_fpu_copy_src(src_fpu);
285 trace_x86_fpu_copy_dst(dst_fpu);
286
278 return 0; 287 return 0;
279} 288}
280 289
@@ -288,7 +297,9 @@ void fpu__activate_curr(struct fpu *fpu)
288 297
289 if (!fpu->fpstate_active) { 298 if (!fpu->fpstate_active) {
290 fpstate_init(&fpu->state); 299 fpstate_init(&fpu->state);
300 trace_x86_fpu_init_state(fpu);
291 301
302 trace_x86_fpu_activate_state(fpu);
292 /* Safe to do for the current task: */ 303 /* Safe to do for the current task: */
293 fpu->fpstate_active = 1; 304 fpu->fpstate_active = 1;
294 } 305 }
@@ -314,7 +325,9 @@ void fpu__activate_fpstate_read(struct fpu *fpu)
314 } else { 325 } else {
315 if (!fpu->fpstate_active) { 326 if (!fpu->fpstate_active) {
316 fpstate_init(&fpu->state); 327 fpstate_init(&fpu->state);
328 trace_x86_fpu_init_state(fpu);
317 329
330 trace_x86_fpu_activate_state(fpu);
318 /* Safe to do for current and for stopped child tasks: */ 331 /* Safe to do for current and for stopped child tasks: */
319 fpu->fpstate_active = 1; 332 fpu->fpstate_active = 1;
320 } 333 }
@@ -347,7 +360,9 @@ void fpu__activate_fpstate_write(struct fpu *fpu)
347 fpu->last_cpu = -1; 360 fpu->last_cpu = -1;
348 } else { 361 } else {
349 fpstate_init(&fpu->state); 362 fpstate_init(&fpu->state);
363 trace_x86_fpu_init_state(fpu);
350 364
365 trace_x86_fpu_activate_state(fpu);
351 /* Safe to do for stopped child tasks: */ 366 /* Safe to do for stopped child tasks: */
352 fpu->fpstate_active = 1; 367 fpu->fpstate_active = 1;
353 } 368 }
@@ -432,9 +447,11 @@ void fpu__restore(struct fpu *fpu)
432 447
433 /* Avoid __kernel_fpu_begin() right after fpregs_activate() */ 448 /* Avoid __kernel_fpu_begin() right after fpregs_activate() */
434 kernel_fpu_disable(); 449 kernel_fpu_disable();
450 trace_x86_fpu_before_restore(fpu);
435 fpregs_activate(fpu); 451 fpregs_activate(fpu);
436 copy_kernel_to_fpregs(&fpu->state); 452 copy_kernel_to_fpregs(&fpu->state);
437 fpu->counter++; 453 fpu->counter++;
454 trace_x86_fpu_after_restore(fpu);
438 kernel_fpu_enable(); 455 kernel_fpu_enable();
439} 456}
440EXPORT_SYMBOL_GPL(fpu__restore); 457EXPORT_SYMBOL_GPL(fpu__restore);
@@ -463,6 +480,8 @@ void fpu__drop(struct fpu *fpu)
463 480
464 fpu->fpstate_active = 0; 481 fpu->fpstate_active = 0;
465 482
483 trace_x86_fpu_dropped(fpu);
484
466 preempt_enable(); 485 preempt_enable();
467} 486}
468 487
diff --git a/arch/x86/kernel/fpu/init.c b/arch/x86/kernel/fpu/init.c
index aacfd7a82cec..60f3839c5bfa 100644
--- a/arch/x86/kernel/fpu/init.c
+++ b/arch/x86/kernel/fpu/init.c
@@ -145,8 +145,8 @@ static void __init fpu__init_system_generic(void)
145 * This is inherent to the XSAVE architecture which puts all state 145 * This is inherent to the XSAVE architecture which puts all state
146 * components into a single, continuous memory block: 146 * components into a single, continuous memory block:
147 */ 147 */
148unsigned int xstate_size; 148unsigned int fpu_kernel_xstate_size;
149EXPORT_SYMBOL_GPL(xstate_size); 149EXPORT_SYMBOL_GPL(fpu_kernel_xstate_size);
150 150
151/* Get alignment of the TYPE. */ 151/* Get alignment of the TYPE. */
152#define TYPE_ALIGN(TYPE) offsetof(struct { char x; TYPE test; }, test) 152#define TYPE_ALIGN(TYPE) offsetof(struct { char x; TYPE test; }, test)
@@ -178,7 +178,7 @@ static void __init fpu__init_task_struct_size(void)
178 * Add back the dynamically-calculated register state 178 * Add back the dynamically-calculated register state
179 * size. 179 * size.
180 */ 180 */
181 task_size += xstate_size; 181 task_size += fpu_kernel_xstate_size;
182 182
183 /* 183 /*
184 * We dynamically size 'struct fpu', so we require that 184 * We dynamically size 'struct fpu', so we require that
@@ -195,7 +195,7 @@ static void __init fpu__init_task_struct_size(void)
195} 195}
196 196
197/* 197/*
198 * Set up the xstate_size based on the legacy FPU context size. 198 * Set up the user and kernel xstate sizes based on the legacy FPU context size.
199 * 199 *
200 * We set this up first, and later it will be overwritten by 200 * We set this up first, and later it will be overwritten by
201 * fpu__init_system_xstate() if the CPU knows about xstates. 201 * fpu__init_system_xstate() if the CPU knows about xstates.
@@ -208,7 +208,7 @@ static void __init fpu__init_system_xstate_size_legacy(void)
208 on_boot_cpu = 0; 208 on_boot_cpu = 0;
209 209
210 /* 210 /*
211 * Note that xstate_size might be overwriten later during 211 * Note that xstate sizes might be overwritten later during
212 * fpu__init_system_xstate(). 212 * fpu__init_system_xstate().
213 */ 213 */
214 214
@@ -219,13 +219,18 @@ static void __init fpu__init_system_xstate_size_legacy(void)
219 */ 219 */
220 setup_clear_cpu_cap(X86_FEATURE_XSAVE); 220 setup_clear_cpu_cap(X86_FEATURE_XSAVE);
221 setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT); 221 setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT);
222 xstate_size = sizeof(struct swregs_state); 222 fpu_kernel_xstate_size = sizeof(struct swregs_state);
223 } else { 223 } else {
224 if (boot_cpu_has(X86_FEATURE_FXSR)) 224 if (boot_cpu_has(X86_FEATURE_FXSR))
225 xstate_size = sizeof(struct fxregs_state); 225 fpu_kernel_xstate_size =
226 sizeof(struct fxregs_state);
226 else 227 else
227 xstate_size = sizeof(struct fregs_state); 228 fpu_kernel_xstate_size =
229 sizeof(struct fregs_state);
228 } 230 }
231
232 fpu_user_xstate_size = fpu_kernel_xstate_size;
233
229 /* 234 /*
230 * Quirk: we don't yet handle the XSAVES* instructions 235 * Quirk: we don't yet handle the XSAVES* instructions
231 * correctly, as we don't correctly convert between 236 * correctly, as we don't correctly convert between
diff --git a/arch/x86/kernel/fpu/signal.c b/arch/x86/kernel/fpu/signal.c
index 31c6a60505e6..8aa96cbb5dfb 100644
--- a/arch/x86/kernel/fpu/signal.c
+++ b/arch/x86/kernel/fpu/signal.c
@@ -8,8 +8,10 @@
8#include <asm/fpu/internal.h> 8#include <asm/fpu/internal.h>
9#include <asm/fpu/signal.h> 9#include <asm/fpu/signal.h>
10#include <asm/fpu/regset.h> 10#include <asm/fpu/regset.h>
11#include <asm/fpu/xstate.h>
11 12
12#include <asm/sigframe.h> 13#include <asm/sigframe.h>
14#include <asm/trace/fpu.h>
13 15
14static struct _fpx_sw_bytes fx_sw_reserved, fx_sw_reserved_ia32; 16static struct _fpx_sw_bytes fx_sw_reserved, fx_sw_reserved_ia32;
15 17
@@ -31,7 +33,7 @@ static inline int check_for_xstate(struct fxregs_state __user *buf,
31 /* Check for the first magic field and other error scenarios. */ 33 /* Check for the first magic field and other error scenarios. */
32 if (fx_sw->magic1 != FP_XSTATE_MAGIC1 || 34 if (fx_sw->magic1 != FP_XSTATE_MAGIC1 ||
33 fx_sw->xstate_size < min_xstate_size || 35 fx_sw->xstate_size < min_xstate_size ||
34 fx_sw->xstate_size > xstate_size || 36 fx_sw->xstate_size > fpu_user_xstate_size ||
35 fx_sw->xstate_size > fx_sw->extended_size) 37 fx_sw->xstate_size > fx_sw->extended_size)
36 return -1; 38 return -1;
37 39
@@ -88,7 +90,8 @@ static inline int save_xstate_epilog(void __user *buf, int ia32_frame)
88 if (!use_xsave()) 90 if (!use_xsave())
89 return err; 91 return err;
90 92
91 err |= __put_user(FP_XSTATE_MAGIC2, (__u32 *)(buf + xstate_size)); 93 err |= __put_user(FP_XSTATE_MAGIC2,
94 (__u32 *)(buf + fpu_user_xstate_size));
92 95
93 /* 96 /*
94 * Read the xfeatures which we copied (directly from the cpu or 97 * Read the xfeatures which we copied (directly from the cpu or
@@ -125,7 +128,7 @@ static inline int copy_fpregs_to_sigframe(struct xregs_state __user *buf)
125 else 128 else
126 err = copy_fregs_to_user((struct fregs_state __user *) buf); 129 err = copy_fregs_to_user((struct fregs_state __user *) buf);
127 130
128 if (unlikely(err) && __clear_user(buf, xstate_size)) 131 if (unlikely(err) && __clear_user(buf, fpu_user_xstate_size))
129 err = -EFAULT; 132 err = -EFAULT;
130 return err; 133 return err;
131} 134}
@@ -167,7 +170,7 @@ int copy_fpstate_to_sigframe(void __user *buf, void __user *buf_fx, int size)
167 sizeof(struct user_i387_ia32_struct), NULL, 170 sizeof(struct user_i387_ia32_struct), NULL,
168 (struct _fpstate_32 __user *) buf) ? -1 : 1; 171 (struct _fpstate_32 __user *) buf) ? -1 : 1;
169 172
170 if (fpregs_active()) { 173 if (fpregs_active() || using_compacted_format()) {
171 /* Save the live register state to the user directly. */ 174 /* Save the live register state to the user directly. */
172 if (copy_fpregs_to_sigframe(buf_fx)) 175 if (copy_fpregs_to_sigframe(buf_fx))
173 return -1; 176 return -1;
@@ -175,8 +178,19 @@ int copy_fpstate_to_sigframe(void __user *buf, void __user *buf_fx, int size)
175 if (ia32_fxstate) 178 if (ia32_fxstate)
176 copy_fxregs_to_kernel(&tsk->thread.fpu); 179 copy_fxregs_to_kernel(&tsk->thread.fpu);
177 } else { 180 } else {
181 /*
182 * It is a *bug* if kernel uses compacted-format for xsave
183 * area and we copy it out directly to a signal frame. It
184 * should have been handled above by saving the registers
185 * directly.
186 */
187 if (boot_cpu_has(X86_FEATURE_XSAVES)) {
188 WARN_ONCE(1, "x86/fpu: saving compacted-format xsave area to a signal frame!\n");
189 return -1;
190 }
191
178 fpstate_sanitize_xstate(&tsk->thread.fpu); 192 fpstate_sanitize_xstate(&tsk->thread.fpu);
179 if (__copy_to_user(buf_fx, xsave, xstate_size)) 193 if (__copy_to_user(buf_fx, xsave, fpu_user_xstate_size))
180 return -1; 194 return -1;
181 } 195 }
182 196
@@ -250,7 +264,7 @@ static int __fpu__restore_sig(void __user *buf, void __user *buf_fx, int size)
250 int ia32_fxstate = (buf != buf_fx); 264 int ia32_fxstate = (buf != buf_fx);
251 struct task_struct *tsk = current; 265 struct task_struct *tsk = current;
252 struct fpu *fpu = &tsk->thread.fpu; 266 struct fpu *fpu = &tsk->thread.fpu;
253 int state_size = xstate_size; 267 int state_size = fpu_kernel_xstate_size;
254 u64 xfeatures = 0; 268 u64 xfeatures = 0;
255 int fx_only = 0; 269 int fx_only = 0;
256 270
@@ -282,6 +296,7 @@ static int __fpu__restore_sig(void __user *buf, void __user *buf_fx, int size)
282 */ 296 */
283 state_size = sizeof(struct fxregs_state); 297 state_size = sizeof(struct fxregs_state);
284 fx_only = 1; 298 fx_only = 1;
299 trace_x86_fpu_xstate_check_failed(fpu);
285 } else { 300 } else {
286 state_size = fx_sw_user.xstate_size; 301 state_size = fx_sw_user.xstate_size;
287 xfeatures = fx_sw_user.xfeatures; 302 xfeatures = fx_sw_user.xfeatures;
@@ -311,6 +326,7 @@ static int __fpu__restore_sig(void __user *buf, void __user *buf_fx, int size)
311 if (__copy_from_user(&fpu->state.xsave, buf_fx, state_size) || 326 if (__copy_from_user(&fpu->state.xsave, buf_fx, state_size) ||
312 __copy_from_user(&env, buf, sizeof(env))) { 327 __copy_from_user(&env, buf, sizeof(env))) {
313 fpstate_init(&fpu->state); 328 fpstate_init(&fpu->state);
329 trace_x86_fpu_init_state(fpu);
314 err = -1; 330 err = -1;
315 } else { 331 } else {
316 sanitize_restored_xstate(tsk, &env, xfeatures, fx_only); 332 sanitize_restored_xstate(tsk, &env, xfeatures, fx_only);
@@ -341,7 +357,8 @@ static int __fpu__restore_sig(void __user *buf, void __user *buf_fx, int size)
341 357
342static inline int xstate_sigframe_size(void) 358static inline int xstate_sigframe_size(void)
343{ 359{
344 return use_xsave() ? xstate_size + FP_XSTATE_MAGIC2_SIZE : xstate_size; 360 return use_xsave() ? fpu_user_xstate_size + FP_XSTATE_MAGIC2_SIZE :
361 fpu_user_xstate_size;
345} 362}
346 363
347/* 364/*
@@ -385,12 +402,12 @@ fpu__alloc_mathframe(unsigned long sp, int ia32_frame,
385 */ 402 */
386void fpu__init_prepare_fx_sw_frame(void) 403void fpu__init_prepare_fx_sw_frame(void)
387{ 404{
388 int size = xstate_size + FP_XSTATE_MAGIC2_SIZE; 405 int size = fpu_user_xstate_size + FP_XSTATE_MAGIC2_SIZE;
389 406
390 fx_sw_reserved.magic1 = FP_XSTATE_MAGIC1; 407 fx_sw_reserved.magic1 = FP_XSTATE_MAGIC1;
391 fx_sw_reserved.extended_size = size; 408 fx_sw_reserved.extended_size = size;
392 fx_sw_reserved.xfeatures = xfeatures_mask; 409 fx_sw_reserved.xfeatures = xfeatures_mask;
393 fx_sw_reserved.xstate_size = xstate_size; 410 fx_sw_reserved.xstate_size = fpu_user_xstate_size;
394 411
395 if (config_enabled(CONFIG_IA32_EMULATION) || 412 if (config_enabled(CONFIG_IA32_EMULATION) ||
396 config_enabled(CONFIG_X86_32)) { 413 config_enabled(CONFIG_X86_32)) {
diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c
index 4ea2a59483c7..0b01f003df8b 100644
--- a/arch/x86/kernel/fpu/xstate.c
+++ b/arch/x86/kernel/fpu/xstate.c
@@ -44,6 +44,13 @@ static unsigned int xstate_sizes[XFEATURE_MAX] = { [ 0 ... XFEATURE_MAX - 1] =
44static unsigned int xstate_comp_offsets[sizeof(xfeatures_mask)*8]; 44static unsigned int xstate_comp_offsets[sizeof(xfeatures_mask)*8];
45 45
46/* 46/*
47 * The XSAVE area of kernel can be in standard or compacted format;
48 * it is always in standard format for user mode. This is the user
49 * mode standard format size used for signal and ptrace frames.
50 */
51unsigned int fpu_user_xstate_size;
52
53/*
47 * Clear all of the X86_FEATURE_* bits that are unavailable 54 * Clear all of the X86_FEATURE_* bits that are unavailable
48 * when the CPU has no XSAVE support. 55 * when the CPU has no XSAVE support.
49 */ 56 */
@@ -171,7 +178,7 @@ void fpstate_sanitize_xstate(struct fpu *fpu)
171 */ 178 */
172 while (xfeatures) { 179 while (xfeatures) {
173 if (xfeatures & 0x1) { 180 if (xfeatures & 0x1) {
174 int offset = xstate_offsets[feature_bit]; 181 int offset = xstate_comp_offsets[feature_bit];
175 int size = xstate_sizes[feature_bit]; 182 int size = xstate_sizes[feature_bit];
176 183
177 memcpy((void *)fx + offset, 184 memcpy((void *)fx + offset,
@@ -322,13 +329,11 @@ static void __init setup_init_fpu_buf(void)
322 setup_xstate_features(); 329 setup_xstate_features();
323 print_xstate_features(); 330 print_xstate_features();
324 331
325 if (boot_cpu_has(X86_FEATURE_XSAVES)) { 332 if (boot_cpu_has(X86_FEATURE_XSAVES))
326 init_fpstate.xsave.header.xcomp_bv = (u64)1 << 63 | xfeatures_mask; 333 init_fpstate.xsave.header.xcomp_bv = (u64)1 << 63 | xfeatures_mask;
327 init_fpstate.xsave.header.xfeatures = xfeatures_mask;
328 }
329 334
330 /* 335 /*
331 * Init all the features state with header_bv being 0x0 336 * Init all the features state with header.xfeatures being 0x0
332 */ 337 */
333 copy_kernel_to_xregs_booting(&init_fpstate.xsave); 338 copy_kernel_to_xregs_booting(&init_fpstate.xsave);
334 339
@@ -415,7 +420,7 @@ static int xfeature_size(int xfeature_nr)
415 * that it is obvious which aspect of 'XSAVES' is being handled 420 * that it is obvious which aspect of 'XSAVES' is being handled
416 * by the calling code. 421 * by the calling code.
417 */ 422 */
418static int using_compacted_format(void) 423int using_compacted_format(void)
419{ 424{
420 return boot_cpu_has(X86_FEATURE_XSAVES); 425 return boot_cpu_has(X86_FEATURE_XSAVES);
421} 426}
@@ -530,11 +535,12 @@ static void do_extra_xstate_size_checks(void)
530 */ 535 */
531 paranoid_xstate_size += xfeature_size(i); 536 paranoid_xstate_size += xfeature_size(i);
532 } 537 }
533 XSTATE_WARN_ON(paranoid_xstate_size != xstate_size); 538 XSTATE_WARN_ON(paranoid_xstate_size != fpu_kernel_xstate_size);
534} 539}
535 540
541
536/* 542/*
537 * Calculate total size of enabled xstates in XCR0/xfeatures_mask. 543 * Get total size of enabled xstates in XCR0/xfeatures_mask.
538 * 544 *
539 * Note the SDM's wording here. "sub-function 0" only enumerates 545 * Note the SDM's wording here. "sub-function 0" only enumerates
540 * the size of the *user* states. If we use it to size a buffer 546 * the size of the *user* states. If we use it to size a buffer
@@ -544,34 +550,33 @@ static void do_extra_xstate_size_checks(void)
544 * Note that we do not currently set any bits on IA32_XSS so 550 * Note that we do not currently set any bits on IA32_XSS so
545 * 'XCR0 | IA32_XSS == XCR0' for now. 551 * 'XCR0 | IA32_XSS == XCR0' for now.
546 */ 552 */
547static unsigned int __init calculate_xstate_size(void) 553static unsigned int __init get_xsaves_size(void)
548{ 554{
549 unsigned int eax, ebx, ecx, edx; 555 unsigned int eax, ebx, ecx, edx;
550 unsigned int calculated_xstate_size; 556 /*
557 * - CPUID function 0DH, sub-function 1:
558 * EBX enumerates the size (in bytes) required by
559 * the XSAVES instruction for an XSAVE area
560 * containing all the state components
561 * corresponding to bits currently set in
562 * XCR0 | IA32_XSS.
563 */
564 cpuid_count(XSTATE_CPUID, 1, &eax, &ebx, &ecx, &edx);
565 return ebx;
566}
551 567
552 if (!boot_cpu_has(X86_FEATURE_XSAVES)) { 568static unsigned int __init get_xsave_size(void)
553 /* 569{
554 * - CPUID function 0DH, sub-function 0: 570 unsigned int eax, ebx, ecx, edx;
555 * EBX enumerates the size (in bytes) required by 571 /*
556 * the XSAVE instruction for an XSAVE area 572 * - CPUID function 0DH, sub-function 0:
557 * containing all the *user* state components 573 * EBX enumerates the size (in bytes) required by
558 * corresponding to bits currently set in XCR0. 574 * the XSAVE instruction for an XSAVE area
559 */ 575 * containing all the *user* state components
560 cpuid_count(XSTATE_CPUID, 0, &eax, &ebx, &ecx, &edx); 576 * corresponding to bits currently set in XCR0.
561 calculated_xstate_size = ebx; 577 */
562 } else { 578 cpuid_count(XSTATE_CPUID, 0, &eax, &ebx, &ecx, &edx);
563 /* 579 return ebx;
564 * - CPUID function 0DH, sub-function 1:
565 * EBX enumerates the size (in bytes) required by
566 * the XSAVES instruction for an XSAVE area
567 * containing all the state components
568 * corresponding to bits currently set in
569 * XCR0 | IA32_XSS.
570 */
571 cpuid_count(XSTATE_CPUID, 1, &eax, &ebx, &ecx, &edx);
572 calculated_xstate_size = ebx;
573 }
574 return calculated_xstate_size;
575} 580}
576 581
577/* 582/*
@@ -591,7 +596,15 @@ static bool is_supported_xstate_size(unsigned int test_xstate_size)
591static int init_xstate_size(void) 596static int init_xstate_size(void)
592{ 597{
593 /* Recompute the context size for enabled features: */ 598 /* Recompute the context size for enabled features: */
594 unsigned int possible_xstate_size = calculate_xstate_size(); 599 unsigned int possible_xstate_size;
600 unsigned int xsave_size;
601
602 xsave_size = get_xsave_size();
603
604 if (boot_cpu_has(X86_FEATURE_XSAVES))
605 possible_xstate_size = get_xsaves_size();
606 else
607 possible_xstate_size = xsave_size;
595 608
596 /* Ensure we have the space to store all enabled: */ 609 /* Ensure we have the space to store all enabled: */
597 if (!is_supported_xstate_size(possible_xstate_size)) 610 if (!is_supported_xstate_size(possible_xstate_size))
@@ -601,8 +614,13 @@ static int init_xstate_size(void)
601 * The size is OK, we are definitely going to use xsave, 614 * The size is OK, we are definitely going to use xsave,
602 * make it known to the world that we need more space. 615 * make it known to the world that we need more space.
603 */ 616 */
604 xstate_size = possible_xstate_size; 617 fpu_kernel_xstate_size = possible_xstate_size;
605 do_extra_xstate_size_checks(); 618 do_extra_xstate_size_checks();
619
620 /*
621 * User space is always in standard format.
622 */
623 fpu_user_xstate_size = xsave_size;
606 return 0; 624 return 0;
607} 625}
608 626
@@ -659,14 +677,14 @@ void __init fpu__init_system_xstate(void)
659 return; 677 return;
660 } 678 }
661 679
662 update_regset_xstate_info(xstate_size, xfeatures_mask); 680 update_regset_xstate_info(fpu_kernel_xstate_size, xfeatures_mask);
663 fpu__init_prepare_fx_sw_frame(); 681 fpu__init_prepare_fx_sw_frame();
664 setup_init_fpu_buf(); 682 setup_init_fpu_buf();
665 setup_xstate_comp(); 683 setup_xstate_comp();
666 684
667 pr_info("x86/fpu: Enabled xstate features 0x%llx, context size is %d bytes, using '%s' format.\n", 685 pr_info("x86/fpu: Enabled xstate features 0x%llx, context size is %d bytes, using '%s' format.\n",
668 xfeatures_mask, 686 xfeatures_mask,
669 xstate_size, 687 fpu_kernel_xstate_size,
670 boot_cpu_has(X86_FEATURE_XSAVES) ? "compacted" : "standard"); 688 boot_cpu_has(X86_FEATURE_XSAVES) ? "compacted" : "standard");
671} 689}
672 690