File Index
Files and directories
Sign in
FILE

capabilities.h

File preview with syntax highlighting.

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