* Initialize CPU control registers */
| 251 | * Initialize CPU control registers |
| 252 | */ |
| 253 | void |
| 254 | initializecpu(void) |
| 255 | { |
| 256 | uint64_t msr; |
| 257 | uint32_t cr4; |
| 258 | |
| 259 | cr4 = rcr4(); |
| 260 | if ((cpu_feature & CPUID_XMM) && (cpu_feature & CPUID_FXSR)) { |
| 261 | cr4 |= CR4_FXSR | CR4_XMM; |
| 262 | cpu_fxsr = hw_instruction_sse = 1; |
| 263 | } |
| 264 | if (cpu_stdext_feature & CPUID_STDEXT_FSGSBASE) |
| 265 | cr4 |= CR4_FSGSBASE; |
| 266 | |
| 267 | if (cpu_stdext_feature2 & CPUID_STDEXT2_PKU) |
| 268 | cr4 |= CR4_PKE; |
| 269 | |
| 270 | /* |
| 271 | * If SMEP is present, we only need to flush RSB (by default) |
| 272 | * on context switches, to prevent cross-process ret2spec |
| 273 | * attacks. Do it automatically if ibrs_disable is set, to |
| 274 | * complete the mitigation. |
| 275 | * |
| 276 | * Postpone enabling the SMEP on the boot CPU until the page |
| 277 | * tables are switched from the boot loader identity mapping |
| 278 | * to the kernel tables. The boot loader enables the U bit in |
| 279 | * its tables. |
| 280 | */ |
| 281 | if (IS_BSP()) { |
| 282 | if (cpu_stdext_feature & CPUID_STDEXT_SMEP && |
| 283 | !TUNABLE_INT_FETCH( |
| 284 | "machdep.mitigations.cpu_flush_rsb_ctxsw", |
| 285 | &cpu_flush_rsb_ctxsw) && |
| 286 | hw_ibrs_disable) |
| 287 | cpu_flush_rsb_ctxsw = 1; |
| 288 | } else { |
| 289 | if (cpu_stdext_feature & CPUID_STDEXT_SMEP) |
| 290 | cr4 |= CR4_SMEP; |
| 291 | if (cpu_stdext_feature & CPUID_STDEXT_SMAP) |
| 292 | cr4 |= CR4_SMAP; |
| 293 | } |
| 294 | load_cr4(cr4); |
| 295 | if (IS_BSP() && (amd_feature & AMDID_NX) != 0) { |
| 296 | msr = rdmsr(MSR_EFER) | EFER_NXE; |
| 297 | wrmsr(MSR_EFER, msr); |
| 298 | pg_nx = PG_NX; |
| 299 | } |
| 300 | hw_ibrs_recalculate(false); |
| 301 | hw_ssb_recalculate(false); |
| 302 | amd64_syscall_ret_flush_l1d_recalc(); |
| 303 | x86_rngds_mitg_recalculate(false); |
| 304 | switch (cpu_vendor_id) { |
| 305 | case CPU_VENDOR_AMD: |
| 306 | case CPU_VENDOR_HYGON: |
| 307 | init_amd(); |
| 308 | break; |
| 309 | case CPU_VENDOR_CENTAUR: |
| 310 | init_via(); |
no test coverage detected