aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/xsave.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/xsave.c')
-rw-r--r--arch/x86/kernel/xsave.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/arch/x86/kernel/xsave.c b/arch/x86/kernel/xsave.c
index 980149867a19..4993caa4181c 100644
--- a/arch/x86/kernel/xsave.c
+++ b/arch/x86/kernel/xsave.c
@@ -21,6 +21,8 @@ struct _fpx_sw_bytes fx_sw_reserved;
21struct _fpx_sw_bytes fx_sw_reserved_ia32; 21struct _fpx_sw_bytes fx_sw_reserved_ia32;
22#endif 22#endif
23 23
24static unsigned int *xstate_offsets, *xstate_sizes, xstate_features;
25
24/* 26/*
25 * Check for the presence of extended state information in the 27 * Check for the presence of extended state information in the
26 * user fpstate pointer in the sigcontext. 28 * user fpstate pointer in the sigcontext.
@@ -302,12 +304,39 @@ void __cpuinit xsave_init(void)
302} 304}
303 305
304/* 306/*
307 * Record the offsets and sizes of different state managed by the xsave
308 * memory layout.
309 */
310static void setup_xstate_features(void)
311{
312 int eax, ebx, ecx, edx, leaf = 0x2;
313
314 xstate_features = fls64(pcntxt_mask);
315 xstate_offsets = alloc_bootmem(xstate_features * sizeof(int));
316 xstate_sizes = alloc_bootmem(xstate_features * sizeof(int));
317
318 do {
319 cpuid_count(0xd, leaf, &eax, &ebx, &ecx, &edx);
320
321 if (eax == 0)
322 break;
323
324 xstate_offsets[leaf] = ebx;
325 xstate_sizes[leaf] = eax;
326
327 leaf++;
328 } while (1);
329}
330
331/*
305 * setup the xstate image representing the init state 332 * setup the xstate image representing the init state
306 */ 333 */
307static void __init setup_xstate_init(void) 334static void __init setup_xstate_init(void)
308{ 335{
309 init_xstate_buf = alloc_bootmem(xstate_size); 336 init_xstate_buf = alloc_bootmem(xstate_size);
310 init_xstate_buf->i387.mxcsr = MXCSR_DEFAULT; 337 init_xstate_buf->i387.mxcsr = MXCSR_DEFAULT;
338
339 setup_xstate_features();
311} 340}
312 341
313/* 342/*