Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 #include <linux/tboot.h>
0003 
0004 #include <asm/cpufeature.h>
0005 #include <asm/msr-index.h>
0006 #include <asm/processor.h>
0007 #include <asm/vmx.h>
0008 #include "cpu.h"
0009 
0010 #undef pr_fmt
0011 #define pr_fmt(fmt) "x86/cpu: " fmt
0012 
0013 #ifdef CONFIG_X86_VMX_FEATURE_NAMES
0014 enum vmx_feature_leafs {
0015     MISC_FEATURES = 0,
0016     PRIMARY_CTLS,
0017     SECONDARY_CTLS,
0018     TERTIARY_CTLS_LOW,
0019     TERTIARY_CTLS_HIGH,
0020     NR_VMX_FEATURE_WORDS,
0021 };
0022 
0023 #define VMX_F(x) BIT(VMX_FEATURE_##x & 0x1f)
0024 
0025 static void init_vmx_capabilities(struct cpuinfo_x86 *c)
0026 {
0027     u32 supported, funcs, ept, vpid, ign, low, high;
0028 
0029     BUILD_BUG_ON(NVMXINTS != NR_VMX_FEATURE_WORDS);
0030 
0031     /*
0032      * The high bits contain the allowed-1 settings, i.e. features that can
0033      * be turned on.  The low bits contain the allowed-0 settings, i.e.
0034      * features that can be turned off.  Ignore the allowed-0 settings,
0035      * if a feature can be turned on then it's supported.
0036      *
0037      * Use raw rdmsr() for primary processor controls and pin controls MSRs
0038      * as they exist on any CPU that supports VMX, i.e. we want the WARN if
0039      * the RDMSR faults.
0040      */
0041     rdmsr(MSR_IA32_VMX_PROCBASED_CTLS, ign, supported);
0042     c->vmx_capability[PRIMARY_CTLS] = supported;
0043 
0044     rdmsr_safe(MSR_IA32_VMX_PROCBASED_CTLS2, &ign, &supported);
0045     c->vmx_capability[SECONDARY_CTLS] = supported;
0046 
0047     /* All 64 bits of tertiary controls MSR are allowed-1 settings. */
0048     rdmsr_safe(MSR_IA32_VMX_PROCBASED_CTLS3, &low, &high);
0049     c->vmx_capability[TERTIARY_CTLS_LOW] = low;
0050     c->vmx_capability[TERTIARY_CTLS_HIGH] = high;
0051 
0052     rdmsr(MSR_IA32_VMX_PINBASED_CTLS, ign, supported);
0053     rdmsr_safe(MSR_IA32_VMX_VMFUNC, &ign, &funcs);
0054 
0055     /*
0056      * Except for EPT+VPID, which enumerates support for both in a single
0057      * MSR, low for EPT, high for VPID.
0058      */
0059     rdmsr_safe(MSR_IA32_VMX_EPT_VPID_CAP, &ept, &vpid);
0060 
0061     /* Pin, EPT, VPID and VM-Func are merged into a single word. */
0062     WARN_ON_ONCE(supported >> 16);
0063     WARN_ON_ONCE(funcs >> 4);
0064     c->vmx_capability[MISC_FEATURES] = (supported & 0xffff) |
0065                        ((vpid & 0x1) << 16) |
0066                        ((funcs & 0xf) << 28);
0067 
0068     /* EPT bits are full on scattered and must be manually handled. */
0069     if (ept & VMX_EPT_EXECUTE_ONLY_BIT)
0070         c->vmx_capability[MISC_FEATURES] |= VMX_F(EPT_EXECUTE_ONLY);
0071     if (ept & VMX_EPT_AD_BIT)
0072         c->vmx_capability[MISC_FEATURES] |= VMX_F(EPT_AD);
0073     if (ept & VMX_EPT_1GB_PAGE_BIT)
0074         c->vmx_capability[MISC_FEATURES] |= VMX_F(EPT_1GB);
0075 
0076     /* Synthetic APIC features that are aggregates of multiple features. */
0077     if ((c->vmx_capability[PRIMARY_CTLS] & VMX_F(VIRTUAL_TPR)) &&
0078         (c->vmx_capability[SECONDARY_CTLS] & VMX_F(VIRT_APIC_ACCESSES)))
0079         c->vmx_capability[MISC_FEATURES] |= VMX_F(FLEXPRIORITY);
0080 
0081     if ((c->vmx_capability[PRIMARY_CTLS] & VMX_F(VIRTUAL_TPR)) &&
0082         (c->vmx_capability[SECONDARY_CTLS] & VMX_F(APIC_REGISTER_VIRT)) &&
0083         (c->vmx_capability[SECONDARY_CTLS] & VMX_F(VIRT_INTR_DELIVERY)) &&
0084         (c->vmx_capability[MISC_FEATURES] & VMX_F(POSTED_INTR)))
0085         c->vmx_capability[MISC_FEATURES] |= VMX_F(APICV);
0086 
0087     /* Set the synthetic cpufeatures to preserve /proc/cpuinfo's ABI. */
0088     if (c->vmx_capability[PRIMARY_CTLS] & VMX_F(VIRTUAL_TPR))
0089         set_cpu_cap(c, X86_FEATURE_TPR_SHADOW);
0090     if (c->vmx_capability[MISC_FEATURES] & VMX_F(FLEXPRIORITY))
0091         set_cpu_cap(c, X86_FEATURE_FLEXPRIORITY);
0092     if (c->vmx_capability[MISC_FEATURES] & VMX_F(VIRTUAL_NMIS))
0093         set_cpu_cap(c, X86_FEATURE_VNMI);
0094     if (c->vmx_capability[SECONDARY_CTLS] & VMX_F(EPT))
0095         set_cpu_cap(c, X86_FEATURE_EPT);
0096     if (c->vmx_capability[MISC_FEATURES] & VMX_F(EPT_AD))
0097         set_cpu_cap(c, X86_FEATURE_EPT_AD);
0098     if (c->vmx_capability[MISC_FEATURES] & VMX_F(VPID))
0099         set_cpu_cap(c, X86_FEATURE_VPID);
0100 }
0101 #endif /* CONFIG_X86_VMX_FEATURE_NAMES */
0102 
0103 static int __init nosgx(char *str)
0104 {
0105     setup_clear_cpu_cap(X86_FEATURE_SGX);
0106 
0107     return 0;
0108 }
0109 
0110 early_param("nosgx", nosgx);
0111 
0112 void init_ia32_feat_ctl(struct cpuinfo_x86 *c)
0113 {
0114     bool enable_sgx_kvm = false, enable_sgx_driver = false;
0115     bool tboot = tboot_enabled();
0116     bool enable_vmx;
0117     u64 msr;
0118 
0119     if (rdmsrl_safe(MSR_IA32_FEAT_CTL, &msr)) {
0120         clear_cpu_cap(c, X86_FEATURE_VMX);
0121         clear_cpu_cap(c, X86_FEATURE_SGX);
0122         return;
0123     }
0124 
0125     enable_vmx = cpu_has(c, X86_FEATURE_VMX) &&
0126              IS_ENABLED(CONFIG_KVM_INTEL);
0127 
0128     if (cpu_has(c, X86_FEATURE_SGX) && IS_ENABLED(CONFIG_X86_SGX)) {
0129         /*
0130          * Separate out SGX driver enabling from KVM.  This allows KVM
0131          * guests to use SGX even if the kernel SGX driver refuses to
0132          * use it.  This happens if flexible Launch Control is not
0133          * available.
0134          */
0135         enable_sgx_driver = cpu_has(c, X86_FEATURE_SGX_LC);
0136         enable_sgx_kvm = enable_vmx && IS_ENABLED(CONFIG_X86_SGX_KVM);
0137     }
0138 
0139     if (msr & FEAT_CTL_LOCKED)
0140         goto update_caps;
0141 
0142     /*
0143      * Ignore whatever value BIOS left in the MSR to avoid enabling random
0144      * features or faulting on the WRMSR.
0145      */
0146     msr = FEAT_CTL_LOCKED;
0147 
0148     /*
0149      * Enable VMX if and only if the kernel may do VMXON at some point,
0150      * i.e. KVM is enabled, to avoid unnecessarily adding an attack vector
0151      * for the kernel, e.g. using VMX to hide malicious code.
0152      */
0153     if (enable_vmx) {
0154         msr |= FEAT_CTL_VMX_ENABLED_OUTSIDE_SMX;
0155 
0156         if (tboot)
0157             msr |= FEAT_CTL_VMX_ENABLED_INSIDE_SMX;
0158     }
0159 
0160     if (enable_sgx_kvm || enable_sgx_driver) {
0161         msr |= FEAT_CTL_SGX_ENABLED;
0162         if (enable_sgx_driver)
0163             msr |= FEAT_CTL_SGX_LC_ENABLED;
0164     }
0165 
0166     wrmsrl(MSR_IA32_FEAT_CTL, msr);
0167 
0168 update_caps:
0169     set_cpu_cap(c, X86_FEATURE_MSR_IA32_FEAT_CTL);
0170 
0171     if (!cpu_has(c, X86_FEATURE_VMX))
0172         goto update_sgx;
0173 
0174     if ( (tboot && !(msr & FEAT_CTL_VMX_ENABLED_INSIDE_SMX)) ||
0175         (!tboot && !(msr & FEAT_CTL_VMX_ENABLED_OUTSIDE_SMX))) {
0176         if (IS_ENABLED(CONFIG_KVM_INTEL))
0177             pr_err_once("VMX (%s TXT) disabled by BIOS\n",
0178                     tboot ? "inside" : "outside");
0179         clear_cpu_cap(c, X86_FEATURE_VMX);
0180     } else {
0181 #ifdef CONFIG_X86_VMX_FEATURE_NAMES
0182         init_vmx_capabilities(c);
0183 #endif
0184     }
0185 
0186 update_sgx:
0187     if (!(msr & FEAT_CTL_SGX_ENABLED)) {
0188         if (enable_sgx_kvm || enable_sgx_driver)
0189             pr_err_once("SGX disabled by BIOS.\n");
0190         clear_cpu_cap(c, X86_FEATURE_SGX);
0191         return;
0192     }
0193 
0194     /*
0195      * VMX feature bit may be cleared due to being disabled in BIOS,
0196      * in which case SGX virtualization cannot be supported either.
0197      */
0198     if (!cpu_has(c, X86_FEATURE_VMX) && enable_sgx_kvm) {
0199         pr_err_once("SGX virtualization disabled due to lack of VMX.\n");
0200         enable_sgx_kvm = 0;
0201     }
0202 
0203     if (!(msr & FEAT_CTL_SGX_LC_ENABLED) && enable_sgx_driver) {
0204         if (!enable_sgx_kvm) {
0205             pr_err_once("SGX Launch Control is locked. Disable SGX.\n");
0206             clear_cpu_cap(c, X86_FEATURE_SGX);
0207         } else {
0208             pr_err_once("SGX Launch Control is locked. Support SGX virtualization only.\n");
0209             clear_cpu_cap(c, X86_FEATURE_SGX_LC);
0210         }
0211     }
0212 }