diff --git a/Architecture/amd64/cpu/fxsr.asm b/Architecture/amd64/cpu/fxsr.asm deleted file mode 100644 index b91d269..0000000 --- a/Architecture/amd64/cpu/fxsr.asm +++ /dev/null @@ -1,11 +0,0 @@ -[bits 64] - -[global _amd64_fxsave] -_amd64_fxsave: - fxsave [rdi] - ret - -[global _amd64_fxrstor] -_amd64_fxrstor: - fxrstor [rdi] - ret diff --git a/Architecture/i686/cpu/fxsr.asm b/Architecture/i686/cpu/fxsr.asm deleted file mode 100644 index 47e40d7..0000000 --- a/Architecture/i686/cpu/fxsr.asm +++ /dev/null @@ -1,11 +0,0 @@ -[bits 64] - -[global _i386_fxsave] -_i386_fxsave: - fxsave [edi] - ret - -[global _i386_fxrstor] -_i386_fxrstor: - fxrstor [edi] - ret diff --git a/Core/CPU.cpp b/Core/CPU.cpp index 2f06545..fc8520b 100644 --- a/Core/CPU.cpp +++ b/Core/CPU.cpp @@ -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) diff --git a/Makefile b/Makefile index a498851..df78518 100644 --- a/Makefile +++ b/Makefile @@ -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 \ diff --git a/Tasking/Task.cpp b/Tasking/Task.cpp index 174ee5b..b485ae2 100644 --- a/Tasking/Task.cpp +++ b/Tasking/Task.cpp @@ -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); diff --git a/include/cpu.hpp b/include/cpu.hpp index ee9a715..6aef7e8 100644 --- a/include/cpu.hpp +++ b/include/cpu.hpp @@ -5,11 +5,6 @@ #include -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 } diff --git a/include/task.hpp b/include/task.hpp index b9e7893..1d3982d 100644 --- a/include/task.hpp +++ b/include/task.hpp @@ -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) {