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:
parent
ab904526b5
commit
b09d1ac594
2 changed files with 84 additions and 7 deletions
|
@ -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"
|
||||
|
|
|
@ -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()) {
|
||||
|
|
Loading…
Add table
Reference in a new issue