Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0
2 : : #include <linux/tboot.h>
3 : :
4 : : #include <asm/cpufeature.h>
5 : : #include <asm/msr-index.h>
6 : : #include <asm/processor.h>
7 : : #include <asm/vmx.h>
8 : :
9 : : #undef pr_fmt
10 : : #define pr_fmt(fmt) "x86/cpu: " fmt
11 : :
12 : : #ifdef CONFIG_X86_VMX_FEATURE_NAMES
13 : : enum vmx_feature_leafs {
14 : : MISC_FEATURES = 0,
15 : : PRIMARY_CTLS,
16 : : SECONDARY_CTLS,
17 : : NR_VMX_FEATURE_WORDS,
18 : : };
19 : :
20 : : #define VMX_F(x) BIT(VMX_FEATURE_##x & 0x1f)
21 : :
22 : 0 : static void init_vmx_capabilities(struct cpuinfo_x86 *c)
23 : : {
24 : 0 : u32 supported, funcs, ept, vpid, ign;
25 : :
26 : 0 : BUILD_BUG_ON(NVMXINTS != NR_VMX_FEATURE_WORDS);
27 : :
28 : : /*
29 : : * The high bits contain the allowed-1 settings, i.e. features that can
30 : : * be turned on. The low bits contain the allowed-0 settings, i.e.
31 : : * features that can be turned off. Ignore the allowed-0 settings,
32 : : * if a feature can be turned on then it's supported.
33 : : *
34 : : * Use raw rdmsr() for primary processor controls and pin controls MSRs
35 : : * as they exist on any CPU that supports VMX, i.e. we want the WARN if
36 : : * the RDMSR faults.
37 : : */
38 : 0 : rdmsr(MSR_IA32_VMX_PROCBASED_CTLS, ign, supported);
39 : 0 : c->vmx_capability[PRIMARY_CTLS] = supported;
40 : :
41 : 0 : rdmsr_safe(MSR_IA32_VMX_PROCBASED_CTLS2, &ign, &supported);
42 : 0 : c->vmx_capability[SECONDARY_CTLS] = supported;
43 : :
44 : 0 : rdmsr(MSR_IA32_VMX_PINBASED_CTLS, ign, supported);
45 : 0 : rdmsr_safe(MSR_IA32_VMX_VMFUNC, &ign, &funcs);
46 : :
47 : : /*
48 : : * Except for EPT+VPID, which enumerates support for both in a single
49 : : * MSR, low for EPT, high for VPID.
50 : : */
51 : 0 : rdmsr_safe(MSR_IA32_VMX_EPT_VPID_CAP, &ept, &vpid);
52 : :
53 : : /* Pin, EPT, VPID and VM-Func are merged into a single word. */
54 [ # # ]: 0 : WARN_ON_ONCE(supported >> 16);
55 [ # # ]: 0 : WARN_ON_ONCE(funcs >> 4);
56 : 0 : c->vmx_capability[MISC_FEATURES] = (supported & 0xffff) |
57 : 0 : ((vpid & 0x1) << 16) |
58 : 0 : ((funcs & 0xf) << 28);
59 : :
60 : : /* EPT bits are full on scattered and must be manually handled. */
61 [ # # ]: 0 : if (ept & VMX_EPT_EXECUTE_ONLY_BIT)
62 : 0 : c->vmx_capability[MISC_FEATURES] |= VMX_F(EPT_EXECUTE_ONLY);
63 [ # # ]: 0 : if (ept & VMX_EPT_AD_BIT)
64 : 0 : c->vmx_capability[MISC_FEATURES] |= VMX_F(EPT_AD);
65 [ # # ]: 0 : if (ept & VMX_EPT_1GB_PAGE_BIT)
66 : 0 : c->vmx_capability[MISC_FEATURES] |= VMX_F(EPT_1GB);
67 : :
68 : : /* Synthetic APIC features that are aggregates of multiple features. */
69 [ # # ]: 0 : if ((c->vmx_capability[PRIMARY_CTLS] & VMX_F(VIRTUAL_TPR)) &&
70 [ # # ]: 0 : (c->vmx_capability[SECONDARY_CTLS] & VMX_F(VIRT_APIC_ACCESSES)))
71 : 0 : c->vmx_capability[MISC_FEATURES] |= VMX_F(FLEXPRIORITY);
72 : :
73 [ # # ]: 0 : if ((c->vmx_capability[PRIMARY_CTLS] & VMX_F(VIRTUAL_TPR)) &&
74 [ # # ]: 0 : (c->vmx_capability[SECONDARY_CTLS] & VMX_F(APIC_REGISTER_VIRT)) &&
75 : 0 : (c->vmx_capability[SECONDARY_CTLS] & VMX_F(VIRT_INTR_DELIVERY)) &&
76 [ # # ]: 0 : (c->vmx_capability[MISC_FEATURES] & VMX_F(POSTED_INTR)))
77 : 0 : c->vmx_capability[MISC_FEATURES] |= VMX_F(APICV);
78 : :
79 : : /* Set the synthetic cpufeatures to preserve /proc/cpuinfo's ABI. */
80 [ # # ]: 0 : if (c->vmx_capability[PRIMARY_CTLS] & VMX_F(VIRTUAL_TPR))
81 : 0 : set_cpu_cap(c, X86_FEATURE_TPR_SHADOW);
82 [ # # ]: 0 : if (c->vmx_capability[MISC_FEATURES] & VMX_F(FLEXPRIORITY))
83 : 0 : set_cpu_cap(c, X86_FEATURE_FLEXPRIORITY);
84 [ # # ]: 0 : if (c->vmx_capability[MISC_FEATURES] & VMX_F(VIRTUAL_NMIS))
85 : 0 : set_cpu_cap(c, X86_FEATURE_VNMI);
86 [ # # ]: 0 : if (c->vmx_capability[SECONDARY_CTLS] & VMX_F(EPT))
87 : 0 : set_cpu_cap(c, X86_FEATURE_EPT);
88 [ # # ]: 0 : if (c->vmx_capability[MISC_FEATURES] & VMX_F(EPT_AD))
89 : 0 : set_cpu_cap(c, X86_FEATURE_EPT_AD);
90 [ # # ]: 0 : if (c->vmx_capability[MISC_FEATURES] & VMX_F(VPID))
91 : 0 : set_cpu_cap(c, X86_FEATURE_VPID);
92 : 0 : }
93 : : #endif /* CONFIG_X86_VMX_FEATURE_NAMES */
94 : :
95 : 0 : void init_ia32_feat_ctl(struct cpuinfo_x86 *c)
96 : : {
97 : 0 : bool tboot = tboot_enabled();
98 : 0 : u64 msr;
99 : :
100 [ # # ]: 0 : if (rdmsrl_safe(MSR_IA32_FEAT_CTL, &msr)) {
101 : 0 : clear_cpu_cap(c, X86_FEATURE_VMX);
102 : 0 : return;
103 : : }
104 : :
105 [ # # ]: 0 : if (msr & FEAT_CTL_LOCKED)
106 : 0 : goto update_caps;
107 : :
108 : : /*
109 : : * Ignore whatever value BIOS left in the MSR to avoid enabling random
110 : : * features or faulting on the WRMSR.
111 : : */
112 : 0 : msr = FEAT_CTL_LOCKED;
113 : :
114 : : /*
115 : : * Enable VMX if and only if the kernel may do VMXON at some point,
116 : : * i.e. KVM is enabled, to avoid unnecessarily adding an attack vector
117 : : * for the kernel, e.g. using VMX to hide malicious code.
118 : : */
119 : 0 : if (cpu_has(c, X86_FEATURE_VMX) && IS_ENABLED(CONFIG_KVM_INTEL)) {
120 : : msr |= FEAT_CTL_VMX_ENABLED_OUTSIDE_SMX;
121 : :
122 : : if (tboot)
123 : : msr |= FEAT_CTL_VMX_ENABLED_INSIDE_SMX;
124 : : }
125 : :
126 : 0 : wrmsrl(MSR_IA32_FEAT_CTL, msr);
127 : :
128 : 0 : update_caps:
129 : 0 : set_cpu_cap(c, X86_FEATURE_MSR_IA32_FEAT_CTL);
130 : :
131 [ # # ]: 0 : if (!cpu_has(c, X86_FEATURE_VMX))
132 : : return;
133 : :
134 : 0 : if ( (tboot && !(msr & FEAT_CTL_VMX_ENABLED_INSIDE_SMX)) ||
135 [ # # ]: 0 : (!tboot && !(msr & FEAT_CTL_VMX_ENABLED_OUTSIDE_SMX))) {
136 : 0 : if (IS_ENABLED(CONFIG_KVM_INTEL))
137 : : pr_err_once("VMX (%s TXT) disabled by BIOS\n",
138 : : tboot ? "inside" : "outside");
139 : 0 : clear_cpu_cap(c, X86_FEATURE_VMX);
140 : : } else {
141 : : #ifdef CONFIG_X86_VMX_FEATURE_NAMES
142 : 0 : init_vmx_capabilities(c);
143 : : #endif
144 : : }
145 : : }
|