1 // SPDX-License-Identifier: GPL-2.0 2 #include <linux/tboot.h> 3 4 #include <asm/cpu.h> 5 #include <asm/cpufeature.h> 6 #include <asm/msr-index.h> 7 #include <asm/msr.h> 8 #include <asm/processor.h> 9 #include <asm/vmx.h> 10 11 #undef pr_fmt 12 #define pr_fmt(fmt) "x86/cpu: " fmt 13 14 #ifdef CONFIG_X86_VMX_FEATURE_NAMES 15 enum vmx_feature_leafs { 16 MISC_FEATURES = 0, 17 PRIMARY_CTLS, 18 SECONDARY_CTLS, 19 TERTIARY_CTLS_LOW, 20 TERTIARY_CTLS_HIGH, 21 NR_VMX_FEATURE_WORDS, 22 }; 23 24 #define VMX_F(x) BIT(VMX_FEATURE_##x & 0x1f) 25 26 static void init_vmx_capabilities(struct cpuinfo_x86 *c) 27 { 28 struct msr val; 29 u32 supported, funcs, ept, vpid; 30 31 BUILD_BUG_ON(NVMXINTS != NR_VMX_FEATURE_WORDS); 32 33 /* 34 * The high bits contain the allowed-1 settings, i.e. features that can 35 * be turned on. The low bits contain the allowed-0 settings, i.e. 36 * features that can be turned off. Ignore the allowed-0 settings, 37 * if a feature can be turned on then it's supported. 38 * 39 * Use raw rdmsr() for primary processor controls and pin controls MSRs 40 * as they exist on any CPU that supports VMX, i.e. we want the WARN if 41 * the RDMSR faults. 42 */ 43 rdmsrq(MSR_IA32_VMX_PROCBASED_CTLS, val.q); 44 supported = val.h; 45 c->vmx_capability[PRIMARY_CTLS] = supported; 46 47 rdmsrq_safe(MSR_IA32_VMX_PROCBASED_CTLS2, &val.q); 48 supported = val.h; 49 c->vmx_capability[SECONDARY_CTLS] = supported; 50 51 /* All 64 bits of tertiary controls MSR are allowed-1 settings. */ 52 rdmsrq_safe(MSR_IA32_VMX_PROCBASED_CTLS3, &val.q); 53 c->vmx_capability[TERTIARY_CTLS_LOW] = val.l; 54 c->vmx_capability[TERTIARY_CTLS_HIGH] = val.h; 55 56 rdmsrq(MSR_IA32_VMX_PINBASED_CTLS, val.q); 57 supported = val.h; 58 rdmsrq_safe(MSR_IA32_VMX_VMFUNC, &val.q); 59 funcs = val.h; 60 61 /* 62 * Except for EPT+VPID, which enumerates support for both in a single 63 * MSR, low for EPT, high for VPID. 64 */ 65 rdmsrq_safe(MSR_IA32_VMX_EPT_VPID_CAP, &val.q); 66 ept = val.l; 67 vpid = val.h; 68 69 /* Pin, EPT, VPID and VM-Func are merged into a single word. */ 70 WARN_ON_ONCE(supported >> 16); 71 WARN_ON_ONCE(funcs >> 4); 72 c->vmx_capability[MISC_FEATURES] = (supported & 0xffff) | 73 ((vpid & 0x1) << 16) | 74 ((funcs & 0xf) << 28); 75 76 /* EPT bits are full on scattered and must be manually handled. */ 77 if (ept & VMX_EPT_EXECUTE_ONLY_BIT) 78 c->vmx_capability[MISC_FEATURES] |= VMX_F(EPT_EXECUTE_ONLY); 79 if (ept & VMX_EPT_AD_BIT) 80 c->vmx_capability[MISC_FEATURES] |= VMX_F(EPT_AD); 81 if (ept & VMX_EPT_1GB_PAGE_BIT) 82 c->vmx_capability[MISC_FEATURES] |= VMX_F(EPT_1GB); 83 if (ept & VMX_EPT_PAGE_WALK_5_BIT) 84 c->vmx_capability[MISC_FEATURES] |= VMX_F(EPT_5LEVEL); 85 86 /* Synthetic APIC features that are aggregates of multiple features. */ 87 if ((c->vmx_capability[PRIMARY_CTLS] & VMX_F(VIRTUAL_TPR)) && 88 (c->vmx_capability[SECONDARY_CTLS] & VMX_F(VIRT_APIC_ACCESSES))) 89 c->vmx_capability[MISC_FEATURES] |= VMX_F(FLEXPRIORITY); 90 91 if ((c->vmx_capability[PRIMARY_CTLS] & VMX_F(VIRTUAL_TPR)) && 92 (c->vmx_capability[SECONDARY_CTLS] & VMX_F(APIC_REGISTER_VIRT)) && 93 (c->vmx_capability[SECONDARY_CTLS] & VMX_F(VIRT_INTR_DELIVERY)) && 94 (c->vmx_capability[MISC_FEATURES] & VMX_F(POSTED_INTR))) 95 c->vmx_capability[MISC_FEATURES] |= VMX_F(APICV); 96 97 /* Set the synthetic cpufeatures to preserve /proc/cpuinfo's ABI. */ 98 if (c->vmx_capability[PRIMARY_CTLS] & VMX_F(VIRTUAL_TPR)) 99 set_cpu_cap(c, X86_FEATURE_TPR_SHADOW); 100 if (c->vmx_capability[MISC_FEATURES] & VMX_F(FLEXPRIORITY)) 101 set_cpu_cap(c, X86_FEATURE_FLEXPRIORITY); 102 if (c->vmx_capability[MISC_FEATURES] & VMX_F(VIRTUAL_NMIS)) 103 set_cpu_cap(c, X86_FEATURE_VNMI); 104 if (c->vmx_capability[SECONDARY_CTLS] & VMX_F(EPT)) 105 set_cpu_cap(c, X86_FEATURE_EPT); 106 if (c->vmx_capability[MISC_FEATURES] & VMX_F(EPT_AD)) 107 set_cpu_cap(c, X86_FEATURE_EPT_AD); 108 if (c->vmx_capability[MISC_FEATURES] & VMX_F(VPID)) 109 set_cpu_cap(c, X86_FEATURE_VPID); 110 } 111 #endif /* CONFIG_X86_VMX_FEATURE_NAMES */ 112 113 static int __init nosgx(char *str) 114 { 115 setup_clear_cpu_cap(X86_FEATURE_SGX); 116 117 return 0; 118 } 119 120 early_param("nosgx", nosgx); 121 122 void init_ia32_feat_ctl(struct cpuinfo_x86 *c) 123 { 124 bool enable_sgx_kvm = false, enable_sgx_driver = false; 125 bool tboot = tboot_enabled(); 126 bool enable_vmx; 127 u64 msr; 128 129 if (rdmsrq_safe(MSR_IA32_FEAT_CTL, &msr)) { 130 clear_cpu_cap(c, X86_FEATURE_VMX); 131 clear_cpu_cap(c, X86_FEATURE_SGX); 132 return; 133 } 134 135 enable_vmx = cpu_has(c, X86_FEATURE_VMX) && 136 IS_ENABLED(CONFIG_KVM_INTEL); 137 138 if (cpu_has(c, X86_FEATURE_SGX) && IS_ENABLED(CONFIG_X86_SGX)) { 139 /* 140 * Separate out SGX driver enabling from KVM. This allows KVM 141 * guests to use SGX even if the kernel SGX driver refuses to 142 * use it. This happens if flexible Launch Control is not 143 * available. 144 */ 145 enable_sgx_driver = cpu_has(c, X86_FEATURE_SGX_LC); 146 enable_sgx_kvm = enable_vmx && IS_ENABLED(CONFIG_X86_SGX_KVM); 147 } 148 149 if (msr & FEAT_CTL_LOCKED) 150 goto update_caps; 151 152 /* 153 * Ignore whatever value BIOS left in the MSR to avoid enabling random 154 * features or faulting on the WRMSR. 155 */ 156 msr = FEAT_CTL_LOCKED; 157 158 /* 159 * Enable VMX if and only if the kernel may do VMXON at some point, 160 * i.e. KVM is enabled, to avoid unnecessarily adding an attack vector 161 * for the kernel, e.g. using VMX to hide malicious code. 162 */ 163 if (enable_vmx) { 164 msr |= FEAT_CTL_VMX_ENABLED_OUTSIDE_SMX; 165 166 if (tboot) 167 msr |= FEAT_CTL_VMX_ENABLED_INSIDE_SMX; 168 } 169 170 if (enable_sgx_kvm || enable_sgx_driver) { 171 msr |= FEAT_CTL_SGX_ENABLED; 172 if (enable_sgx_driver) 173 msr |= FEAT_CTL_SGX_LC_ENABLED; 174 } 175 176 wrmsrq(MSR_IA32_FEAT_CTL, msr); 177 178 update_caps: 179 set_cpu_cap(c, X86_FEATURE_MSR_IA32_FEAT_CTL); 180 181 if (!cpu_has(c, X86_FEATURE_VMX)) 182 goto update_sgx; 183 184 if ( (tboot && !(msr & FEAT_CTL_VMX_ENABLED_INSIDE_SMX)) || 185 (!tboot && !(msr & FEAT_CTL_VMX_ENABLED_OUTSIDE_SMX))) { 186 if (IS_ENABLED(CONFIG_KVM_INTEL)) 187 pr_err_once("VMX (%s TXT) disabled by BIOS\n", 188 tboot ? "inside" : "outside"); 189 clear_cpu_cap(c, X86_FEATURE_VMX); 190 } else { 191 #ifdef CONFIG_X86_VMX_FEATURE_NAMES 192 init_vmx_capabilities(c); 193 #endif 194 } 195 196 update_sgx: 197 if (!(msr & FEAT_CTL_SGX_ENABLED)) { 198 if (enable_sgx_kvm || enable_sgx_driver) 199 pr_err_once("SGX disabled or unsupported by BIOS.\n"); 200 clear_cpu_cap(c, X86_FEATURE_SGX); 201 return; 202 } 203 204 /* 205 * VMX feature bit may be cleared due to being disabled in BIOS, 206 * in which case SGX virtualization cannot be supported either. 207 */ 208 if (!cpu_has(c, X86_FEATURE_VMX) && enable_sgx_kvm) { 209 pr_err_once("SGX virtualization disabled due to lack of VMX.\n"); 210 enable_sgx_kvm = 0; 211 } 212 213 if (!(msr & FEAT_CTL_SGX_LC_ENABLED) && enable_sgx_driver) { 214 if (!enable_sgx_kvm) { 215 pr_err_once("SGX Launch Control is locked. Disable SGX.\n"); 216 clear_cpu_cap(c, X86_FEATURE_SGX); 217 } else { 218 pr_err_once("SGX Launch Control is locked. Support SGX virtualization only.\n"); 219 clear_cpu_cap(c, X86_FEATURE_SGX_LC); 220 } 221 } 222 } 223