diff options
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/kernel/xsave.c | 29 |
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; | |||
21 | struct _fpx_sw_bytes fx_sw_reserved_ia32; | 21 | struct _fpx_sw_bytes fx_sw_reserved_ia32; |
22 | #endif | 22 | #endif |
23 | 23 | ||
24 | static 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 | */ | ||
310 | static 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 | */ |
307 | static void __init setup_xstate_init(void) | 334 | static 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 | /* |