Linux Audio

Check our new training course

Loading...
  1/* SPDX-License-Identifier: GPL-2.0 */
  2#ifndef __KVM_X86_VMX_CAPS_H
  3#define __KVM_X86_VMX_CAPS_H
  4
  5#include <asm/vmx.h>
  6
  7#include "lapic.h"
  8
  9extern bool __read_mostly enable_vpid;
 10extern bool __read_mostly flexpriority_enabled;
 11extern bool __read_mostly enable_ept;
 12extern bool __read_mostly enable_unrestricted_guest;
 13extern bool __read_mostly enable_ept_ad_bits;
 14extern bool __read_mostly enable_pml;
 15extern int __read_mostly pt_mode;
 16
 17#define PT_MODE_SYSTEM		0
 18#define PT_MODE_HOST_GUEST	1
 19
 20#define PMU_CAP_FW_WRITES	(1ULL << 13)
 21#define PMU_CAP_LBR_FMT		0x3f
 22
 23#define DEBUGCTLMSR_LBR_MASK		(DEBUGCTLMSR_LBR | DEBUGCTLMSR_FREEZE_LBRS_ON_PMI)
 24
 25struct nested_vmx_msrs {
 26	/*
 27	 * We only store the "true" versions of the VMX capability MSRs. We
 28	 * generate the "non-true" versions by setting the must-be-1 bits
 29	 * according to the SDM.
 30	 */
 31	u32 procbased_ctls_low;
 32	u32 procbased_ctls_high;
 33	u32 secondary_ctls_low;
 34	u32 secondary_ctls_high;
 35	u32 pinbased_ctls_low;
 36	u32 pinbased_ctls_high;
 37	u32 exit_ctls_low;
 38	u32 exit_ctls_high;
 39	u32 entry_ctls_low;
 40	u32 entry_ctls_high;
 41	u32 misc_low;
 42	u32 misc_high;
 43	u32 ept_caps;
 44	u32 vpid_caps;
 45	u64 basic;
 46	u64 cr0_fixed0;
 47	u64 cr0_fixed1;
 48	u64 cr4_fixed0;
 49	u64 cr4_fixed1;
 50	u64 vmcs_enum;
 51	u64 vmfunc_controls;
 52};
 53
 54struct vmcs_config {
 55	int size;
 56	int order;
 57	u32 basic_cap;
 58	u32 revision_id;
 59	u32 pin_based_exec_ctrl;
 60	u32 cpu_based_exec_ctrl;
 61	u32 cpu_based_2nd_exec_ctrl;
 62	u32 vmexit_ctrl;
 63	u32 vmentry_ctrl;
 64	struct nested_vmx_msrs nested;
 65};
 66extern struct vmcs_config vmcs_config;
 67
 68struct vmx_capability {
 69	u32 ept;
 70	u32 vpid;
 71};
 72extern struct vmx_capability vmx_capability;
 73
 74static inline bool cpu_has_vmx_basic_inout(void)
 75{
 76	return	(((u64)vmcs_config.basic_cap << 32) & VMX_BASIC_INOUT);
 77}
 78
 79static inline bool cpu_has_virtual_nmis(void)
 80{
 81	return vmcs_config.pin_based_exec_ctrl & PIN_BASED_VIRTUAL_NMIS;
 82}
 83
 84static inline bool cpu_has_vmx_preemption_timer(void)
 85{
 86	return vmcs_config.pin_based_exec_ctrl &
 87		PIN_BASED_VMX_PREEMPTION_TIMER;
 88}
 89
 90static inline bool cpu_has_vmx_posted_intr(void)
 91{
 92	return vmcs_config.pin_based_exec_ctrl & PIN_BASED_POSTED_INTR;
 93}
 94
 95static inline bool cpu_has_load_ia32_efer(void)
 96{
 97	return (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_EFER) &&
 98	       (vmcs_config.vmexit_ctrl & VM_EXIT_LOAD_IA32_EFER);
 99}
