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 | ||
20 | /* | |
21 | * Enable the extended processor state save/restore feature | |
22 | */ | |
23 | void __cpuinit xsave_init(void) | |
24 | { | |
25 | if (!cpu_has_xsave) | |
26 | return; | |
27 | ||
28 | set_in_cr4(X86_CR4_OSXSAVE); | |
29 | ||
30 | /* | |
31 | * Enable all the features that the HW is capable of | |
32 | * and the Linux kernel is aware of. | |
33 | * | |
34 | * xsetbv(); | |
35 | */ | |
36 | asm volatile(".byte 0x0f,0x01,0xd1" : : "c" (0), | |
37 | "a" (pcntxt_lmask), "d" (pcntxt_hmask)); | |
38 | } | |
39 | ||
40 | /* | |
41 | * setup the xstate image representing the init state | |
42 | */ | |
43 | void setup_xstate_init(void) | |
44 | { | |
45 | init_xstate_buf = alloc_bootmem(xstate_size); | |
46 | init_xstate_buf->i387.mxcsr = MXCSR_DEFAULT; | |
47 | } | |
48 | ||
49 | /* | |
50 | * Enable and initialize the xsave feature. | |
51 | */ | |
52 | void __init xsave_cntxt_init(void) | |
53 | { | |
54 | unsigned int eax, ebx, ecx, edx; | |
55 | ||
56 | cpuid_count(0xd, 0, &eax, &ebx, &ecx, &edx); | |
57 | ||
58 | pcntxt_lmask = eax; | |
59 | pcntxt_hmask = edx; | |
60 | ||
61 | if ((pcntxt_lmask & XSTATE_FPSSE) != XSTATE_FPSSE) { | |
62 | printk(KERN_ERR "FP/SSE not shown under xsave features %x\n", | |
63 | pcntxt_lmask); | |
64 | BUG(); | |
65 | } | |
66 | ||
67 | /* | |
68 | * for now OS knows only about FP/SSE | |
69 | */ | |
70 | pcntxt_lmask = pcntxt_lmask & XCNTXT_LMASK; | |
71 | pcntxt_hmask = pcntxt_hmask & XCNTXT_HMASK; | |
72 | ||
73 | xsave_init(); | |
74 | ||
75 | /* | |
76 | * Recompute the context size for enabled features | |
77 | */ | |
78 | cpuid_count(0xd, 0, &eax, &ebx, &ecx, &edx); | |
79 | ||
80 | xstate_size = ebx; | |
81 | ||
82 | setup_xstate_init(); | |
83 | ||
84 | printk(KERN_INFO "xsave/xrstor: enabled xstate_bv 0x%Lx, " | |
85 | "cntxt size 0x%x\n", | |
86 | (pcntxt_lmask | ((u64) pcntxt_hmask << 32)), xstate_size); | |
87 | } |