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