save fpu state properly-ish, add a guard to doom_malloc_wrapper, fix QueryPerformance* and GetSystemTimeAsFileTime
This commit is contained in:
1 parent
def649b995
commit
ddb5d5f5d8
8 files changed
+78
-56
No files matched your search
@@ -53,6 +53,7 @@ void KeInitializeScheduler(void) {
|
||||
__stosq((unsigned __int64 *)ctx, 0, sizeof(KCONTEXT) / 8);
|
||||
ctx->Rip = (uint64_t)IdleLoop;
|
||||
idle->SavedContext = ctx;
|
||||
KeInitThreadFpuContext(idle);
|
||||
|
||||
gIdleThread = idle;
|
||||
gCurrentThread = idle;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
THREAD_SavedContext EQU 88
|
||||
THREAD_TssRsp0 EQU 104
|
||||
THREAD_Teb EQU 112
|
||||
THREAD_FpuContext EQU 160
|
||||
TSS_RSP0_OFFSET EQU 4
|
||||
|
||||
EXTERN gTss:QWORD ; address of the single TSS, exported from ke_idt.c
|
||||
@@ -20,6 +21,9 @@ EXTERN gTss:QWORD ; address of the single TSS, exported from ke_idt.c
|
||||
; RCX = from, RDX = to (Microsoft x64)
|
||||
; -------------------------------------------------------------------------
|
||||
KeSwitchContext PROC
|
||||
mov rax, [rcx + THREAD_FpuContext]
|
||||
fxsave64 [rax]
|
||||
|
||||
; Save non-volatile registers onto the current (outgoing) kernel stack.
|
||||
push rbx
|
||||
push rbp
|
||||
@@ -50,6 +54,9 @@ KeSwitchContext PROC
|
||||
mov r8, gTss
|
||||
mov qword ptr [r8 + TSS_RSP0_OFFSET], rax
|
||||
|
||||
mov rax, [rdx + THREAD_FpuContext]
|
||||
fxrstor64 [rax]
|
||||
|
||||
; Restore non-volatile registers of the incoming thread.
|
||||
pop r15
|
||||
pop r14
|
||||
|
||||
+23
-2
@@ -7,6 +7,9 @@
|
||||
#include <mm_virt.h>
|
||||
#include <ob_object.h>
|
||||
|
||||
#define FPU_FCW_DEFAULT 0x037Fu
|
||||
#define FPU_MXCSR_DEFAULT 0x1F80u
|
||||
|
||||
static uint32_t gNextThreadId = 1;
|
||||
extern void KeThreadEntry(void);
|
||||
|
||||
@@ -80,8 +83,8 @@ __declspec(dllexport) KSTATUS KeCreateThread(PROCESS* owner, uintptr_t entry, ui
|
||||
// offset 0x10 is StackLimit, which __chkstk checks.
|
||||
uint64_t* teb = (uint64_t*)ustack;
|
||||
teb[0] = 0; // ExceptionList (GS:0x00)
|
||||
teb[1] = 0; // StackBase (GS:0x08)
|
||||
teb[2] = 0; // StackLimit (GS:0x10) - __chkstk will see 0 and safely exit
|
||||
teb[1] = userStackTop; // StackBase
|
||||
teb[2] = (uintptr_t)ustack; // StackLimit
|
||||
|
||||
thread->Teb = teb;
|
||||
|
||||
@@ -124,6 +127,7 @@ __declspec(dllexport) KSTATUS KeCreateThread(PROCESS* owner, uintptr_t entry, ui
|
||||
owner->ThreadCount++;
|
||||
KeReleaseSpinlock(&owner->HandleLock, flags);
|
||||
|
||||
KeInitThreadFpuContext(thread);
|
||||
KeReadyThread(thread);
|
||||
*out = thread;
|
||||
return STATUS_SUCCESS;
|
||||
@@ -211,6 +215,7 @@ __declspec(dllexport) KSTATUS KeCreateKernelThread(uintptr_t fn, uintptr_t arg,
|
||||
|
||||
if (out) *out = thread;
|
||||
|
||||
KeInitThreadFpuContext(thread);
|
||||
KeReadyThread(thread);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
@@ -233,3 +238,19 @@ void KeUnblockThread(THREAD* thread) {
|
||||
|
||||
KeReadyThread(thread);
|
||||
}
|
||||
|
||||
void KeInitThreadFpuContext(THREAD* thread)
|
||||
{
|
||||
uintptr_t raw =
|
||||
(uintptr_t)thread->FpuStorage;
|
||||
|
||||
uintptr_t aligned =
|
||||
(raw + 15) & ~(uintptr_t)15;
|
||||
|
||||
thread->FpuContext = (void*)aligned;
|
||||
|
||||
memset(thread->FpuContext, 0, 512);
|
||||
|
||||
*(uint16_t*)((uint8_t*)thread->FpuContext + 0x00) = 0x037F;
|
||||
*(uint32_t*)((uint8_t*)thread->FpuContext + 0x18) = 0x1F80;
|
||||
}
|
||||
@@ -73,6 +73,9 @@ typedef struct THREAD {
|
||||
// Allocated in KeCreateThread, signaled in KeExitThread before teardown.
|
||||
// Waiters block on this via SYS_WAIT_THREAD -> KeWaitForEvent.
|
||||
EVENT* ExitEvent;
|
||||
|
||||
void* FpuContext;
|
||||
uint8_t FpuStorage[528];
|
||||
} THREAD;
|
||||
|
||||
__declspec(dllexport) KSTATUS KeCreateThread(PROCESS* owner, uintptr_t entry, uintptr_t arg,
|
||||
@@ -94,3 +97,5 @@ void KeUnblockThread(THREAD* thread);
|
||||
|
||||
// Assembly stub - implemented in ke_switch.asm.
|
||||
void KeSwitchContext(THREAD* from, THREAD* to);
|
||||
|
||||
void KeInitThreadFpuContext(THREAD* thread);
|
||||
Reference in new issue
Block a user