xref: /openbmc/linux/arch/x86/kvm/vmx/capabilities.h (revision 023e4163)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef __KVM_X86_VMX_CAPS_H
3 #define __KVM_X86_VMX_CAPS_H
4 
5 #include "lapic.h"
6 
7 extern bool __read_mostly enable_vpid;
8 extern bool __read_mostly flexpriority_enabled;
9 extern bool __read_mostly enable_ept;
10 extern bool __read_mostly enable_unrestricted_guest;
11 extern bool __read_mostly enable_ept_ad_bits;
12 extern bool __read_mostly enable_pml;
13 extern int __read_mostly pt_mode;
14 
15 #define PT_MODE_SYSTEM		0
16 #define PT_MODE_HOST_GUEST	1
17 
18 struct nested_vmx_msrs {
19 	/*
20 	 * We only store the "true" versions of the VMX capability MSRs. We
21 	 * generate the "non-true" versions by setting the must-be-1 bits
22 	 * according to the SDM.
23 	 */
24 	u32 procbased_ctls_low;
25 	u32 procbased_ctls_high;
26 	u32 secondary_ctls_low;
27 	u32 secondary_ctls_high;
28 	u32 pinbased_ctls_low;
29 	u32 pinbased_ctls_high;
30 	u32 exit_ctls_low;
31 	u32 exit_ctls_high;
32 	u32 entry_ctls_low;
33 	u32 entry_ctls_high;
34 	u32 misc_low;
35 	u32 misc_high;
36 	u32 ept_caps;
37 	u32 vpid_caps;
38 	u64 basic;
39 	u64 cr0_fixed0;
40 	u64 cr0_fixed1;
41 	u64 cr4_fixed0;
42 	u64 cr4_fixed1;
43 	u64 vmcs_enum;
44 	u64 vmfunc_controls;
45 };
46 
47 struct vmcs_config {
48 	int size;
49 	int order;
50 	u32 basic_cap;
51 	u32 revision_id;
52 	u32 pin_based_exec_ctrl;
53 	u32 cpu_based_exec_ctrl;
54 	u32 cpu_based_2nd_exec_ctrl;
55 	u32 vmexit_ctrl;
56 	u32 vmentry_ctrl;
57 	struct nested_vmx_msrs nested;
58 };
59 extern struct vmcs_config vmcs_config;
60 
61 struct vmx_capability {
62 	u32 ept;
63 	u32 vpid;
64 };
65 extern struct vmx_capability vmx_capability;
66 
67 static inline bool cpu_has_vmx_basic_inout(void)
68 {
69 	return	(((u64)vmcs_config.basic_cap << 32) & VMX_BASIC_INOUT);
70 }
71 
72 static inline bool cpu_has_virtual_nmis(void)
73 {
74 	return vmcs_config.pin_based_exec_ctrl & PIN_BASED_VIRTUAL_NMIS;
75 }
76 
77 static inline bool cpu_has_vmx_preemption_timer(void)
78 {
79 	return vmcs_config.pin_based_exec_ctrl &
80 		PIN_BASED_VMX_PREEMPTION_TIMER;
81 }
82 
83 static inline bool cpu_has_vmx_posted_intr(void)
84 {
85 	return IS_ENABLED(CONFIG_X86_LOCAL_APIC) &&
86 		vmcs_config.pin_based_exec_ctrl & PIN_BASED_POSTED_INTR;
87 }
88 
89 static inline bool cpu_has_load_ia32_efer(void)
90 {
91 	return (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_EFER) &&
92 	       (vmcs_config.vmexit_ctrl & VM_EXIT_LOAD_IA32_EFER);
93 }
94 
95 static inline bool cpu_has_load_perf_global_ctrl(void)
96 {
97 	return (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL) &&
98 	       (vmcs_config.vmexit_ctrl & VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL);
99 }
100 
101 static inline bool vmx_mpx_supported(void)
102 {
103 	return (vmcs_config.vmexit_ctrl & VM_EXIT_CLEAR_BNDCFGS) &&
104 		(vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_BNDCFGS);
105 }
106 
107 static inline bool cpu_has_vmx_tpr_shadow(void)
108 {
109 	return vmcs_config.cpu_based_exec_ctrl & CPU_BASED_TPR_SHADOW;
110 }
111 
112 static inline bool cpu_need_tpr_shadow(struct kvm_vcpu *vcpu)
113 {
114 	return cpu_has_vmx_tpr_shadow() && lapic_in_kernel(vcpu);
115 }
116 
117 static inline bool cpu_has_vmx_msr_bitmap(void)
118 {
119 	return vmcs_config.cpu_based_exec_ctrl & CPU_BASED_USE_MSR_BITMAPS;
120 }
121 
122 static inline bool cpu_has_secondary_exec_ctrls(void)
123 {
124 	return vmcs_config.cpu_based_exec_ctrl &
125 		CPU_BASED_ACTIVATE_SECONDARY_CONTROLS;
126 }
127 
128 static inline bool cpu_has_vmx_virtualize_apic_accesses(void)
129 {
130 	return vmcs_config.cpu_based_2nd_exec_ctrl &
131 		SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
132 }
133 
134 static inline bool cpu_has_vmx_ept(void)
135 {
136 	return vmcs_config.cpu_based_2nd_exec_ctrl &
137 		SECONDARY_EXEC_ENABLE_EPT;
138 }
139 
140 static inline bool vmx_umip_emulated(void)
141 {
142 	return vmcs_config.cpu_based_2nd_exec_ctrl &
143 		SECONDARY_EXEC_DESC;
144 }
145 
146 static inline bool cpu_has_vmx_rdtscp(void)
147 {
148 	return vmcs_config.cpu_based_2nd_exec_ctrl &
149 		SECONDARY_EXEC_RDTSCP;
150 }
151 
152 static inline bool cpu_has_vmx_virtualize_x2apic_mode(void)
153 {
154 	return vmcs_config.cpu_based_2nd_exec_ctrl &
155 		SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE;
156 }
157 
158 static inline bool cpu_has_vmx_vpid(void)
159 {
160 	return vmcs_config.cpu_based_2nd_exec_ctrl &
161 		SECONDARY_EXEC_ENABLE_VPID;
162 }
163 
164 static inline bool cpu_has_vmx_wbinvd_exit(void)
165 {
166 	return vmcs_config.cpu_based_2nd_exec_ctrl &
167 		SECONDARY_EXEC_WBINVD_EXITING;
168 }
169 
170 static inline bool cpu_has_vmx_unrestricted_guest(void)
171 {
172 	return vmcs_config.cpu_based_2nd_exec_ctrl &
173 		SECONDARY_EXEC_UNRESTRICTED_GUEST;
174 }
175 
176 static inline bool cpu_has_vmx_apic_register_virt(void)
177 {
178 	return vmcs_config.cpu_based_2nd_exec_ctrl &
179 		SECONDARY_EXEC_APIC_REGISTER_VIRT;
180 }
181 
182 static inline bool cpu_has_vmx_virtual_intr_delivery(void)
183 {
184 	return vmcs_config.cpu_based_2nd_exec_ctrl &
185 		SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY;
186 }
187 
188 static inline bool cpu_has_vmx_ple(void)
189 {
190 	return vmcs_config.cpu_based_2nd_exec_ctrl &
191 		SECONDARY_EXEC_PAUSE_LOOP_EXITING;
192 }
193 
194 static inline bool vmx_rdrand_supported(void)
195 {
196 	return vmcs_config.cpu_based_2nd_exec_ctrl &
197 		SECONDARY_EXEC_RDRAND_EXITING;
198 }
199 
200 static inline bool cpu_has_vmx_invpcid(void)
201 {
202 	return vmcs_config.cpu_based_2nd_exec_ctrl &
203 		SECONDARY_EXEC_ENABLE_INVPCID;
204 }
205 
206 static inline bool cpu_has_vmx_vmfunc(void)
207 {
208 	return vmcs_config.cpu_based_2nd_exec_ctrl &
209 		SECONDARY_EXEC_ENABLE_VMFUNC;
210 }
211 
212 static inline bool cpu_has_vmx_shadow_vmcs(void)
213 {
214 	u64 vmx_msr;
215 
216 	/* check if the cpu supports writing r/o exit information fields */
217 	rdmsrl(MSR_IA32_VMX_MISC, vmx_msr);
218 	if (!(vmx_msr & MSR_IA32_VMX_MISC_VMWRITE_SHADOW_RO_FIELDS))
219 		return false;
220 
221 	return vmcs_config.cpu_based_2nd_exec_ctrl &
222 		SECONDARY_EXEC_SHADOW_VMCS;
223 }
224 
225 static inline bool cpu_has_vmx_encls_vmexit(void)
226 {
227 	return vmcs_config.cpu_based_2nd_exec_ctrl &
228 		SECONDARY_EXEC_ENCLS_EXITING;
229 }
230 
231 static inline bool vmx_rdseed_supported(void)
232 {
233 	return vmcs_config.cpu_based_2nd_exec_ctrl &
234 		SECONDARY_EXEC_RDSEED_EXITING;
235 }
236 
237 static inline bool cpu_has_vmx_pml(void)
238 {
239 	return vmcs_config.cpu_based_2nd_exec_ctrl & SECONDARY_EXEC_ENABLE_PML;
240 }
241 
242 static inline bool vmx_xsaves_supported(void)
243 {
244 	return vmcs_config.cpu_based_2nd_exec_ctrl &
245 		SECONDARY_EXEC_XSAVES;
246 }
247 
248 static inline bool cpu_has_vmx_tsc_scaling(void)
249 {
250 	return vmcs_config.cpu_based_2nd_exec_ctrl &
251 		SECONDARY_EXEC_TSC_SCALING;
252 }
253 
254 static inline bool cpu_has_vmx_apicv(void)
255 {
256 	return cpu_has_vmx_apic_register_virt() &&
257 		cpu_has_vmx_virtual_intr_delivery() &&
258 		cpu_has_vmx_posted_intr();
259 }
260 
261 static inline bool cpu_has_vmx_flexpriority(void)
262 {
263 	return cpu_has_vmx_tpr_shadow() &&
264 		cpu_has_vmx_virtualize_apic_accesses();
265 }
266 
267 static inline bool cpu_has_vmx_ept_execute_only(void)
268 {
269 	return vmx_capability.ept & VMX_EPT_EXECUTE_ONLY_BIT;
270 }
271 
272 static inline bool cpu_has_vmx_ept_4levels(void)
273 {
274 	return vmx_capability.ept & VMX_EPT_PAGE_WALK_4_BIT;
275 }
276 
277 static inline bool cpu_has_vmx_ept_5levels(void)
278 {
279 	return vmx_capability.ept & VMX_EPT_PAGE_WALK_5_BIT;
280 }
281 
282 static inline bool cpu_has_vmx_ept_mt_wb(void)
283 {
284 	return vmx_capability.ept & VMX_EPTP_WB_BIT;
285 }
286 
287 static inline bool cpu_has_vmx_ept_2m_page(void)
288 {
289 	return vmx_capability.ept & VMX_EPT_2MB_PAGE_BIT;
290 }
291 
292 static inline bool cpu_has_vmx_ept_1g_page(void)
293 {
294 	return vmx_capability.ept & VMX_EPT_1GB_PAGE_BIT;
295 }
296 
297 static inline bool cpu_has_vmx_ept_ad_bits(void)
298 {
299 	return vmx_capability.ept & VMX_EPT_AD_BIT;
300 }
301 
302 static inline bool cpu_has_vmx_invept_context(void)
303 {
304 	return vmx_capability.ept & VMX_EPT_EXTENT_CONTEXT_BIT;
305 }
306 
307 static inline bool cpu_has_vmx_invept_global(void)
308 {
309 	return vmx_capability.ept & VMX_EPT_EXTENT_GLOBAL_BIT;
310 }
311 
312 static inline bool cpu_has_vmx_invvpid(void)
313 {
314 	return vmx_capability.vpid & VMX_VPID_INVVPID_BIT;
315 }
316 
317 static inline bool cpu_has_vmx_invvpid_individual_addr(void)
318 {
319 	return vmx_capability.vpid & VMX_VPID_EXTENT_INDIVIDUAL_ADDR_BIT;
320 }
321 
322 static inline bool cpu_has_vmx_invvpid_single(void)
323 {
324 	return vmx_capability.vpid & VMX_VPID_EXTENT_SINGLE_CONTEXT_BIT;
325 }
326 
327 static inline bool cpu_has_vmx_invvpid_global(void)
328 {
329 	return vmx_capability.vpid & VMX_VPID_EXTENT_GLOBAL_CONTEXT_BIT;
330 }
331 
332 static inline bool cpu_has_vmx_intel_pt(void)
333 {
334 	u64 vmx_msr;
335 
336 	rdmsrl(MSR_IA32_VMX_MISC, vmx_msr);
337 	return (vmx_msr & MSR_IA32_VMX_MISC_INTEL_PT) &&
338 		(vmcs_config.cpu_based_2nd_exec_ctrl & SECONDARY_EXEC_PT_USE_GPA) &&
339 		(vmcs_config.vmexit_ctrl & VM_EXIT_CLEAR_IA32_RTIT_CTL) &&
340 		(vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_RTIT_CTL);
341 }
342 
343 #endif /* __KVM_X86_VMX_CAPS_H */
344