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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstatic 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