Fix i686 thread context setup

This commit is contained in:
2026-06-14 00:53:34 +02:00
parent df35bf8601
commit e035666f7a

View File

@@ -41,6 +41,7 @@ KE::KThread::InitializeThreadContext(IN PKTHREAD Thread,
{ {
PKTHREAD_INIT_FRAME ThreadFrame; PKTHREAD_INIT_FRAME ThreadFrame;
PFX_SAVE_FORMAT FxSaveFormat; PFX_SAVE_FORMAT FxSaveFormat;
CONTEXT ContextFrame;
/* Set initial thread frame */ /* Set initial thread frame */
ThreadFrame = ((PKTHREAD_INIT_FRAME)Thread->InitialStack) - 1; ThreadFrame = ((PKTHREAD_INIT_FRAME)Thread->InitialStack) - 1;
@@ -51,18 +52,24 @@ KE::KThread::InitializeThreadContext(IN PKTHREAD Thread,
/* Check if context provided for this thread */ /* Check if context provided for this thread */
if(ContextRecord) if(ContextRecord)
{ {
/* User mode thread needs further initialization, this is not completed */ /* Make a local copy of the context to avoid mutating caller's memory */
UNIMPLEMENTED; RTL::Memory::CopyMemory(&ContextFrame, ContextRecord, sizeof(CONTEXT));
/* Disable debug registers and enable control and extended registers */
ContextFrame.ContextFlags |= (CONTEXT_CONTROL | CONTEXT_EXTENDED_REGISTERS);
ContextFrame.ContextFlags &= ~CONTEXT_DEBUG_REGISTERS;
/* Fill trap frame with zeroes */ /* Fill trap frame with zeroes */
RTL::Memory::ZeroMemory(&ThreadFrame->TrapFrame, sizeof(KTRAP_FRAME)); RTL::Memory::ZeroMemory(&ThreadFrame->TrapFrame, sizeof(KTRAP_FRAME));
/* Disable debug registers and enable context registers */ /* Translate Context frame to Trap frame */
ContextRecord->ContextFlags &= ~CONTEXT_DEBUG_REGISTERS | CONTEXT_CONTROL; KE::Processor::RestoreProcessorContext(&ThreadFrame->TrapFrame, NULLPTR,
&ContextFrame, ContextFrame.ContextFlags);
/* This is user mode thread */ /* This is user mode thread */
ThreadFrame->StartFrame.UserMode = TRUE;
Thread->PreviousMode = UserMode; Thread->PreviousMode = UserMode;
ThreadFrame->StartFrame.UserMode = TRUE;
ThreadFrame->TrapFrame.PreviousMode = UserMode;
/* Disable coprocessor floating point state */ /* Disable coprocessor floating point state */
Thread->NpxState = NPX_STATE_UNLOADED; Thread->NpxState = NPX_STATE_UNLOADED;
@@ -71,11 +78,19 @@ KE::KThread::InitializeThreadContext(IN PKTHREAD Thread,
/* Set initial floating point state */ /* Set initial floating point state */
FxSaveFormat = (PFX_SAVE_FORMAT)ContextRecord->ExtendedRegisters; FxSaveFormat = (PFX_SAVE_FORMAT)ContextRecord->ExtendedRegisters;
FxSaveFormat->ControlWord = 0x27F; FxSaveFormat->ControlWord = 0x27F;
FxSaveFormat->MxCsr = 0x1F80; FxSaveFormat->DataOffset = 0;
ContextRecord->FloatSave.Cr0NpxState = 0; FxSaveFormat->DataSelector = 0;
FxSaveFormat->ErrorOffset = 0;
FxSaveFormat->ErrorSelector = 0;
FxSaveFormat->StatusWord = 0;
FxSaveFormat->TagWord = 0;
ContextFrame.FloatSave.Cr0NpxState = 0;
ThreadFrame->NpxFrame.Cr0NpxState = 0; ThreadFrame->NpxFrame.Cr0NpxState = 0;
ThreadFrame->NpxFrame.NpxSavedCpu = 0; ThreadFrame->NpxFrame.NpxSavedCpu = 0;
/* Set initial MXCSR register value */
FxSaveFormat->MxCsr = 0x1F80;
/* Clear DR6 and DR7 registers */ /* Clear DR6 and DR7 registers */
ThreadFrame->TrapFrame.Dr6 = 0; ThreadFrame->TrapFrame.Dr6 = 0;
ThreadFrame->TrapFrame.Dr7 = 0; ThreadFrame->TrapFrame.Dr7 = 0;
@@ -84,15 +99,12 @@ KE::KThread::InitializeThreadContext(IN PKTHREAD Thread,
ThreadFrame->TrapFrame.SegDs |= RPL_MASK; ThreadFrame->TrapFrame.SegDs |= RPL_MASK;
ThreadFrame->TrapFrame.SegEs |= RPL_MASK; ThreadFrame->TrapFrame.SegEs |= RPL_MASK;
ThreadFrame->TrapFrame.SegSs |= RPL_MASK; ThreadFrame->TrapFrame.SegSs |= RPL_MASK;
/* Set user mode thread in the trap frame */
ThreadFrame->TrapFrame.PreviousMode = UserMode;
} }
else else
{ {
/* This is kernel mode thread */ /* This is kernel mode thread */
ThreadFrame->StartFrame.UserMode = FALSE;
Thread->PreviousMode = KernelMode; Thread->PreviousMode = KernelMode;
ThreadFrame->StartFrame.UserMode = FALSE;
/* Disable coprocessor floating point state */ /* Disable coprocessor floating point state */
Thread->NpxState = NPX_STATE_UNLOADED; Thread->NpxState = NPX_STATE_UNLOADED;
@@ -110,7 +122,9 @@ KE::KThread::InitializeThreadContext(IN PKTHREAD Thread,
/* Initialize switch frame */ /* Initialize switch frame */
ThreadFrame->SwitchFrame.ApcBypassDisabled = TRUE; ThreadFrame->SwitchFrame.ApcBypassDisabled = TRUE;
ThreadFrame->SwitchFrame.ExceptionList = (PEXCEPTION_REGISTRATION_RECORD) - 1; ThreadFrame->SwitchFrame.ExceptionList = (PEXCEPTION_REGISTRATION_RECORD) - 1;
ThreadFrame->SwitchFrame.Return = (PVOID)(ULONG)RunThread;
/* Set thread stack */ /* Set thread stack boundaries */
Thread->InitialStack = (PVOID)&ThreadFrame->NpxFrame;
Thread->KernelStack = &ThreadFrame->SwitchFrame; Thread->KernelStack = &ThreadFrame->SwitchFrame;
} }