diff --git a/reactos/ntoskrnl/ke/apc.c b/reactos/ntoskrnl/ke/apc.c index da66359f99c..675a6d41ba4 100644 --- a/reactos/ntoskrnl/ke/apc.c +++ b/reactos/ntoskrnl/ke/apc.c @@ -658,7 +658,7 @@ KiDeliverApc(KPROCESSOR_MODE DeliveryMode, PKTRAP_FRAME TrapFrame) { PKTHREAD Thread = KeGetCurrentThread(); - PKPROCESS Process = KeGetCurrentProcess(); + PKPROCESS Process = Thread->ApcState.Process; PKTRAP_FRAME OldTrapFrame; PLIST_ENTRY ApcListEntry; PKAPC Apc; diff --git a/reactos/ntoskrnl/ke/i386/ctxswitch.S b/reactos/ntoskrnl/ke/i386/ctxswitch.S index 7ec6cb62b7a..b76e4d3689d 100644 --- a/reactos/ntoskrnl/ke/i386/ctxswitch.S +++ b/reactos/ntoskrnl/ke/i386/ctxswitch.S @@ -546,3 +546,61 @@ _Ki386AdjustEsp0@4: popf ret 4 .endfunc + +.globl _KiSwapProcess@8 +.func KiSwapProcess@8 +_KiSwapProcess@8: + + /* Get process pointers */ + mov edx, [esp+4] + mov eax, [esp+8] + +#ifdef CONFIG_SMP + /* Update active processors */ + mov ecx, fs:[KPCR_SET_MEMBER] + lock xor [edx+KPROCESS_ACTIVE_PROCESSORS], ecx + lock xor [eax+KPROCESS_ACTIVE_PROCESSORS], ecx + + /* Sanity check */ +#ifdef DBG + test dword ptr [edx+KPROCESS_ACTIVE_PROCESSORS], 0 + jz WrongCpu1 + test dword ptr [eax+KPROCESS_ACTIVE_PROCESSORS], 0 + jnz WrongCpu2 +#endif +#endif + + /* Check if their LDTs changed */ + mov ecx, [edx+KPROCESS_LDT_DESCRIPTOR0] + or ecx, [eax+KPROCESS_LDT_DESCRIPTOR0] + jnz NewLdt + + /* Update CR3 */ + mov eax, [edx+KPROCESS_DIRECTORY_TABLE_BASE] + mov cr3, eax + + /* Get the KTSS */ + mov ecx, fs:[KPCR_TSS] + + /* Clear GS on process swap */ + xor eax, eax + mov gs, ax + + /* Update IOPM offset */ + mov ax, [edx+KPROCESS_IOPM_OFFSET] + mov [ecx+KTSS_IOMAPBASE], ax + + /* Return */ + ret 8 + +NewLdt: + /* FIXME: TODO */ + int 3 + +#ifdef DBG +WrongCpu1: + int 3 +WrongCpu2: + int 3 +#endif +.endfunc diff --git a/reactos/ntoskrnl/ke/i386/ldt.c b/reactos/ntoskrnl/ke/i386/ldt.c index 1e1efc4a9ef..67446e77ba3 100644 --- a/reactos/ntoskrnl/ke/i386/ldt.c +++ b/reactos/ntoskrnl/ke/i386/ldt.c @@ -157,7 +157,7 @@ NtSetLdtEntries (ULONG Selector1, KeAcquireSpinLock(&LdtLock, &oldIrql); - LdtDescriptor = (PUSHORT) &KeGetCurrentProcess()->LdtDescriptor; + LdtDescriptor = (PUSHORT) &PsGetCurrentProcess()->Pcb.LdtDescriptor; LdtBase = LdtDescriptor[1] | ((LdtDescriptor[2] & 0xff) << 16) | ((LdtDescriptor[3] & ~0xff) << 16); diff --git a/reactos/ntoskrnl/ke/process.c b/reactos/ntoskrnl/ke/process.c index cd30899c03c..4ce27d24b54 100644 --- a/reactos/ntoskrnl/ke/process.c +++ b/reactos/ntoskrnl/ke/process.c @@ -1,13 +1,13 @@ /* - * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory * FILE: ntoskrnl/ke/process.c * PURPOSE: Kernel Process Management and System Call Tables * PROGRAMMERS: Alex Ionescu * Gregor Anich */ -/* INCLUDES ********(*********************************************************/ +/* INCLUDES ******************************************************************/ #include #define NDEBUG @@ -28,16 +28,9 @@ PVOID KeUserCallbackDispatcher; PVOID KeUserExceptionDispatcher; PVOID KeRaiseUserExceptionDispatcher; -/* FUNCTIONS *****************************************************************/ +/* PRIVATE FUNCTIONS *********************************************************/ -PKPROCESS -STDCALL -KeGetCurrentProcess(VOID) -{ - return(&(PsGetCurrentProcess()->Pcb)); -} - -static __inline +FORCEINLINE VOID NTAPI UpdatePageDirs(IN PKTHREAD Thread, @@ -65,10 +58,9 @@ KiAttachProcess(PKTHREAD Thread, PRKAPC_STATE SavedApcState) { ASSERT(Process != Thread->ApcState.Process); - DPRINT("KiAttachProcess(Thread: %x, Process: %x, SavedApcState: %x\n", - Thread, Process, SavedApcState); /* Increase Stack Count */ + ASSERT(Process->StackCount != MAXULONG_PTR); Process->StackCount++; /* Swap the APC Environment */ @@ -85,7 +77,8 @@ KiAttachProcess(PKTHREAD Thread, /* Update Environment Pointers if needed*/ if (SavedApcState == &Thread->SavedApcState) { - Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->SavedApcState; + Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread-> + SavedApcState; Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->ApcState; Thread->ApcStateIndex = AttachedApcEnvironment; } @@ -107,7 +100,7 @@ KiAttachProcess(PKTHREAD Thread, else { DPRINT1("Errr. ReactOS doesn't support paging out processes yet...\n"); - DbgBreakPoint(); + ASSERT(FALSE); } } @@ -190,6 +183,8 @@ KeSetProcess(PKPROCESS Process, { KIRQL OldIrql; ULONG OldState; + ASSERT_PROCESS(Process); + ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); /* Lock Dispatcher */ OldIrql = KiAcquireDispatcherLock(); @@ -199,7 +194,10 @@ KeSetProcess(PKPROCESS Process, /* Signal the Process */ Process->Header.SignalState = TRUE; - if ((OldState == 0) && IsListEmpty(&Process->Header.WaitListHead) != TRUE) + + /* Check if was unsignaled and has waiters */ + if (!(OldState) && + !(IsListEmpty(&Process->Header.WaitListHead))) { /* Satisfy waits */ KiWaitTest((PVOID)Process, Increment); @@ -212,15 +210,6 @@ KeSetProcess(PKPROCESS Process, return OldState; } -VOID -NTAPI -KiSwapProcess(PKPROCESS NewProcess, - PKPROCESS OldProcess) -{ - DPRINT("Switching CR3 to: %x\n", NewProcess->DirectoryTableBase.u.LowPart); - Ke386SetPageTableDirectory(NewProcess->DirectoryTableBase.u.LowPart); -} - VOID NTAPI KeSetQuantumProcess(IN PKPROCESS Process, @@ -419,6 +408,8 @@ KeSetPriorityAndQuantumProcess(IN PKPROCESS Process, return OldPriority; } +/* PUBLIC FUNCTIONS **********************************************************/ + /* * @implemented */ @@ -464,12 +455,12 @@ KeAttachProcess(PKPROCESS Process) */ VOID NTAPI -KeDetachProcess (VOID) +KeDetachProcess(VOID) { PKTHREAD Thread = KeGetCurrentThread(); KLOCK_QUEUE_HANDLE ApcLock; + PKPROCESS Process; ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); - DPRINT("KeDetachProcess()\n"); /* Check if it's attached */ if (Thread->ApcStateIndex == OriginalApcEnvironment) return; @@ -477,12 +468,35 @@ KeDetachProcess (VOID) /* Acquire APC Lock */ KiAcquireApcLock(Thread, &ApcLock); - /* It is, decrease Stack Count */ - if(!(--Thread->ApcState.Process->StackCount)) + /* Check for invalid attach attempts */ + if ((Thread->ApcState.KernelApcInProgress) || + !(IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode])) || + !(IsListEmpty(&Thread->ApcState.ApcListHead[UserMode]))) + { + /* Crash the system */ + KeBugCheck(INVALID_PROCESS_DETACH_ATTEMPT); + } + + /* Get the process */ + Process = Thread->ApcState.Process; + + /* Acquire dispatcher lock */ + KiAcquireDispatcherLockAtDpcLevel(); + + /* Decrease the stack count */ + ASSERT(Process->StackCount != 0); + ASSERT(Process->State == ProcessInMemory); + Process->StackCount--; + + /* Check if we can swap the process out */ + if (!Process->StackCount) { /* FIXME: Swap the process out */ } + /* Release dispatcher lock */ + KiReleaseDispatcherLockFromDpcLevel(); + /* Restore the APC State */ KiMoveApcState(&Thread->SavedApcState, &Thread->ApcState); Thread->SavedApcState.Process = NULL; @@ -529,6 +543,7 @@ KeStackAttachProcess(IN PKPROCESS Process, { KLOCK_QUEUE_HANDLE ApcLock; PKTHREAD Thread = KeGetCurrentThread(); + ASSERT_PROCESS(Process); ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); /* Make sure that we are in the right page directory */ @@ -579,6 +594,7 @@ KeUnstackDetachProcess(IN PRKAPC_STATE ApcState) { KLOCK_QUEUE_HANDLE ApcLock; PKTHREAD Thread = KeGetCurrentThread(); + PKPROCESS Process; ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); /* Check for magic value meaning we were already in the same process */ @@ -596,16 +612,32 @@ KeUnstackDetachProcess(IN PRKAPC_STATE ApcState) (!IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode])) || (!IsListEmpty(&Thread->ApcState.ApcListHead[UserMode]))) { + /* Bugcheck the system */ KEBUGCHECK(INVALID_PROCESS_DETACH_ATTEMPT); } - /* Decrease Stack Count */ - if(!(--Thread->ApcState.Process->StackCount)) + /* Get the process */ + Process = Thread->ApcState.Process; + + /* Acquire dispatcher lock */ + KiAcquireDispatcherLockAtDpcLevel(); + + /* Decrease the stack count */ + ASSERT(Process->StackCount != 0); + ASSERT(Process->State == ProcessInMemory); + Process->StackCount--; + + /* Check if we can swap the process out */ + if (!Process->StackCount) { /* FIXME: Swap the process out */ } - if (ApcState->Process != NULL) + /* Release dispatcher lock */ + KiReleaseDispatcherLockFromDpcLevel(); + + /* Check if there's an APC state to restore */ + if (ApcState->Process) { /* Restore the APC State */ KiMoveApcState(ApcState, &Thread->ApcState); diff --git a/reactos/ntoskrnl/mm/i386/pfault.c b/reactos/ntoskrnl/mm/i386/pfault.c index 0a94556cc63..96adea4e5a0 100644 --- a/reactos/ntoskrnl/mm/i386/pfault.c +++ b/reactos/ntoskrnl/mm/i386/pfault.c @@ -79,7 +79,7 @@ ULONG KiPageFaultHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr) if (!NT_SUCCESS(Status)) { /* FIXME: This should use ->VdmObjects */ - if(!KeGetCurrentProcess()->Unused) + if(!PsGetCurrentProcess()->Pcb.Unused) { *((PKV86M_TRAP_FRAME)Tf)->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION; } diff --git a/reactos/ntoskrnl/ntoskrnl.def b/reactos/ntoskrnl/ntoskrnl.def index 04ba96f7b54..51a843c927b 100644 --- a/reactos/ntoskrnl/ntoskrnl.def +++ b/reactos/ntoskrnl/ntoskrnl.def @@ -891,7 +891,7 @@ PsDereferencePrimaryToken@4 PsDisableImpersonation@8 PsEstablishWin32Callouts@4 PsGetContextThread@12 -PsGetCurrentProcess@0=KeGetCurrentProcess@0 +PsGetCurrentProcess@0=IoGetCurrentProcess@0 PsGetCurrentProcessId@0 PsGetCurrentProcessWin32Process@0 PsGetCurrentProcessSessionId@0