1
0
Fork 0
mirror of https://github.com/hermitcore/libhermit.git synced 2025-03-09 00:00:03 +01:00

add the support of rdgsbase, rdfsbase, wrgsbase and wrfsbase

This commit is contained in:
Stefan Lankes 2015-08-09 14:32:00 +02:00
parent ab904526b5
commit b09d1ac594
2 changed files with 84 additions and 7 deletions

View file

@ -80,6 +80,7 @@ extern "C" {
#define CPU_FEATURE_LM (1 << 29)
// feature list 0x00000007:0
#define CPU_FEATURE_FSGSBASE (1 << 0)
#define CPU_FEATURE_AVX2 (1 << 5)
@ -158,7 +159,7 @@ extern "C" {
/// Enable Safer Mode Extensions, see Trusted Execution Technology (TXT)
#define CR4_SMXE (1 << 14)
/// Enables the instructions RDFSBASE, RDGSBASE, WRFSBASE, and WRGSBASE
#define CR4_FSGSBASE (1 << 16)
#define CR4_FSGSBASE (1 << 16)
/// Enables process-context identifiers
#define CR4_PCIDE (1 << 17)
/// Enable XSAVE and Processor Extended States
@ -288,8 +289,12 @@ inline static uint32_t has_nx(void)
return (cpu_info.feature3 & CPU_FEATURE_NX);
}
inline static uint32_t has_fsgsbase(void) {
return (cpu_info.feature4 & CPU_FEATURE_FSGSBASE);
}
inline static uint32_t has_avx2(void) {
return cpu_info.feature4 & CPU_FEATURE_AVX2;
return (cpu_info.feature4 & CPU_FEATURE_AVX2);
}
inline static uint32_t has_rdtscp(void) {
@ -412,6 +417,14 @@ static inline void write_cr4(size_t val) {
asm volatile("mov %0, %%cr4" : : "r"(val));
}
typedef size_t (*func_read_fsgs)(void);
typedef void (*func_write_fsgs)(size_t);
extern func_read_fsgs readfs;
extern func_read_fsgs readgs;
extern func_write_fsgs writefs;
extern func_write_fsgs writegs;
/** @brief Flush cache
*
* The wbinvd asm instruction which stands for "Write back and invalidate"

View file

@ -75,6 +75,59 @@ func_memory_barrier mb = default_mb;
func_memory_barrier rmb = default_mb;
func_memory_barrier wmb = default_mb;
static void default_writefs(size_t fs)
{
wrmsr(MSR_FS_BASE, fs);
}
static size_t default_readfs(void)
{
return rdmsr(MSR_FS_BASE);
}
static void default_writegs(size_t gs)
{
wrmsr(MSR_GS_BASE, gs);
}
static size_t default_readgs(void)
{
return rdmsr(MSR_GS_BASE);
}
static void wrfsbase(size_t fs)
{
asm volatile ("wrfsbase %0" :: "r"(fs));
}
static size_t rdfsbase(void)
{
size_t ret = 0;
asm volatile ("rdfsbase %0" : "=r"(ret) :: "memory");
return ret;
}
static void wrgsbase(size_t gs)
{
asm volatile ("wrgsbase %0" :: "r"(gs));
}
static size_t rdgsbase(void)
{
size_t ret = 0;
asm volatile ("rdgsbase %0" : "=r"(ret) :: "memory");
return ret;
}
func_read_fsgs readfs = default_readfs;
func_read_fsgs readgs = default_readgs;
func_write_fsgs writefs = default_writefs;
func_write_fsgs writegs = default_writegs;
static void mfence(void) { asm volatile("mfence" ::: "memory"); }
static void lfence(void) { asm volatile("lfence" ::: "memory"); }
static void sfence(void) { asm volatile("sfence" ::: "memory"); }
@ -207,9 +260,19 @@ int cpu_detection(void) {
cr4 |= CR4_OSXSAVE;
if (has_pge())
cr4 |= CR4_PGE;
if (has_fsgsbase())
cr4 |= CR4_FSGSBASE;
cr4 &= ~CR4_TSD; // => every privilege level is able to use rdtsc
write_cr4(cr4);
if (has_fsgsbase())
{
readfs = rdfsbase;
readgs = rdgsbase;
writefs = wrfsbase;
writegs = wrgsbase;
}
if (has_xsave())
{
xcr0 = xgetbv(0);
@ -235,11 +298,11 @@ int cpu_detection(void) {
if (has_nx())
wrmsr(MSR_EFER, rdmsr(MSR_EFER) | EFER_NXE);
wrmsr(MSR_FS_BASE, 0);
writefs(0);
#if MAX_CORES > 1
wrmsr(MSR_GS_BASE, apic_cpu_id() * ((size_t) &percore_end0 - (size_t) &percore_start));
writegs(apic_cpu_id() * ((size_t) &percore_end0 - (size_t) &percore_start));
#else
wrmsr(MSR_GS_BASE, 0);
writegs(0);
#endif
wrmsr(MSR_KERNEL_GS_BASE, 0);
@ -269,7 +332,7 @@ int cpu_detection(void) {
a = b = c = d = 0;
cpuid(1, &a, &b, &cpu_info.feature2, &cpu_info.feature1);
kprintf("CPU features: %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
kprintf("CPU features: %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
has_sse() ? "SSE " : "",
has_sse2() ? "SSE2 " : "",
has_sse3() ? "SSE3 " : "",
@ -284,7 +347,8 @@ int cpu_detection(void) {
has_fxsr() ? "FXSR " : "",
has_xsave() ? "XSAVE " : "",
has_osxsave() ? "OSXSAVE " : "",
has_rdtscp() ? "RDTSCP " : "");
has_rdtscp() ? "RDTSCP " : "",
has_fsgsbase() ? "FSGSBASE " : "");
}
if (first_time && has_osxsave()) {