Fixed tasking SSE

This commit is contained in:
Alex 2022-12-29 02:05:07 +02:00
parent 5da3b3ae6c
commit e53bc14240
Signed by untrusted user who does not match committer: enderice2
GPG Key ID: EACC3AD603BAB4DD
7 changed files with 88 additions and 57 deletions

View File

@ -1,11 +0,0 @@
[bits 64]
[global _amd64_fxsave]
_amd64_fxsave:
fxsave [rdi]
ret
[global _amd64_fxrstor]
_amd64_fxrstor:
fxrstor [rdi]
ret

View File

@ -1,11 +0,0 @@
[bits 64]
[global _i386_fxsave]
_i386_fxsave:
fxsave [edi]
ret
[global _i386_fxrstor]
_i386_fxrstor:
fxrstor [edi]
ret

View File

@ -209,30 +209,35 @@ namespace CPU
debug("Enabling UMIP, SMEP & SMAP support...");
x64::cpuid(0x1, &rax, &rbx, &rcx, &rdx);
if (rdx & x64::CPUID_FEAT_RDX_UMIP)
if (rdx & x64::CPUID_FEAT_RDX_UMIP) // https://en.wikipedia.org/wiki/Control_register
{
if (!BSP)
KPrint("UMIP is supported.");
fixme("Not going to enable UMIP.");
cr4.UMIP = 1;
debug("UMIP is supported.");
// cr4.UMIP = 1;
}
if (rdx & x64::CPUID_FEAT_RDX_SMEP)
if (rdx & x64::CPUID_FEAT_RDX_SMEP) // https://en.wikipedia.org/wiki/Control_register#SMEP
// https://web.archive.org/web/20160312223150/http://ncsi.com/nsatc11/presentations/wednesday/emerging_technologies/fischer.pdf
{
if (!BSP)
KPrint("SMEP is supported.");
fixme("Not going to enable SMEP.");
cr4.SMEP = 1;
debug("SMEP is supported.");
// cr4.SMEP = 1;
}
if (rdx & x64::CPUID_FEAT_RDX_SMAP)
if (rdx & x64::CPUID_FEAT_RDX_SMAP) // https://en.wikipedia.org/wiki/Supervisor_Mode_Access_Prevention
{
if (!BSP)
KPrint("SMAP is supported.");
fixme("Not going to enable SMAP.");
cr4.SMAP = 1;
debug("SMAP is supported.");
// cr4.SMAP = 1;
}
if (strcmp(Hypervisor(), x86_CPUID_VENDOR_VIRTUALBOX) == 0 &&
strcmp(Hypervisor(), x86_CPUID_VENDOR_TCG) == 0)
if (strcmp(Hypervisor(), x86_CPUID_VENDOR_VIRTUALBOX) != 0 &&
strcmp(Hypervisor(), x86_CPUID_VENDOR_TCG) != 0)
{
debug("Writing CR4...");
x64::writecr4(cr4);
debug("Wrote CR4.");
}
else
{
if (!BSP)

View File

@ -61,8 +61,8 @@ CFLAGS := \
ifeq ($(OSARCH), amd64)
CFLAGS += -fno-pic -fno-pie -mno-80387 -mno-mmx -mno-3dnow \
-mno-red-zone -march=x86-64 -pipe \
CFLAGS += -fno-pic -fno-pie \
-mno-red-zone -march=x86-64 -pipe \
-mcmodel=kernel -msoft-float -fno-builtin
CFLAG_STACK_PROTECTOR := -fstack-protector-all
LDFLAGS += -TArchitecture/amd64/linker.ld \

View File

@ -379,6 +379,10 @@ namespace Tasking
tcb->Info.SleepUntil = 0;
schedbg("Thread \"%s\"(%d) woke up.", tcb->Name, tcb->ID);
}
else
{
schedbg("Thread \"%s\"(%d) is not ready to wake up. (SleepUntil: %d, Counter: %d)", tcb->Name, tcb->ID, tcb->Info.SleepUntil, TimeManager->GetCounter());
}
}
}
}
@ -433,7 +437,7 @@ namespace Tasking
{
// Save current process and thread registries, gs, fs, fpu, etc...
CurrentCPU->CurrentThread->Registers = *Frame;
CPU::x64::fxsave(CurrentCPU->CurrentThread->FXRegion);
CPU::x64::fxsave(CurrentCPU->CurrentThread->FPU);
CurrentCPU->CurrentThread->GSBase = CPU::x64::rdmsr(CPU::x64::MSR_GS_BASE);
CurrentCPU->CurrentThread->FSBase = CPU::x64::rdmsr(CPU::x64::MSR_FS_BASE);
@ -548,7 +552,7 @@ namespace Tasking
// Not sure if this is needed, but it's better to be safe than sorry.
asmv("movq %cr3, %rax");
asmv("movq %rax, %cr3");
CPU::x64::fxrstor(CurrentCPU->CurrentThread->FXRegion);
CPU::x64::fxrstor(CurrentCPU->CurrentThread->FPU);
CPU::x64::wrmsr(CPU::x64::MSR_GS_BASE, CurrentCPU->CurrentThread->GSBase);
CPU::x64::wrmsr(CPU::x64::MSR_FS_BASE, CurrentCPU->CurrentThread->FSBase);
@ -729,10 +733,11 @@ namespace Tasking
void Task::Sleep(uint64_t Milliseconds)
{
SmartCriticalSection(SchedulerLock);
SmartCriticalSection(TaskingLock);
TCB *thread = this->GetCurrentThread();
thread->Status = TaskStatus::Sleeping;
thread->Info.SleepUntil = TimeManager->CalculateTarget(Milliseconds);
schedbg("Thread \"%s\"(%d) is going to sleep until %llu", thread->Name, thread->ID, thread->Info.SleepUntil);
OneShot(1);
}
@ -773,6 +778,27 @@ namespace Tasking
Thread->Offset = Offset;
Thread->ExitCode = 0xdead;
Thread->Status = TaskStatus::Ready;
Thread->Memory = new Memory::MemMgr(Parent->PageTable);
Thread->FPU = (FXState *)Thread->Memory->RequestPages(TO_PAGES(sizeof(FXState)));
memset(Thread->FPU, 0, FROM_PAGES(TO_PAGES(sizeof(FXState))));
// TODO: Is really a good idea to use the FPU in kernel mode?
Thread->FPU->mxcsr = 0b0001111110000000;
Thread->FPU->mxcsrmask = 0b1111111110111111;
Thread->FPU->fcw = 0b0000001100111111;
CPU::x64::fxrstor(Thread->FPU);
// uint16_t FCW = 0b1100111111;
// asmv("fldcw %0"
// :
// : "m"(FCW)
// : "memory");
// uint32_t MXCSR = 0b1111110000000;
// asmv("ldmxcsr %0"
// :
// : "m"(MXCSR)
// : "memory");
// CPU::x64::fxsave(Thread->FPU);
#if defined(__amd64__)
memset(&Thread->Registers, 0, sizeof(CPU::x64::TrapFrame)); // Just in case
@ -808,7 +834,6 @@ namespace Tasking
case TaskTrustLevel::User:
{
Thread->Stack = new Memory::StackGuard(true, Parent->PageTable);
Thread->Memory = new Memory::MemMgr(Parent->PageTable);
#if defined(__amd64__)
SecurityManager.TrustToken(Thread->Security.UniqueToken, TokenTrustLevel::Untrusted);
Thread->GSBase = 0;
@ -823,6 +848,8 @@ namespace Tasking
Thread->Registers.rflags.ID = 1;
Thread->Registers.rsp = ((uintptr_t)Thread->Stack->GetStackTop());
#pragma region
size_t ArgvSize = 0;
if (argv)
while (argv[ArgvSize] != nullptr)
@ -942,6 +969,8 @@ namespace Tasking
Thread->Registers.rcx = (uintptr_t)EnvpSize; // envc
Thread->Registers.rdx = (uintptr_t)(Thread->Registers.rsp + 8 + (8 * ArgvSize) + 8); // envp
#pragma endregion
/* We need to leave the libc's crt to make a syscall when the Thread is exited or we are going to get GPF or PF exception. */
Memory::Virtual uva = Memory::Virtual(Parent->PageTable);

View File

@ -5,11 +5,6 @@
#include <cstring>
extern "C" void _amd64_fxsave(char *Buffer);
extern "C" void _amd64_fxrstor(char *Buffer);
extern "C" void _i386_fxsave(char *Buffer);
extern "C" void _i386_fxrstor(char *Buffer);
#define x86_CPUID_VENDOR_OLDAMD "AMDisbetter!" /* Early engineering samples of AMD K5 processor */
#define x86_CPUID_VENDOR_AMD "AuthenticAMD"
#define x86_CPUID_VENDOR_INTEL "GenuineIntel"
@ -3404,31 +3399,29 @@ namespace CPU
#endif
}
SafeFunction static inline void fxsave(char *FXSaveArea)
SafeFunction static inline void fxsave(void *FXSaveArea)
{
#if defined(__amd64__)
if (!FXSaveArea || FXSaveArea >= (char *)0xfffffffffffff000)
return;
_amd64_fxsave(FXSaveArea);
// asmv("fxsaveq (%0)"
// :
// : "r"(FXSaveArea)
// : "memory");
asmv("fxsaveq (%0)"
:
: "r"(FXSaveArea)
: "memory");
#endif
}
SafeFunction static inline void fxrstor(char *FXRstorArea)
SafeFunction static inline void fxrstor(void *FXRstorArea)
{
#if defined(__amd64__)
if (!FXRstorArea || FXRstorArea >= (char *)0xfffffffffffff000)
return;
_amd64_fxrstor(FXRstorArea);
// asmv("fxrstorq (%0)"
// :
// : "r"(FXRstorArea)
// : "memory");
asmv("fxrstorq (%0)"
:
: "r"(FXRstorArea)
: "memory");
#endif
}

View File

@ -57,6 +57,32 @@ namespace Tasking
Terminated
};
struct FXState
{
/** @brief FPU control word */
uint16_t fcw;
/** @brief FPU status word */
uint16_t fsw;
/** @brief FPU tag words */
uint8_t ftw;
/** @brief Reserved (zero) */
uint8_t Reserved;
/** @brief FPU opcode */
uint16_t fop;
/** @brief PFU instruction pointer */
uint64_t rip;
/** @brief FPU data pointer */
uint64_t rdp;
/** @brief SSE control register */
uint32_t mxcsr;
/** @brief SSE control register mask */
uint32_t mxcsrmask;
/** @brief FPU registers (last 6 bytes reserved) */
uint8_t st[8][16];
/** @brief XMM registers */
uint8_t xmm[16][16];
} __attribute__((packed));
struct TaskSecurity
{
TaskTrustLevel TrustLevel;
@ -104,7 +130,7 @@ namespace Tasking
uintptr_t IPHistory[128];
TaskSecurity Security;
TaskInfo Info;
char FXRegion[512] __attribute__((aligned(16)));
FXState *FPU;
void Rename(const char *name)
{