Enable the new instructions for reading and writing bases for %fs,

%gs, when supported.  Note that WRFSBASE and WRGSBASE are not very
useful on FreeBSD right now, because a return from the kernel mode to
userspace reloads the bases specified by the sysarch(2) syscall, most
likely.

Enable the Supervisor Mode Execution Prevention (SMEP) when
supported. Since the loader(8) performs hand-off to the kernel with
the page tables which contradict the SMEP, postpone enabling the SMEP
on BSP until pmap switched for the proper kernel tables.

Debugged with the help from:	avg
Tested by:	avg, Michael Moll <kvedulv@kvedulv.de>
MFC after:	1 month
This commit is contained in:
Konstantin Belousov 2012-11-01 15:17:43 +00:00
parent 2773649d2f
commit cd9e9d1bc2
2 changed files with 18 additions and 1 deletions

View File

@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h> #include <sys/param.h>
#include <sys/kernel.h> #include <sys/kernel.h>
#include <sys/pcpu.h>
#include <sys/systm.h> #include <sys/systm.h>
#include <sys/sysctl.h> #include <sys/sysctl.h>
@ -153,11 +154,25 @@ void
initializecpu(void) initializecpu(void)
{ {
uint64_t msr; uint64_t msr;
uint32_t cr4;
cr4 = rcr4();
if ((cpu_feature & CPUID_XMM) && (cpu_feature & CPUID_FXSR)) { if ((cpu_feature & CPUID_XMM) && (cpu_feature & CPUID_FXSR)) {
load_cr4(rcr4() | CR4_FXSR | CR4_XMM); cr4 |= CR4_FXSR | CR4_XMM;
cpu_fxsr = hw_instruction_sse = 1; cpu_fxsr = hw_instruction_sse = 1;
} }
if (cpu_stdext_feature & CPUID_STDEXT_FSGSBASE)
cr4 |= CR4_FSGSBASE;
/*
* Postpone enabling the SMEP on the boot CPU until the page
* tables are switched from the boot loader identity mapping
* to the kernel tables. The boot loader enables the U bit in
* its tables.
*/
if (!IS_BSP() && (cpu_stdext_feature & CPUID_STDEXT_SMEP))
cr4 |= CR4_SMEP;
load_cr4(cr4);
if ((amd_feature & AMDID_NX) != 0) { if ((amd_feature & AMDID_NX) != 0) {
msr = rdmsr(MSR_EFER) | EFER_NXE; msr = rdmsr(MSR_EFER) | EFER_NXE;
wrmsr(MSR_EFER, msr); wrmsr(MSR_EFER, msr);

View File

@ -622,6 +622,8 @@ pmap_bootstrap(vm_paddr_t *firstaddr)
/* XXX do %cr0 as well */ /* XXX do %cr0 as well */
load_cr4(rcr4() | CR4_PGE | CR4_PSE); load_cr4(rcr4() | CR4_PGE | CR4_PSE);
load_cr3(KPML4phys); load_cr3(KPML4phys);
if (cpu_stdext_feature & CPUID_STDEXT_SMEP)
load_cr4(rcr4() | CR4_SMEP);
/* /*
* Initialize the kernel pmap (which is statically allocated). * Initialize the kernel pmap (which is statically allocated).