]>
Commit | Line | Data |
---|---|---|
dc1e35c6 SS |
1 | /* |
2 | * xsave/xrstor support. | |
3 | * | |
4 | * Author: Suresh Siddha <suresh.b.siddha@intel.com> | |
5 | */ | |
6 | #include <linux/bootmem.h> | |
7 | #include <linux/compat.h> | |
8 | #include <asm/i387.h> | |
9 | ||
10 | /* | |
11 | * Supported feature mask by the CPU and the kernel. | |
12 | */ | |
13 | unsigned int pcntxt_hmask, pcntxt_lmask; | |
14 | ||
15 | /* | |
16 | * Represents init state for the supported extended state. | |
17 | */ | |
18 | struct xsave_struct *init_xstate_buf; | |
19 | ||
3c1c7f10 SS |
20 | #ifdef CONFIG_X86_64 |
21 | unsigned int sig_xstate_size = sizeof(struct _fpstate); | |
22 | #endif | |
23 | ||
dc1e35c6 SS |
24 | /* |
25 | * Enable the extended processor state save/restore feature | |
26 | */ | |
27 | void __cpuinit xsave_init(void) | |
28 | { | |
29 | if (!cpu_has_xsave) | |
30 | return; | |
31 | ||
32 | set_in_cr4(X86_CR4_OSXSAVE); | |
33 | ||
34 | /* | |
35 | * Enable all the features that the HW is capable of | |
36 | * and the Linux kernel is aware of. | |
37 | * | |
38 | * xsetbv(); | |
39 | */ | |
40 | asm volatile(".byte 0x0f,0x01,0xd1" : : "c" (0), | |
41 | "a" (pcntxt_lmask), "d" (pcntxt_hmask)); | |
42 | } | |
43 | ||
44 | /* | |
45 | * setup the xstate image representing the init state | |
46 | */ | |
47 | void setup_xstate_init(void) | |
48 | { | |
49 | init_xstate_buf = alloc_bootmem(xstate_size); | |
50 | init_xstate_buf->i387.mxcsr = MXCSR_DEFAULT; | |
51 | } | |
52 | ||
53 | /* | |
54 | * Enable and initialize the xsave feature. | |
55 | */ | |
56 | void __init xsave_cntxt_init(void) | |
57 | { | |
58 | unsigned int eax, ebx, ecx, edx; | |
59 | ||
60 | cpuid_count(0xd, 0, &eax, &ebx, &ecx, &edx); | |
61 | ||
62 | pcntxt_lmask = eax; | |
63 | pcntxt_hmask = edx; | |
64 | ||
65 | if ((pcntxt_lmask & XSTATE_FPSSE) != XSTATE_FPSSE) { | |
66 | printk(KERN_ERR "FP/SSE not shown under xsave features %x\n", | |
67 | pcntxt_lmask); | |
68 | BUG(); | |
69 | } | |
70 | ||
71 | /* | |
72 | * for now OS knows only about FP/SSE | |
73 | */ | |
74 | pcntxt_lmask = pcntxt_lmask & XCNTXT_LMASK; | |
75 | pcntxt_hmask = pcntxt_hmask & XCNTXT_HMASK; | |
76 | ||
77 | xsave_init(); | |
78 | ||
79 | /* | |
80 | * Recompute the context size for enabled features | |
81 | */ | |
82 | cpuid_count(0xd, 0, &eax, &ebx, &ecx, &edx); | |
83 | ||
84 | xstate_size = ebx; | |
85 | ||
86 | setup_xstate_init(); | |
87 | ||
88 | printk(KERN_INFO "xsave/xrstor: enabled xstate_bv 0x%Lx, " | |
89 | "cntxt size 0x%x\n", | |
90 | (pcntxt_lmask | ((u64) pcntxt_hmask << 32)), xstate_size); | |
91 | } |