100
101static inline bool cpu_has_load_perf_global_ctrl(void)
102{
103	return (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL) &&
104	       (vmcs_config.vmexit_ctrl & VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL);
105}
106
107static inline bool cpu_has_vmx_mpx(void)
108{
109	return (vmcs_config.vmexit_ctrl & VM_EXIT_CLEAR_BNDCFGS) &&
110		(vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_BNDCFGS);
111}
112
113static inline bool cpu_has_vmx_tpr_shadow(void)
114{
115	return vmcs_config.cpu_based_exec_ctrl & CPU_BASED_TPR_SHADOW;
116}
117
118static inline bool cpu_need_tpr_shadow(struct kvm_vcpu *vcpu)
119{
120	return cpu_has_vmx_tpr_shadow() && lapic_in_kernel(vcpu);
121}
122
123static inline bool cpu_has_vmx_msr_bitmap(void)
124{
125	return vmcs_config.cpu_based_exec_ctrl & CPU_BASED_USE_MSR_BITMAPS;
126}
127
128static inline bool cpu_has_secondary_exec_ctrls(void)
129{
130	return vmcs_config.cpu_based_exec_ctrl &
131		CPU_BASED_ACTIVATE_SECONDARY_CONTROLS;
132}
133
134static inline bool cpu_has_vmx_virtualize_apic_accesses(void)
135{
136	return vmcs_config.cpu_based_2nd_exec_ctrl &
137		SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
138}
139
140static inline bool cpu_has_vmx_ept(void)
141{
142	return vmcs_config.cpu_based_2nd_exec_ctrl &
143		SECONDARY_EXEC_ENABLE_EPT;
144}
145
146static inline bool vmx_umip_emulated(void)
147{
148	return vmcs_config.cpu_based_2nd_exec_ctrl &
149		SECONDARY_EXEC_DESC;
150}
151
152static inline bool cpu_has_vmx_rdtscp(void)
153{
154	return vmcs_config.cpu_based_2nd_exec_ctrl &
155		SECONDARY_EXEC_ENABLE_RDTSCP;
156}
157
158static inline bool cpu_has_vmx_virtualize_x2apic_mode(void)
159{
160	return vmcs_config.cpu_based_2nd_exec_ctrl &
161		SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE;
162}
163
164static inline bool cpu_has_vmx_vpid(void)
165{
166	return vmcs_config.cpu_based_2nd_exec_ctrl &
167		SECONDARY_EXEC_ENABLE_VPID;
168}
169
170static inline bool cpu_has_vmx_wbinvd_exit(void)
171{
172	return vmcs_config.cpu_based_2nd_exec_ctrl &
173		SECONDARY_EXEC_WBINVD_EXITING;
174}
175
176static inline bool cpu_has_vmx_unrestricted_guest(void)
177{
178	return vmcs_config.cpu_based_2nd_exec_ctrl &
179		SECONDARY_EXEC_UNRESTRICTED_GUEST;
180}
181
182static inline bool cpu_has_vmx_apic_register_virt(void)
183{
184	return vmcs_config.cpu_based_2nd_exec_ctrl &
185		SECONDARY_EXEC_APIC_REGISTER_VIRT;
186}
187
188static inline bool cpu_has_vmx_virtual_intr_delivery(void)
189{
190	return vmcs_config.cpu_based_2nd_exec_ctrl &
191		SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY;
192}
193
194static inline bool cpu_has_vmx_ple(void)
195{
196	return vmcs_config.cpu_based_2nd_exec_ctrl &
197		SECONDARY_EXEC_PAUSE_LOOP_EXITING;
198}
199
200static inline bool cpu_has_vmx_rdrand(void)
201{
202	return vmcs_config.cpu_based_2nd_exec_ctrl &
203		SECONDARY_EXEC_RDRAND_EXITING;
204}
205
206static inline bool cpu_has_vmx_invpcid(void)
207{
208	return vmcs_config.cpu_based_2nd_exec_ctrl &
209		SECONDARY_EXEC_ENABLE_INVPCID;
210}
211
212static inline bool cpu_has_vmx_vmfunc(void)
213{
214	return vmcs_config.cpu_based_2nd_exec_ctrl &
215		SECONDARY_EXEC_ENABLE_VMFUNC;
216}
217
218static inline bool cpu_has_vmx_shadow_vmcs(void)
219{
220	u64 vmx_msr;
221
222	/* check if the cpu supports writing r/o exit information fields */
223	rdmsrl(MSR_IA32_VMX_MISC, vmx_msr);
224	if (!(vmx_msr & MSR_IA32_VMX_MISC_VMWRITE_SHADOW_RO_FIELDS))
225		return false;
226
227	return vmcs_config.cpu_based_2nd_exec_ctrl &
228		SECONDARY_EXEC_SHADOW_VMCS;
229}
230
231static inline bool cpu_has_vmx_encls_vmexit(void)
232{
233	return vmcs_config.cpu_based_2nd_exec_ctrl &
234		SECONDARY_EXEC_ENCLS_EXITING;
235}
236
237static inline bool cpu_has_vmx_rdseed(void)
238{
239	return vmcs_config.cpu_based_2nd_exec_ctrl &
240		SECONDARY_EXEC_RDSEED_EXITING;
241}
242
243static inline bool cpu_has_vmx_pml(void)
244{
245	return vmcs_config.cpu_based_2nd_exec_ctrl & SECONDARY_EXEC_ENABLE_PML;
246}
247
248static inline bool cpu_has_vmx_xsaves(void)
249{
250	return vmcs_config.cpu_based_2nd_exec_ctrl &
251		SECONDARY_EXEC_XSAVES;
252}
253
254static inline bool cpu_has_vmx_waitpkg(void)
255{
256	return vmcs_config.cpu_based_2nd_exec_ctrl &
257		SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE;
258}
259
260static inline bool cpu_has_vmx_tsc_scaling(void)
261{
262	return vmcs_config.cpu_based_2nd_exec_ctrl &
263		SECONDARY_EXEC_TSC_SCALING;
264}
265
266static inline bool cpu_has_vmx_bus_lock_detection(void)
267{
268	return vmcs_config.cpu_based_2nd_exec_ctrl &
269	    SECONDARY_EXEC_BUS_LOCK_DETECTION;
270}
271
272static inline bool cpu_has_vmx_apicv(void)
273{
274	return cpu_has_vmx_apic_register_virt() &&
275		cpu_has_vmx_virtual_intr_delivery() &&
276		cpu_has_vmx_posted_intr();
277}
278
279static inline bool cpu_has_vmx_flexpriority(void)
280{
281	return cpu_has_vmx_tpr_shadow() &&
282		cpu_has_vmx_virtualize_apic_accesses();
283}
284
285static inline bool cpu_has_vmx_ept_execute_only(void)
286{
287	return vmx_capability.ept & VMX_EPT_EXECUTE_ONLY_BIT;
288}
289
290static inline bool cpu_has_vmx_ept_4levels(void)
291{
292	return vmx_capability.ept & VMX_EPT_PAGE_WALK_4_BIT;
293}
294
295static inline bool cpu_has_vmx_ept_5levels(void)
296{
297	return vmx_capability.ept & VMX_EPT_PAGE_WALK_5_BIT;
298}
299
300static inline bool cpu_has_vmx_ept_mt_wb(void)
301{
302	return vmx_capability.ept & VMX_EPTP_WB_BIT;
303}
304
305static inline bool cpu_has_vmx_ept_2m_page(void)
306{
307	return vmx_capability.ept & VMX_EPT_2MB_PAGE_BIT;
308}
309
310static inline bool cpu_has_vmx_ept_1g_page(void)
311{
312	return vmx_capability.ept & VMX_EPT_1GB_PAGE_BIT;
313}
314
315static inline bool cpu_has_vmx_ept_ad_bits(void)
316{
317	return vmx_capability.ept & VMX_EPT_AD_BIT;
318}
319
320static inline bool cpu_has_vmx_invept_context(void)
321{
322	return vmx_capability.ept & VMX_EPT_EXTENT_CONTEXT_BIT;
323}
324
325static inline bool cpu_has_vmx_invept_global(void)
326{
327	return vmx_capability.ept & VMX_EPT_EXTENT_GLOBAL_BIT;
328}
329
330static inline bool cpu_has_vmx_invvpid(void)
331{
332	return vmx_capability.vpid & VMX_VPID_INVVPID_BIT;
333}
334
335static inline bool cpu_has_vmx_invvpid_individual_addr(void)
336{
337	return vmx_capability.vpid & VMX_VPID_EXTENT_INDIVIDUAL_ADDR_BIT;
338}
339
340static inline bool cpu_has_vmx_invvpid_single(void)
341{
342	return vmx_capability.vpid & VMX_VPID_EXTENT_SINGLE_CONTEXT_BIT;
343}
344
345static inline bool cpu_has_vmx_invvpid_global(void)
346{
347	return vmx_capability.vpid & VMX_VPID_EXTENT_GLOBAL_CONTEXT_BIT;
348}
349
350static inline bool cpu_has_vmx_intel_pt(void)
351{
352	u64 vmx_msr;
353
354	rdmsrl(MSR_IA32_VMX_MISC, vmx_msr);
355	return (vmx_msr & MSR_IA32_VMX_MISC_INTEL_PT) &&
356		(vmcs_config.cpu_based_2nd_exec_ctrl & SECONDARY_EXEC_PT_USE_GPA) &&
357		(vmcs_config.vmexit_ctrl & VM_EXIT_CLEAR_IA32_RTIT_CTL) &&
358		(vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_RTIT_CTL);
359}
360
361/*
362 * Processor Trace can operate in one of three modes:
363 *  a. system-wide: trace both host/guest and output to host buffer
364 *  b. host-only:   only trace host and output to host buffer
365 *  c. host-guest:  trace host and guest simultaneously and output to their
366 *                  respective buffer
367 *
368 * KVM currently only supports (a) and (c).
369 */
370static inline bool vmx_pt_mode_is_system(void)
371{
372	return pt_mode == PT_MODE_SYSTEM;
373}
374static inline bool vmx_pt_mode_is_host_guest(void)
375{
376	return pt_mode == PT_MODE_HOST_GUEST;
377}
378
379static inline u64 vmx_get_perf_capabilities(void)
380{
381	u64 perf_cap = 0;
382
383	if (boot_cpu_has(X86_FEATURE_PDCM))
384		rdmsrl(MSR_IA32_PERF_CAPABILITIES, perf_cap);
385
386	perf_cap &= PMU_CAP_LBR_FMT;
387
388	/*
389	 * Since counters are virtualized, KVM would support full
390	 * width counting unconditionally, even if the host lacks it.
391	 */
392	return PMU_CAP_FW_WRITES | perf_cap;
393}
394
395static inline u64 vmx_supported_debugctl(void)
396{
397	u64 debugctl = 0;
398
399	if (boot_cpu_has(X86_FEATURE_BUS_LOCK_DETECT))
400		debugctl |= DEBUGCTLMSR_BUS_LOCK_DETECT;
401
402	if (vmx_get_perf_capabilities() & PMU_CAP_LBR_FMT)
403		debugctl |= DEBUGCTLMSR_LBR_MASK;
404
405	return debugctl;
406}
407
408#endif /* __KVM_X86_VMX_CAPS_H */