diff options
-rw-r--r-- | arch/x86/include/asm/i387.h | 1 | ||||
-rw-r--r-- | arch/x86/include/asm/xsave.h | 1 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/common.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/i387.c | 27 | ||||
-rw-r--r-- | arch/x86/kernel/xsave.c | 10 |
5 files changed, 26 insertions, 15 deletions
diff --git a/arch/x86/include/asm/i387.h b/arch/x86/include/asm/i387.h index 59bd93ac7fef..509ddabeae25 100644 --- a/arch/x86/include/asm/i387.h +++ b/arch/x86/include/asm/i387.h | |||
@@ -31,7 +31,6 @@ extern void mxcsr_feature_mask_init(void); | |||
31 | extern int init_fpu(struct task_struct *child); | 31 | extern int init_fpu(struct task_struct *child); |
32 | extern asmlinkage void math_state_restore(void); | 32 | extern asmlinkage void math_state_restore(void); |
33 | extern void __math_state_restore(void); | 33 | extern void __math_state_restore(void); |
34 | extern void init_thread_xstate(void); | ||
35 | extern int dump_fpu(struct pt_regs *, struct user_i387_struct *); | 34 | extern int dump_fpu(struct pt_regs *, struct user_i387_struct *); |
36 | 35 | ||
37 | extern user_regset_active_fn fpregs_active, xfpregs_active; | 36 | extern user_regset_active_fn fpregs_active, xfpregs_active; |
diff --git a/arch/x86/include/asm/xsave.h b/arch/x86/include/asm/xsave.h index 94d5f84d89f2..4d3b5d1fc028 100644 --- a/arch/x86/include/asm/xsave.h +++ b/arch/x86/include/asm/xsave.h | |||
@@ -28,7 +28,6 @@ extern u64 pcntxt_mask; | |||
28 | extern struct xsave_struct *init_xstate_buf; | 28 | extern struct xsave_struct *init_xstate_buf; |
29 | extern u64 xstate_fx_sw_bytes[USER_XSTATE_FX_SW_WORDS]; | 29 | extern u64 xstate_fx_sw_bytes[USER_XSTATE_FX_SW_WORDS]; |
30 | 30 | ||
31 | extern void xsave_cntxt_init(void); | ||
32 | extern void xsave_init(void); | 31 | extern void xsave_init(void); |
33 | extern void update_regset_xstate_info(unsigned int size, u64 xstate_mask); | 32 | extern void update_regset_xstate_info(unsigned int size, u64 xstate_mask); |
34 | extern int init_fpu(struct task_struct *child); | 33 | extern int init_fpu(struct task_struct *child); |
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 40561085d4f3..94c36c7ac183 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
@@ -1210,6 +1210,7 @@ void __cpuinit cpu_init(void) | |||
1210 | dbg_restore_debug_regs(); | 1210 | dbg_restore_debug_regs(); |
1211 | 1211 | ||
1212 | fpu_init(); | 1212 | fpu_init(); |
1213 | xsave_init(); | ||
1213 | 1214 | ||
1214 | raw_local_save_flags(kernel_eflags); | 1215 | raw_local_save_flags(kernel_eflags); |
1215 | 1216 | ||
@@ -1270,6 +1271,7 @@ void __cpuinit cpu_init(void) | |||
1270 | clear_used_math(); | 1271 | clear_used_math(); |
1271 | mxcsr_feature_mask_init(); | 1272 | mxcsr_feature_mask_init(); |
1272 | 1273 | ||
1274 | fpu_init(); | ||
1273 | xsave_init(); | 1275 | xsave_init(); |
1274 | } | 1276 | } |
1275 | #endif | 1277 | #endif |
diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c index 2f32ef05f10e..e73c54ebafce 100644 --- a/arch/x86/kernel/i387.c +++ b/arch/x86/kernel/i387.c | |||
@@ -59,18 +59,18 @@ void __cpuinit mxcsr_feature_mask_init(void) | |||
59 | stts(); | 59 | stts(); |
60 | } | 60 | } |
61 | 61 | ||
62 | void __cpuinit init_thread_xstate(void) | 62 | static void __cpuinit init_thread_xstate(void) |
63 | { | 63 | { |
64 | /* | ||
65 | * Note that xstate_size might be overwriten later during | ||
66 | * xsave_init(). | ||
67 | */ | ||
68 | |||
64 | if (!HAVE_HWFP) { | 69 | if (!HAVE_HWFP) { |
65 | xstate_size = sizeof(struct i387_soft_struct); | 70 | xstate_size = sizeof(struct i387_soft_struct); |
66 | return; | 71 | return; |
67 | } | 72 | } |
68 | 73 | ||
69 | if (cpu_has_xsave) { | ||
70 | xsave_cntxt_init(); | ||
71 | return; | ||
72 | } | ||
73 | |||
74 | if (cpu_has_fxsr) | 74 | if (cpu_has_fxsr) |
75 | xstate_size = sizeof(struct i387_fxsave_struct); | 75 | xstate_size = sizeof(struct i387_fxsave_struct); |
76 | #ifdef CONFIG_X86_32 | 76 | #ifdef CONFIG_X86_32 |
@@ -84,6 +84,7 @@ void __cpuinit init_thread_xstate(void) | |||
84 | * Called at bootup to set up the initial FPU state that is later cloned | 84 | * Called at bootup to set up the initial FPU state that is later cloned |
85 | * into all processes. | 85 | * into all processes. |
86 | */ | 86 | */ |
87 | |||
87 | void __cpuinit fpu_init(void) | 88 | void __cpuinit fpu_init(void) |
88 | { | 89 | { |
89 | unsigned long oldcr0 = read_cr0(); | 90 | unsigned long oldcr0 = read_cr0(); |
@@ -93,14 +94,24 @@ void __cpuinit fpu_init(void) | |||
93 | 94 | ||
94 | write_cr0(oldcr0 & ~(X86_CR0_TS|X86_CR0_EM)); /* clear TS and EM */ | 95 | write_cr0(oldcr0 & ~(X86_CR0_TS|X86_CR0_EM)); /* clear TS and EM */ |
95 | 96 | ||
96 | xsave_init(); | 97 | if (!smp_processor_id()) |
98 | init_thread_xstate(); | ||
97 | 99 | ||
98 | mxcsr_feature_mask_init(); | 100 | mxcsr_feature_mask_init(); |
99 | /* clean state in init */ | 101 | /* clean state in init */ |
100 | current_thread_info()->status = 0; | 102 | current_thread_info()->status = 0; |
101 | clear_used_math(); | 103 | clear_used_math(); |
102 | } | 104 | } |
103 | #endif /* CONFIG_X86_64 */ | 105 | |
106 | #else /* CONFIG_X86_64 */ | ||
107 | |||
108 | void __cpuinit fpu_init(void) | ||
109 | { | ||
110 | if (!smp_processor_id()) | ||
111 | init_thread_xstate(); | ||
112 | } | ||
113 | |||
114 | #endif /* CONFIG_X86_32 */ | ||
104 | 115 | ||
105 | static void fpu_finit(struct fpu *fpu) | 116 | static void fpu_finit(struct fpu *fpu) |
106 | { | 117 | { |
diff --git a/arch/x86/kernel/xsave.c b/arch/x86/kernel/xsave.c index ab9ad48b6530..550bf45236f4 100644 --- a/arch/x86/kernel/xsave.c +++ b/arch/x86/kernel/xsave.c | |||
@@ -362,9 +362,6 @@ unsigned int sig_xstate_size = sizeof(struct _fpstate); | |||
362 | */ | 362 | */ |
363 | static void __cpuinit __xsave_init(void) | 363 | static void __cpuinit __xsave_init(void) |
364 | { | 364 | { |
365 | if (!cpu_has_xsave) | ||
366 | return; | ||
367 | |||
368 | set_in_cr4(X86_CR4_OSXSAVE); | 365 | set_in_cr4(X86_CR4_OSXSAVE); |
369 | 366 | ||
370 | /* | 367 | /* |
@@ -429,7 +426,7 @@ static void __init setup_xstate_init(void) | |||
429 | /* | 426 | /* |
430 | * Enable and initialize the xsave feature. | 427 | * Enable and initialize the xsave feature. |
431 | */ | 428 | */ |
432 | void __ref xsave_cntxt_init(void) | 429 | static void __cpuinit xsave_cntxt_init(void) |
433 | { | 430 | { |
434 | unsigned int eax, ebx, ecx, edx; | 431 | unsigned int eax, ebx, ecx, edx; |
435 | 432 | ||
@@ -466,10 +463,13 @@ void __ref xsave_cntxt_init(void) | |||
466 | 463 | ||
467 | void __cpuinit xsave_init(void) | 464 | void __cpuinit xsave_init(void) |
468 | { | 465 | { |
466 | if (!cpu_has_xsave) | ||
467 | return; | ||
468 | |||
469 | /* | 469 | /* |
470 | * Boot processor to setup the FP and extended state context info. | 470 | * Boot processor to setup the FP and extended state context info. |
471 | */ | 471 | */ |
472 | if (!smp_processor_id()) | 472 | if (!smp_processor_id()) |
473 | init_thread_xstate(); | 473 | xsave_cntxt_init(); |
474 | __xsave_init(); | 474 | __xsave_init(); |
475 | } | 475 | } |