diff options
Diffstat (limited to 'arch/x86/kernel/fpu/init.c')
-rw-r--r-- | arch/x86/kernel/fpu/init.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/arch/x86/kernel/fpu/init.c b/arch/x86/kernel/fpu/init.c index 32826791e675..0b39173dd971 100644 --- a/arch/x86/kernel/fpu/init.c +++ b/arch/x86/kernel/fpu/init.c | |||
@@ -4,6 +4,8 @@ | |||
4 | #include <asm/fpu/internal.h> | 4 | #include <asm/fpu/internal.h> |
5 | #include <asm/tlbflush.h> | 5 | #include <asm/tlbflush.h> |
6 | 6 | ||
7 | #include <linux/sched.h> | ||
8 | |||
7 | /* | 9 | /* |
8 | * Initialize the TS bit in CR0 according to the style of context-switches | 10 | * Initialize the TS bit in CR0 according to the style of context-switches |
9 | * we are using: | 11 | * we are using: |
@@ -136,6 +138,43 @@ static void __init fpu__init_system_generic(void) | |||
136 | unsigned int xstate_size; | 138 | unsigned int xstate_size; |
137 | EXPORT_SYMBOL_GPL(xstate_size); | 139 | EXPORT_SYMBOL_GPL(xstate_size); |
138 | 140 | ||
141 | /* Enforce that 'MEMBER' is the last field of 'TYPE': */ | ||
142 | #define CHECK_MEMBER_AT_END_OF(TYPE, MEMBER) \ | ||
143 | BUILD_BUG_ON(sizeof(TYPE) != offsetofend(TYPE, MEMBER)) | ||
144 | |||
145 | /* | ||
146 | * We append the 'struct fpu' to the task_struct: | ||
147 | */ | ||
148 | static void __init fpu__init_task_struct_size(void) | ||
149 | { | ||
150 | int task_size = sizeof(struct task_struct); | ||
151 | |||
152 | /* | ||
153 | * Subtract off the static size of the register state. | ||
154 | * It potentially has a bunch of padding. | ||
155 | */ | ||
156 | task_size -= sizeof(((struct task_struct *)0)->thread.fpu.state); | ||
157 | |||
158 | /* | ||
159 | * Add back the dynamically-calculated register state | ||
160 | * size. | ||
161 | */ | ||
162 | task_size += xstate_size; | ||
163 | |||
164 | /* | ||
165 | * We dynamically size 'struct fpu', so we require that | ||
166 | * it be at the end of 'thread_struct' and that | ||
167 | * 'thread_struct' be at the end of 'task_struct'. If | ||
168 | * you hit a compile error here, check the structure to | ||
169 | * see if something got added to the end. | ||
170 | */ | ||
171 | CHECK_MEMBER_AT_END_OF(struct fpu, state); | ||
172 | CHECK_MEMBER_AT_END_OF(struct thread_struct, fpu); | ||
173 | CHECK_MEMBER_AT_END_OF(struct task_struct, thread); | ||
174 | |||
175 | arch_task_struct_size = task_size; | ||
176 | } | ||
177 | |||
139 | /* | 178 | /* |
140 | * Set up the xstate_size based on the legacy FPU context size. | 179 | * Set up the xstate_size based on the legacy FPU context size. |
141 | * | 180 | * |
@@ -287,6 +326,7 @@ void __init fpu__init_system(struct cpuinfo_x86 *c) | |||
287 | fpu__init_system_generic(); | 326 | fpu__init_system_generic(); |
288 | fpu__init_system_xstate_size_legacy(); | 327 | fpu__init_system_xstate_size_legacy(); |
289 | fpu__init_system_xstate(); | 328 | fpu__init_system_xstate(); |
329 | fpu__init_task_struct_size(); | ||
290 | 330 | ||
291 | fpu__init_system_ctx_switch(); | 331 | fpu__init_system_ctx_switch(); |
292 | } | 332 | } |