aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorRobert Richter <robert.richter@amd.com>2010-07-21 13:03:52 -0400
committerH. Peter Anvin <hpa@linux.intel.com>2010-07-21 17:06:04 -0400
commit0e49bf66d2ca649b167428adddbbbe9d9bd4894c (patch)
tree741f170dbb160ece127b2ab497f9fc9d1e3bd1bc /arch
parent82d4150cec83b9775f84810b39a1c0b91585d429 (diff)
x86, xsave: Separate fpu and xsave initialization
As xsave also supports other than fpu features, it should be initialized independently of the fpu. This patch moves this out of fpu initialization. There is also a lot of cross referencing between fpu and xsave code. This patch reduces this by making xsave_cntxt_init() and init_thread_xstate() static functions. The patch moves the cpu_has_xsave check at the beginning of xsave_init(). All other checks may removed then. Signed-off-by: Robert Richter <robert.richter@amd.com> LKML-Reference: <1279731838-1522-2-git-send-email-robert.richter@amd.com> Acked-by: Suresh Siddha <suresh.b.siddha@intel.com> Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/include/asm/i387.h1
-rw-r--r--arch/x86/include/asm/xsave.h1
-rw-r--r--arch/x86/kernel/cpu/common.c2
-rw-r--r--arch/x86/kernel/i387.c27
-rw-r--r--arch/x86/kernel/xsave.c10
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);
31extern int init_fpu(struct task_struct *child); 31extern int init_fpu(struct task_struct *child);
32extern asmlinkage void math_state_restore(void); 32extern asmlinkage void math_state_restore(void);
33extern void __math_state_restore(void); 33extern void __math_state_restore(void);
34extern void init_thread_xstate(void);
35extern int dump_fpu(struct pt_regs *, struct user_i387_struct *); 34extern int dump_fpu(struct pt_regs *, struct user_i387_struct *);
36 35
37extern user_regset_active_fn fpregs_active, xfpregs_active; 36extern 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;
28extern struct xsave_struct *init_xstate_buf; 28extern struct xsave_struct *init_xstate_buf;
29extern u64 xstate_fx_sw_bytes[USER_XSTATE_FX_SW_WORDS]; 29extern u64 xstate_fx_sw_bytes[USER_XSTATE_FX_SW_WORDS];
30 30
31extern void xsave_cntxt_init(void);
32extern void xsave_init(void); 31extern void xsave_init(void);
33extern void update_regset_xstate_info(unsigned int size, u64 xstate_mask); 32extern void update_regset_xstate_info(unsigned int size, u64 xstate_mask);
34extern int init_fpu(struct task_struct *child); 33extern 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
62void __cpuinit init_thread_xstate(void) 62static 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
87void __cpuinit fpu_init(void) 88void __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
108void __cpuinit fpu_init(void)
109{
110 if (!smp_processor_id())
111 init_thread_xstate();
112}
113
114#endif /* CONFIG_X86_32 */
104 115
105static void fpu_finit(struct fpu *fpu) 116static 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 */
363static void __cpuinit __xsave_init(void) 363static 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 */
432void __ref xsave_cntxt_init(void) 429static 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
467void __cpuinit xsave_init(void) 464void __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}