Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef __KVM_X86_VMX_CAPS_H
0003 #define __KVM_X86_VMX_CAPS_H
0004 
0005 #include <asm/vmx.h>
0006 
0007 #include "../lapic.h"
0008 #include "../x86.h"
0009 #include "../pmu.h"
0010 #include "../cpuid.h"
0011 
0012 extern bool __read_mostly enable_vpid;
0013 extern bool __read_mostly flexpriority_enabled;
0014 extern bool __read_mostly enable_ept;
0015 extern bool __read_mostly enable_unrestricted_guest;
0016 extern bool __read_mostly enable_ept_ad_bits;
0017 extern bool __read_mostly enable_pml;
0018 extern bool __read_mostly enable_ipiv;
0019 extern int __read_mostly pt_mode;
0020 
0021 #define PT_MODE_SYSTEM      0
0022 #define PT_MODE_HOST_GUEST  1
0023 
0024 #define PMU_CAP_FW_WRITES   (1ULL << 13)
0025 #define PMU_CAP_LBR_FMT     0x3f
0026 
0027 #define DEBUGCTLMSR_LBR_MASK        (DEBUGCTLMSR_LBR | DEBUGCTLMSR_FREEZE_LBRS_ON_PMI)
0028 
0029 struct nested_vmx_msrs {
0030     /*
0031      * We only store the "true" versions of the VMX capability MSRs. We
0032      * generate the "non-true" versions by setting the must-be-1 bits
0033      * according to the SDM.
0034      */
0035     u32 procbased_ctls_low;
0036     u32 procbased_ctls_high;
0037     u32 secondary_ctls_low;
0038     u32 secondary_ctls_high;
0039     u32 pinbased_ctls_low;
0040     u32 pinbased_ctls_high;
0041     u32 exit_ctls_low;
0042     u32 exit_ctls_high;
0043     u32 entry_ctls_low;
0044     u32 entry_ctls_high;
0045     u32 misc_low;
0046     u32 misc_high;
0047     u32 ept_caps;
0048     u32 vpid_caps;
0049     u64 basic;
0050     u64 cr0_fixed0;
0051     u64 cr0_fixed1;
0052     u64 cr4_fixed0;
0053     u64 cr4_fixed1;
0054     u64 vmcs_enum;
0055     u64 vmfunc_controls;
0056 };
0057 
0058 struct vmcs_config {
0059     int size;
0060     u32 basic_cap;
0061     u32 revision_id;
0062     u32 pin_based_exec_ctrl;
0063     u32 cpu_based_exec_ctrl;
0064     u32 cpu_based_2nd_exec_ctrl;
0065     u64 cpu_based_3rd_exec_ctrl;
0066     u32 vmexit_ctrl;
0067     u32 vmentry_ctrl;
0068     struct nested_vmx_msrs nested;
0069 };
0070 extern struct vmcs_config vmcs_config;
0071 
0072 struct vmx_capability {
0073     u32 ept;
0074     u32 vpid;
0075 };
0076 extern struct vmx_capability vmx_capability;
0077 
0078 static inline bool cpu_has_vmx_basic_inout(void)
0079 {
0080     return  (((u64)vmcs_config.basic_cap << 32) & VMX_BASIC_INOUT);
0081 }
0082 
0083 static inline bool cpu_has_virtual_nmis(void)
0084 {
0085     return vmcs_config.pin_based_exec_ctrl & PIN_BASED_VIRTUAL_NMIS;
0086 }
0087 
0088 static inline bool cpu_has_vmx_preemption_timer(void)
0089 {
0090     return vmcs_config.pin_based_exec_ctrl &
0091         PIN_BASED_VMX_PREEMPTION_TIMER;
0092 }
0093 
0094 static inline bool cpu_has_vmx_posted_intr(void)
0095 {
0096     return vmcs_config.pin_based_exec_ctrl & PIN_BASED_POSTED_INTR;
0097 }
0098 
0099 static inline bool cpu_has_load_ia32_efer(void)
0100 {
0101     return vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_EFER;
0102 }
0103 
0104 static inline bool cpu_has_load_perf_global_ctrl(void)
0105 {
0106     return vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL;
0107 }
0108 
0109 static inline bool cpu_has_vmx_mpx(void)
0110 {
0111     return vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_BNDCFGS;
0112 }
0113 
0114 static inline bool cpu_has_vmx_tpr_shadow(void)
0115 {
0116     return vmcs_config.cpu_based_exec_ctrl & CPU_BASED_TPR_SHADOW;
0117 }
0118 
0119 static inline bool cpu_need_tpr_shadow(struct kvm_vcpu *vcpu)
0120 {
0121     return cpu_has_vmx_tpr_shadow() && lapic_in_kernel(vcpu);
0122 }
0123 
0124 static inline bool cpu_has_vmx_msr_bitmap(void)
0125 {
0126     return vmcs_config.cpu_based_exec_ctrl & CPU_BASED_USE_MSR_BITMAPS;
0127 }
0128 
0129 static inline bool cpu_has_secondary_exec_ctrls(void)
0130 {
0131     return vmcs_config.cpu_based_exec_ctrl &
0132         CPU_BASED_ACTIVATE_SECONDARY_CONTROLS;
0133 }
0134 
0135 static inline bool cpu_has_tertiary_exec_ctrls(void)
0136 {
0137     return vmcs_config.cpu_based_exec_ctrl &
0138         CPU_BASED_ACTIVATE_TERTIARY_CONTROLS;
0139 }
0140 
0141 static inline bool cpu_has_vmx_virtualize_apic_accesses(void)
0142 {
0143     return vmcs_config.cpu_based_2nd_exec_ctrl &
0144         SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
0145 }
0146 
0147 static inline bool cpu_has_vmx_ept(void)
0148 {
0149     return vmcs_config.cpu_based_2nd_exec_ctrl &
0150         SECONDARY_EXEC_ENABLE_EPT;
0151 }
0152 
0153 static inline bool vmx_umip_emulated(void)
0154 {
0155     return vmcs_config.cpu_based_2nd_exec_ctrl &
0156         SECONDARY_EXEC_DESC;
0157 }
0158 
0159 static inline bool cpu_has_vmx_rdtscp(void)
0160 {
0161     return vmcs_config.cpu_based_2nd_exec_ctrl &
0162         SECONDARY_EXEC_ENABLE_RDTSCP;
0163 }
0164 
0165 static inline bool cpu_has_vmx_virtualize_x2apic_mode(void)
0166 {
0167     return vmcs_config.cpu_based_2nd_exec_ctrl &
0168         SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE;
0169 }
0170 
0171 static inline bool cpu_has_vmx_vpid(void)
0172 {
0173     return vmcs_config.cpu_based_2nd_exec_ctrl &
0174         SECONDARY_EXEC_ENABLE_VPID;
0175 }
0176 
0177 static inline bool cpu_has_vmx_wbinvd_exit(void)
0178 {
0179     return vmcs_config.cpu_based_2nd_exec_ctrl &
0180         SECONDARY_EXEC_WBINVD_EXITING;
0181 }
0182 
0183 static inline bool cpu_has_vmx_unrestricted_guest(void)
0184 {
0185     return vmcs_config.cpu_based_2nd_exec_ctrl &
0186         SECONDARY_EXEC_UNRESTRICTED_GUEST;
0187 }
0188 
0189 static inline bool cpu_has_vmx_apic_register_virt(void)
0190 {
0191     return vmcs_config.cpu_based_2nd_exec_ctrl &
0192         SECONDARY_EXEC_APIC_REGISTER_VIRT;
0193 }
0194 
0195 static inline bool cpu_has_vmx_virtual_intr_delivery(void)
0196 {
0197     return vmcs_config.cpu_based_2nd_exec_ctrl &
0198         SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY;
0199 }
0200 
0201 static inline bool cpu_has_vmx_ple(void)
0202 {
0203     return vmcs_config.cpu_based_2nd_exec_ctrl &
0204         SECONDARY_EXEC_PAUSE_LOOP_EXITING;
0205 }
0206 
0207 static inline bool cpu_has_vmx_rdrand(void)
0208 {
0209     return vmcs_config.cpu_based_2nd_exec_ctrl &
0210         SECONDARY_EXEC_RDRAND_EXITING;
0211 }
0212 
0213 static inline bool cpu_has_vmx_invpcid(void)
0214 {
0215     return vmcs_config.cpu_based_2nd_exec_ctrl &
0216         SECONDARY_EXEC_ENABLE_INVPCID;
0217 }
0218 
0219 static inline bool cpu_has_vmx_vmfunc(void)
0220 {
0221     return vmcs_config.cpu_based_2nd_exec_ctrl &
0222         SECONDARY_EXEC_ENABLE_VMFUNC;
0223 }
0224 
0225 static inline bool cpu_has_vmx_shadow_vmcs(void)
0226 {
0227     u64 vmx_msr;
0228 
0229     /* check if the cpu supports writing r/o exit information fields */
0230     rdmsrl(MSR_IA32_VMX_MISC, vmx_msr);
0231     if (!(vmx_msr & MSR_IA32_VMX_MISC_VMWRITE_SHADOW_RO_FIELDS))
0232         return false;
0233 
0234     return vmcs_config.cpu_based_2nd_exec_ctrl &
0235         SECONDARY_EXEC_SHADOW_VMCS;
0236 }
0237 
0238 static inline bool cpu_has_vmx_encls_vmexit(void)
0239 {
0240     return vmcs_config.cpu_based_2nd_exec_ctrl &
0241         SECONDARY_EXEC_ENCLS_EXITING;
0242 }
0243 
0244 static inline bool cpu_has_vmx_rdseed(void)
0245 {
0246     return vmcs_config.cpu_based_2nd_exec_ctrl &
0247         SECONDARY_EXEC_RDSEED_EXITING;
0248 }
0249 
0250 static inline bool cpu_has_vmx_pml(void)
0251 {
0252     return vmcs_config.cpu_based_2nd_exec_ctrl & SECONDARY_EXEC_ENABLE_PML;
0253 }
0254 
0255 static inline bool cpu_has_vmx_xsaves(void)
0256 {
0257     return vmcs_config.cpu_based_2nd_exec_ctrl &
0258         SECONDARY_EXEC_XSAVES;
0259 }
0260 
0261 static inline bool cpu_has_vmx_waitpkg(void)
0262 {
0263     return vmcs_config.cpu_based_2nd_exec_ctrl &
0264         SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE;
0265 }
0266 
0267 static inline bool cpu_has_vmx_tsc_scaling(void)
0268 {
0269     return vmcs_config.cpu_based_2nd_exec_ctrl &
0270         SECONDARY_EXEC_TSC_SCALING;
0271 }
0272 
0273 static inline bool cpu_has_vmx_bus_lock_detection(void)
0274 {
0275     return vmcs_config.cpu_based_2nd_exec_ctrl &
0276         SECONDARY_EXEC_BUS_LOCK_DETECTION;
0277 }
0278 
0279 static inline bool cpu_has_vmx_apicv(void)
0280 {
0281     return cpu_has_vmx_apic_register_virt() &&
0282         cpu_has_vmx_virtual_intr_delivery() &&
0283         cpu_has_vmx_posted_intr();
0284 }
0285 
0286 static inline bool cpu_has_vmx_ipiv(void)
0287 {
0288     return vmcs_config.cpu_based_3rd_exec_ctrl & TERTIARY_EXEC_IPI_VIRT;
0289 }
0290 
0291 static inline bool cpu_has_vmx_flexpriority(void)
0292 {
0293     return cpu_has_vmx_tpr_shadow() &&
0294         cpu_has_vmx_virtualize_apic_accesses();
0295 }
0296 
0297 static inline bool cpu_has_vmx_ept_execute_only(void)
0298 {
0299     return vmx_capability.ept & VMX_EPT_EXECUTE_ONLY_BIT;
0300 }
0301 
0302 static inline bool cpu_has_vmx_ept_4levels(void)
0303 {
0304     return vmx_capability.ept & VMX_EPT_PAGE_WALK_4_BIT;
0305 }
0306 
0307 static inline bool cpu_has_vmx_ept_5levels(void)
0308 {
0309     return vmx_capability.ept & VMX_EPT_PAGE_WALK_5_BIT;
0310 }
0311 
0312 static inline bool cpu_has_vmx_ept_mt_wb(void)
0313 {
0314     return vmx_capability.ept & VMX_EPTP_WB_BIT;
0315 }
0316 
0317 static inline bool cpu_has_vmx_ept_2m_page(void)
0318 {
0319     return vmx_capability.ept & VMX_EPT_2MB_PAGE_BIT;
0320 }
0321 
0322 static inline bool cpu_has_vmx_ept_1g_page(void)
0323 {
0324     return vmx_capability.ept & VMX_EPT_1GB_PAGE_BIT;
0325 }
0326 
0327 static inline int ept_caps_to_lpage_level(u32 ept_caps)
0328 {
0329     if (ept_caps & VMX_EPT_1GB_PAGE_BIT)
0330         return PG_LEVEL_1G;
0331     if (ept_caps & VMX_EPT_2MB_PAGE_BIT)
0332         return PG_LEVEL_2M;
0333     return PG_LEVEL_4K;
0334 }
0335 
0336 static inline bool cpu_has_vmx_ept_ad_bits(void)
0337 {
0338     return vmx_capability.ept & VMX_EPT_AD_BIT;
0339 }
0340 
0341 static inline bool cpu_has_vmx_invept_context(void)
0342 {
0343     return vmx_capability.ept & VMX_EPT_EXTENT_CONTEXT_BIT;
0344 }
0345 
0346 static inline bool cpu_has_vmx_invept_global(void)
0347 {
0348     return vmx_capability.ept & VMX_EPT_EXTENT_GLOBAL_BIT;
0349 }
0350 
0351 static inline bool cpu_has_vmx_invvpid(void)
0352 {
0353     return vmx_capability.vpid & VMX_VPID_INVVPID_BIT;
0354 }
0355 
0356 static inline bool cpu_has_vmx_invvpid_individual_addr(void)
0357 {
0358     return vmx_capability.vpid & VMX_VPID_EXTENT_INDIVIDUAL_ADDR_BIT;
0359 }
0360 
0361 static inline bool cpu_has_vmx_invvpid_single(void)
0362 {
0363     return vmx_capability.vpid & VMX_VPID_EXTENT_SINGLE_CONTEXT_BIT;
0364 }
0365 
0366 static inline bool cpu_has_vmx_invvpid_global(void)
0367 {
0368     return vmx_capability.vpid & VMX_VPID_EXTENT_GLOBAL_CONTEXT_BIT;
0369 }
0370 
0371 static inline bool cpu_has_vmx_intel_pt(void)
0372 {
0373     u64 vmx_msr;
0374 
0375     rdmsrl(MSR_IA32_VMX_MISC, vmx_msr);
0376     return (vmx_msr & MSR_IA32_VMX_MISC_INTEL_PT) &&
0377         (vmcs_config.cpu_based_2nd_exec_ctrl & SECONDARY_EXEC_PT_USE_GPA) &&
0378         (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_RTIT_CTL);
0379 }
0380 
0381 /*
0382  * Processor Trace can operate in one of three modes:
0383  *  a. system-wide: trace both host/guest and output to host buffer
0384  *  b. host-only:   only trace host and output to host buffer
0385  *  c. host-guest:  trace host and guest simultaneously and output to their
0386  *                  respective buffer
0387  *
0388  * KVM currently only supports (a) and (c).
0389  */
0390 static inline bool vmx_pt_mode_is_system(void)
0391 {
0392     return pt_mode == PT_MODE_SYSTEM;
0393 }
0394 static inline bool vmx_pt_mode_is_host_guest(void)
0395 {
0396     return pt_mode == PT_MODE_HOST_GUEST;
0397 }
0398 
0399 static inline bool vmx_pebs_supported(void)
0400 {
0401     return boot_cpu_has(X86_FEATURE_PEBS) && kvm_pmu_cap.pebs_ept;
0402 }
0403 
0404 static inline u64 vmx_get_perf_capabilities(void)
0405 {
0406     u64 perf_cap = PMU_CAP_FW_WRITES;
0407     u64 host_perf_cap = 0;
0408 
0409     if (!enable_pmu)
0410         return 0;
0411 
0412     if (boot_cpu_has(X86_FEATURE_PDCM))
0413         rdmsrl(MSR_IA32_PERF_CAPABILITIES, host_perf_cap);
0414 
0415     perf_cap |= host_perf_cap & PMU_CAP_LBR_FMT;
0416 
0417     if (vmx_pebs_supported()) {
0418         perf_cap |= host_perf_cap & PERF_CAP_PEBS_MASK;
0419         if ((perf_cap & PERF_CAP_PEBS_FORMAT) < 4)
0420             perf_cap &= ~PERF_CAP_PEBS_BASELINE;
0421     }
0422 
0423     return perf_cap;
0424 }
0425 
0426 static inline u64 vmx_supported_debugctl(void)
0427 {
0428     u64 debugctl = 0;
0429 
0430     if (boot_cpu_has(X86_FEATURE_BUS_LOCK_DETECT))
0431         debugctl |= DEBUGCTLMSR_BUS_LOCK_DETECT;
0432 
0433     if (vmx_get_perf_capabilities() & PMU_CAP_LBR_FMT)
0434         debugctl |= DEBUGCTLMSR_LBR_MASK;
0435 
0436     return debugctl;
0437 }
0438 
0439 static inline bool cpu_has_notify_vmexit(void)
0440 {
0441     return vmcs_config.cpu_based_2nd_exec_ctrl &
0442         SECONDARY_EXEC_NOTIFY_VM_EXITING;
0443 }
0444 
0445 #endif /* __KVM_X86_VMX_CAPS_H */