0001
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
0033
0034
0035
0036
0037
0038
0039
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
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
0057
0058
0059 rdmsr_safe(MSR_IA32_VMX_EPT_VPID_CAP, &ept, &vpid);
0060
0061
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
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
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
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
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
0131
0132
0133
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
0144
0145
0146 msr = FEAT_CTL_LOCKED;
0147
0148
0149
0150
0151
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
0196
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 }